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

Scipy Optimize循环创建约束时出现奇异矩阵错误求助

问题描述

我正在尝试优化一个20×5的矩阵以最大化返回值y,核心约束是所有元素的总和必须处于指定的最小与最大范围之间。但通过循环创建约束时,持续出现如下奇异矩阵错误:

Singular matrix C in LSQ subproblem    (Exit mode 6)
            Current function value: -3.0867160133139926
            Iterations: 1
            Function evaluations: 261
            Gradient evaluations: 1

循环创建约束的代码版本

# 导入库
import pandas as pd
import numpy as np
import scipy.optimize as so
import random

# 定义目标函数
def obj_func(matrix):
    # 定义各列的计算逻辑
    return np.sum(output_matrix)

# 优化器函数
def optimizer_result(tot_sum_max, tot_sum_min, col_min, col_max, matrix_input):
    constraints_list = [
        {'type': 'ineq', 'fun': lambda x: np.sum(x) - tot_sum_max},
        {'type': 'ineq', 'fun': lambda x: -(np.sum(x) - tot_sum_min)}
    ]

    # 生成初始矩阵
    start_matrix = [random.randint(0, 3) for i in range(0, 260)]

    # 运行优化器
    optimizer_solution = so.minimize(
        obj_func, 
        start_matrix, 
        method='SLSQP', 
        bounds=[(0, tot_sum_max)] * 20,
        tol=0.01,
        options={'disp': True, 'maxiter': 100}, 
        constraints=constraints_list,
        callback=callback
    )

但手动编写约束时,优化器能正常运行(为简洁未包含全部260个元素约束),不清楚两者差异的原因。

手动创建约束的代码版本

# 导入库
import pandas as pd
import numpy as np
import scipy.optimize as so
import random

# 定义目标函数
def obj_func(matrix):
    return np.sum(output_matrix)

# 优化器函数
def optimizer_result(tot_sum_max, tot_sum_min, col_min, col_max, matrix_input):
    total_and_col_cons = [
        {'type': 'ineq', 'fun': lambda x: np.sum(x) - tot_sum_min},
        {'type': 'ineq', 'fun': lambda x: -(np.sum(x) - tot_sum_max)}
    ]

    # 生成初始矩阵
    start_matrix = [random.randint(0, 3) for i in range(0, 260)]

    # 运行优化器
    optimizer_solution = so.minimize(
        obj_func, 
        start_matrix, 
        method='SLSQP', 
        bounds=[(0, tot_sum_max)] * 20,
        tol=0.01,
        options={'disp': True, 'maxiter': 100}, 
        constraints=constraints_list,
        callback=callback
    )

问题原因与解决方法

你遇到的奇异矩阵错误,本质是代码中存在多处维度不匹配、变量未定义的问题,和“循环/手动创建约束”本身无关,具体问题如下:

1. 目标函数的致命错误

两个版本的obj_func都直接引用了未定义的output_matrix变量,优化器无法计算目标值,直接导致后续迭代逻辑混乱,这是触发奇异矩阵的核心诱因之一。

2. 维度不匹配问题

  • 你要优化的是20×5=100个元素的矩阵,但start_matrix生成了260个元素,变量维度和优化目标完全不符。
  • 边界参数bounds=[(0, tot_sum_max)] * 20只设置了20个边界,和260个变量的数量不匹配,导致约束矩阵维度错乱,SLSQP算法无法构建有效的雅可比矩阵,最终出现奇异矩阵。

3. 手动版本的笔误

手动版本中定义了total_and_col_cons约束列表,但优化器调用时仍使用constraints_list,如果实际运行时你修正了这个笔误,约束逻辑才会生效;而循环版本没有这个笔误,但其他维度错误依然存在,所以出现报错。

修正后的代码示例

import numpy as np
import scipy.optimize as so
import random

# 修正目标函数:基于传入的matrix参数计算输出,最大化等价于最小化负值
def obj_func(matrix):
    # 转换为20×5的二维矩阵
    matrix_2d = matrix.reshape(20, 5)
    # 替换为你实际的各列计算逻辑,示例为各列求和的总和
    total_output = np.sum([np.sum(col) for col in matrix_2d.T])
    # scipy.minimize是最小化器,最大化需返回负值
    return -total_output

def optimizer_result(tot_sum_max, tot_sum_min, col_min, col_max, matrix_input):
    # 总和约束:sum(x) ≥ tot_sum_min 且 sum(x) ≤ tot_sum_max
    constraints_list = [
        {'type': 'ineq', 'fun': lambda x: np.sum(x) - tot_sum_min},
        {'type': 'ineq', 'fun': lambda x: tot_sum_max - np.sum(x)}
    ]

    # 初始矩阵:匹配20×5=100个元素的维度
    start_matrix = [random.randint(0, 3) for _ in range(20*5)]

    # 边界:每个元素的范围,数量与变量一致
    bounds = [(0, tot_sum_max // 100 + 1)] * (20*5)

    # 运行优化器
    optimizer_solution = so.minimize(
        obj_func, 
        start_matrix, 
        method='SLSQP', 
        bounds=bounds,
        tol=0.01,
        options={'disp': True, 'maxiter': 100}, 
        constraints=constraints_list
    )
    return optimizer_solution

关键修正点

  • 目标函数使用传入的matrix参数,正确计算输出值,适配scipy的最小化逻辑返回负值。
  • 初始矩阵、边界数量均匹配20×5矩阵的100个元素维度。
  • 约束逻辑简化,避免符号错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 10:30:43