You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用CVXPY遇TypeError与ValueError:变量与Numpy标量相乘问题

问题:使用CVXPY求解优化问题时遇到类型错误

原始代码

import numpy as np
import cvxpy as cp

N = 10
threshold = 0.3
p = 1 - threshold
para_dim = 1000
para_mat = np.random.rand(para_dim, N) 
para_avg = np.expand_dims(np.mean(para_mat, axis=1), axis=1)
A = np.random.rand(N, N)

def dist(para_mat, para_avg):
    para_avr_arr = np.tile(para_avg, (1, N))
    para_tmp = para_avr_arr - para_mat
    con_dist = 0
    for i in range(N):
        con_dist += np.linalg.norm(para_tmp[:, i], 2)
    return con_dist/N

def aggregation(para_mat, B, N):
    para_mat_new = np.zeros((para_dim, N))
    for i in range(N):
        for j in range(N):
            for k in range(para_dim):
                para_mat_new[k, i] = (para_mat[k, j] - para_mat[k, i]) * B[i, j]
    return para_mat_new

B = cp.Variable((N, N))
B_col_sum = cp.sum(B, axis=0)
B_row_sum = cp.sum(B, axis=1)
para_mat_new = aggregation(para_mat, B, N)
obj = dist(para_mat_new, para_avg)
cons = []
for i in range(N):
    cons += [B_col_sum[i] == 1, B_row_sum[i] == 1]
cons += [B <= A, 0 <= B,  B<= 1]
prob = cp.Problem(cp.Minimize(obj), cons)
prob.solve(method='dccp')

错误信息

TypeError: float() argument must be a string or a number, not 'multiply'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
  File "Anaconda3\lib\site-packages\IPython\core\interactiveshell.py", line 3437, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-2-53cd92582735>", line 1, in <module>
    runfile('participation.py', wdir='participation')
  File "plugins\python\helpers\pydev\_pydev_bundle\pydev_umd.py", line 198, in runfile
    pydev_imports.execfile(filename, global_vars, local_vars)  # execute the script
  File "python\helpers\pydev\_pydev_imps\_pydev_execfile.py", line 18, in execfile
    exec(compile(contents+"\n", file, 'exec'), glob, loc)
  File "participation.py", line 57, in <module>
    para_mat_new = aggregation(para_mat, B, N)
  File "participation.py", line 40, in aggregation
    para_mat_new[k, i] = (para_mat[k, j] - para_mat[k, i]) * B[i, j]
ValueError: setting an array element with a sequence.

问题原因

  1. CVXPY变量与Numpy数组不兼容:B是CVXPY的Variable对象,属于符号化变量,并非数值型数组。你试图将(para_mat[k,j]-para_mat[k,i])*B[i,j]这个CVXPY表达式赋值给Numpy数组para_mat_new的元素,但Numpy数组仅能存储数值,无法存储符号化的CVXPY表达式,因此触发错误。
  2. Numpy函数无法处理CVXPY变量:dist函数中使用的np.linalg.norm仅支持数值型输入,不能处理CVXPY的符号化表达式。

修正方案

将aggregation和dist函数改写为使用CVXPY原生操作,避免混合使用Numpy和CVXPY的变量操作:

import numpy as np
import cvxpy as cp

N = 10
threshold = 0.3
p = 1 - threshold
para_dim = 1000
para_mat = np.random.rand(para_dim, N) 
# 转换为CVXPY常量,适配符号化运算
para_mat_cp = cp.Constant(para_mat)
para_avg = np.expand_dims(np.mean(para_mat, axis=1), axis=1)
para_avg_cp = cp.Constant(para_avg)
A = np.random.rand(N, N)

def dist(para_mat_cp, para_avg_cp):
    # 使用CVXPY的tile实现重复操作
    para_avr_arr = cp.tile(para_avg_cp, (1, N))
    para_tmp = para_avr_arr - para_mat_cp
    con_dist = 0
    for i in range(N):
        # 使用CVXPY的norm函数处理符号化变量
        con_dist += cp.norm(para_tmp[:, i], 2)
    return con_dist/N

def aggregation(para_mat_cp, B, N):
    # 用矩阵乘法替代三重循环,提升效率且符合CVXPY语法
    diff_mat = para_mat_cp.T - cp.diag(para_mat_cp.T @ np.eye(N))
    para_mat_new = (diff_mat @ B).T
    return para_mat_new

B = cp.Variable((N, N))
B_col_sum = cp.sum(B, axis=0)
B_row_sum = cp.sum(B, axis=1)
para_mat_new = aggregation(para_mat_cp, B, N)
obj = dist(para_mat_new, para_avg_cp)
cons = []
for i in range(N):
    cons += [B_col_sum[i] == 1, B_row_sum[i] == 1]
cons += [B <= A, 0 <= B,  B<= 1]
prob = cp.Problem(cp.Minimize(obj), cons)
prob.solve(method='dccp')

关键修改点

  • 将para_mat和para_avg转换为CVXPY的Constant对象,确保所有运算都在CVXPY的符号化框架内进行。
  • 改写aggregation函数:用矩阵乘法替代三重循环,既提升运算效率,又避免将CVXPY表达式赋值给Numpy数组的错误。
  • 在dist函数中用cp.norm替代np.linalg.norm、cp.tile替代np.tile,适配CVXPY的符号化变量特性。

内容的提问来源于stack exchange,提问作者chuiyang meng

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 01:17:48