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

使用Mosek优化二次型平方根函数遇类型错误求助

问题解决:Mosek实现二次范数最小化

错误1:列表与变量运算不兼容

unsupported operand type(s) for -: 'list' and 'LinearVariable'是因为Python原生列表不能直接和Mosek的LinearVariable对象做算术运算。必须把weights_b这类常量转换为Mosek可识别的表达式对象,而非保留原生列表格式。

错误2:平方根的建模方式

直接在目标函数中写平方根不可行,Mosek需要通过二次锥约束来处理这类凸函数;或者利用单调性简化问题——最小化√y等价于最小化y(当y≥0时),两种方式都能实现原目标。

修正后的完整代码

b = [[1.0,2.0,3.0], 
     [2.0,6.0,8.0], 
     [8.0,1.0,5.0]]

weights_b = [0.3, 0.5, 0.2]  # 改为一维列表,便于转换为Mosek常量
n_opt = 3

import sys
from mosek.fusion import *

def main(args):
    with Model("quadratic_norm_min") as M:
        # 定义优化变量x,添加非负约束
        x = M.variable("x", n_opt, Domain.greaterThan(0.0))
        # 定义变量t,用于表示平方根的结果
        t = M.variable("t", 1, Domain.greaterThan(0.0))

        # 将常量转换为Mosek可识别的格式
        w_expr = Expr.const(n_opt, weights_b)
        B_mat = Matrix.dense(b)

        # 计算 weights_b - x 的差值
        diff = Expr.sub(w_expr, x)
        # 计算二次型项:(weights_b - x)^T · b · (weights_b - x)
        quad_form = Expr.dot(diff, Expr.mul(B_mat, diff))

        # 添加二次锥约束:t ≥ sqrt(quad_form)
        # 注意:矩阵b必须是正定/半正定的,否则问题非凸,Mosek无法求解
        M.constraint("quad_cone", Expr.vstack(t, diff), Domain.inQCone())

        # 目标:最小化t(即最小化原目标的平方根)
        M.objective("obj", ObjectiveSense.Minimize, t)

        # 求解问题
        M.solve()

        # 输出结果
        x_sol = x.level()
        t_sol = t.level()
        print("最优解x:")
        for i in range(n_opt):
            print(f"x[{i}] = {x_sol[i]:.6f}")
        print(f"目标函数值(平方根结果):{t_sol[0]:.6f}")

if __name__ == '__main__':
    main(sys.argv[1:])

关键注意事项

  • 矩阵正定性:目标函数中的矩阵b必须是正定或半正定的,否则二次型不是凸函数,Mosek无法处理这类非凸优化问题。可以通过计算特征值检查b的正定性。
  • 简化选项:如果不需要显式得到平方根结果,直接将quad_form设为目标函数即可——因为平方根是单调递增函数,最小化√y和最小化y的最优解x完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 15:05:31