无线通信系统中的功率分配

作者:Robert Gowers,Roger Hill,Sami Al-Izzi,Timothy Pollington和Keith Briggs

来自Boyd和Vandenberghe的《凸优化》,第196页的练习4.20

凸优化可以用于最大化无线通信系统的最小信号干扰加噪声比(SINR)。考虑一个具有n个发射机的系统,每个发射机的功率为:p_jgeq 0。为了传输到n个接收机。让G_{ij}geq 0表示从发射机j到接收机i的路径增益。这些路径增益形成矩阵Gin mathbb{R}^{n times n}。

每个接收机被分配给一个发射机,使接收机i处的信号功率为S_i=G_{ii}p_i,干扰功率为I_i=sum_{kneq i} G_{ik}p_k。给定每个接收机的噪声功率sigma_i,接收机i处的SINR为gamma_i=frac{S_i}{I_i+sigma_i}。

目标是在一定的功率约束下最大化系统的最小SINR。这些约束条件如下:

i - 每个发射机的功率:p_j leq P_j^{text{max}}

ii - 如果发射机被划分为m个不重叠的组:K_1, …, K_m,它们与总功率P_l^{text{gp}}共享一个共同的电源,则sum_{kin K_l}p_k leq P_l^{text{gp}}。

iii - 每个接收机可以接收的最大功率为P_i^{text{rc}},sum_{k=1}^{n}G_{ik}p_k leq P_i^{text{rc}}。

目标函数可以重写为:最小化:math:max_{i=1,…,n}frac{I_i + sigma_i}{S_i}

然而,由于这是一个拟凸的目标函数,我们不能直接使用CVXPY来解决它。相反,我们必须使用二分法。首先我们进行目标的重写,:math:alpha = gamma^{-1} geq 0,作为一个约束条件:

\(I_i+\sigma_i \leq S_i\alpha\)

然后我们选择初始下界和上界:math:L_0 和:math:U_0 为:math:alpha,应该选择这样的初始下界和上界使得:math:L < alpha^* < U,其中:math:alpha^* 是:math:alpha 的最优值。从一个初始值:math:alpha_0 = frac{1}{2}(L_0+U_0) 开始,使用任意目标函数来检查:math:`alpha_0`的可行性。从可行性中确定新的上界和下界:

如果:math:alpha_0 是可行的,那么:math:L_1 = L_0,:math:U_1 = alpha_0 和:math:alpha_1 = frac{1}{2}(L_1+U_1)

如果:math:alpha_0 是不可行的,那么:math:L_1 = alpha_1,:math:U_1 = U_0 和:math:alpha_1 = frac{1}{2}(L_1+U_1)

这个二分法过程一直重复,直到:math:U_N - L_N < epsilon,其中:math:epsilon 是所需的容忍度。

#!/usr/bin/env python3
# 作者:R. Gowers, S. Al-Izzi, T. Pollington, R. Hill & K. Briggs

import cvxpy as cp
import numpy as np
def maxmin_sinr(G, P_max, P_received, sigma, Group, Group_max, epsilon = 0.001):
    # 根据路径增益矩阵的大小找到 n 和 m
    n, m = np.shape(G)

    # 检查输入的大小
    if m != np.size(P_max):
        print('错误:P_max 的维度与增益矩阵的维度不匹配\n')
        return '错误:P_max 的维度与增益矩阵的维度不匹配\n', np.nan, np.nan, np.nan

    if n != np.size(P_received):
        print('错误:P_received 的维度与增益矩阵的维度不匹配\n')
        return '错误:P_received 的维度与增益矩阵的维度不匹配', np.nan, np.nan, np.nan

    if n != np.size(sigma):
        print('错误:σ 的维度与增益矩阵的维度不匹配\n')
        return '错误:σ 的维度与增益矩阵的维度不匹配', np.nan, np.nan, np.nan

    # I = np.zeros((n,m))
    # S = np.zeros((n,m))

    delta = np.identity(n)
    S = G*delta  # 信号功率矩阵
    I = G-S  # 干扰功率矩阵

    # 分组矩阵:按照发射机的数量分组
    num_groups = int(np.size(Group,0))

    if num_groups != np.size(Group_max):
        print('错误:Group 矩阵中的组数与 Group_max 的维度不匹配\n')
        return ('错误:Group 矩阵中的组数与 Group_max 的维度不匹配',
                np.nan, np.nan, np.nan, np.nan)

    # 将组的最大功率归一化为范围 [0,1]
    Group_norm = Group/np.sum(Group,axis=1).reshape((num_groups,1))

    # 创建标量优化变量 p:n 个发射机的功率
    p = cp.Variable(shape=n)
    best = np.zeros(n)

    # 设置子级集的上下界
    u = 1e4
    l = 0

    # alpha 定义广义线性二次问题的子级集,在这种情况下,α 是最小 SINR 的倒数
    alpha = cp.Parameter(shape=1)

    # 设置双分度可行性检验的约束条件
    constraints = [I*p + sigma <= alpha*S*p, p <= P_max, p >= 0, G*p <= P_received, Group_norm*p <= Group_max]

    # 定义目标函数,在这个案例中只希望测试解的可行性
    obj = cp.Minimize(alpha)

    # 现在检查解是否位于 u 和 l 之间
    alpha.value = [u]
    prob = cp.Problem(obj, constraints)
    prob.solve()

    if prob.status != 'optimal':
        # 在这种情况下,等级集 u 在解的下方
        print('上下界之间无最优解\n')
        return '错误:上下界之间无最优解', np.nan, np.nan, np.nan

    alpha.value = [l]
    prob = cp.Problem(obj, constraints)
    prob.solve()

    if prob.status == 'optimal':
        # 在这种情况下,等级集 l 在解的下方
        print('上下界之间无最优解\n')
        return '错误:上下界之间无最优解', np.nan, np.nan, np.nan

    # 双分度算法开始
    maxLoop = int(1e7)
    for i in range(1,maxLoop):
        # 首先检查 u 是否在可行域内,l 是否不在可行域内,如果不是这样,循环在此结束
        # 将 α 设置为区间的中点
        alpha.value = np.atleast_1d((u + l)/2.0)

        # 根据指定的容差测试区间的大小
        if u-l <= epsilon:
            break

        # 形成并求解问题
        prob = cp.Problem(obj, constraints)
        prob.solve()

        # 如果问题是可行的,则 u -> α,如果不是,则 l -> α,当达到容差时,新的 α 可能超出界限,最佳值取最后一个可行值作为最优值
        if prob.status == 'optimal':
            u = alpha.value
            best = p.value
        else:
            l = alpha.value

        # 最终条件检查区间是否收敛到顺序 ε,即最优子级集的范围 <=ε
        if u - l > epsilon and i == (maxLoop-1):
            print("解未收敛到顺序 epsilon")

    return l, u, float(alpha.value), best

示例

作为一个简单的示例,我们将考虑一种情况,其中 \(n=5\),并且 \(G_{ij} = 0.6`(当 :math:`i=j\))和 :math:`0.1`(其他情况)。

对于所有发射机 \(P_j^{\text{max}} = 1\),并且发射机分为两组,每组 \(P_l^{\text{gp}} = 1.8\)。第一组包含发射机 1 和 2,而第二组包含发射机 3,4 和 5。

对于所有接收机 \(P_i^{\text{rc}} = 4\)\(\sigma_i = 0.1\)

np.set_printoptions(precision=3)

# 在这种情况下,我们将使用一个信号权重为 0.6 和干扰权重为 0.1 的增益矩阵
G = np.array([[0.6,0.1,0.1,0.1,0.1],
              [0.1,0.6,0.1,0.1,0.1],
              [0.1,0.1,0.6,0.1,0.1],
              [0.1,0.1,0.1,0.6,0.1],
              [0.1,0.1,0.1,0.1,0.6]])

# 在这种情况下,m=n,但是这个问题可以推广到我们想要 n 个接收机和 m 个发射机的情况
n, m = np.shape(G)

# 设置每个发射机和接收机的最大功率饱和级别
P_max = np.array([1.]*n)

# 归一化的接收功率,总可能性是所有发射机的所有功率,所以是 1/n
P_received = np.array([4.,4.,4.,4.,4.])/n

# 设置噪声水平
sigma = np.array([0.1,0.1,0.1,0.1,0.1])

# 分组矩阵:按照发射机的数量分组
Group = np.array([[1.,1.,0,0,0],[0,0,1.,1.,1.]])

# 最大归一化功率组,组数乘以 1
Group_max = np.array([1.8,1.8])

# 现在运行优化问题
l, u, alpha, best = maxmin_sinr(G, P_max, P_received, sigma, Group, Group_max)

print('最小 SINR={:.4g}'.format(1/alpha))
print('功率={}'.format(best))
Minimum SINR=1.148
Power=[0.8 0.8 0.8 0.8 0.8]