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

使用Mystic优化矩阵时约束失效及目标值异常问题求助

Mystic优化矩阵出现负数及返回值异常问题

我尝试用mystic优化一个10×5矩阵以最大化返回值y,设置了两类约束:

  • 每个元素必须处于指定的最小和最大范围之间
  • 部分元素必须等于字典中给定的特定值

但优化结果出现负数(已设置元素非负约束),且返回值y异常偏小,不清楚原因。相关代码如下:

import random
import pandas as pd
import numpy as np
import mystic.symbolic as ms
import mystic as my
import scipy.optimize as so

# Specifiying constraints
element_low_lim = 0
element_hi_lim = 1000
total_matrix_min_sum = 0
total_matrix_max_sum = 220000

# Create an input matrix where the values must equal a specific amount
matrix_in = np.zeros((52,5))
matrix_in[0,0] = 100


def constraints_func(element_low_lim, element_hi_lim, total_matrix_min_sum, total_matrix_max_sum,element_vals_dict):
    var_num = ['x'+str(i) for i in range(260)]

    #creating element bounds constraints
    constraint_bound = ''
    for var in var_num:
        if var not in element_vals_dict:
            constraint_bound += var + f' >= {element_low_lim}' + '\n' + var + f' <= {element_hi_lim}' + '\n'

    #creating sum of all the elements constraint
    constraint_matrix_sum = ' + '.join(var_num) + f' <= {total_matrix_max_sum}' + '\n' + ' + '.join(var_num) + f' >= {total_matrix_min_sum}'


    #creating element constraints
    constraint_elements = '\n'.join([var+' == '+str(element_vals_dict[var]) for var in element_vals_dict])

    # bundle all constraints
    constraint_equations = constraint_bound.lstrip() + constraint_matrix_sum.lstrip() + constraint_column_sum.lstrip() + constraint_elements.lstrip()

    return constraint_equations

equations = constraints_func(element_low_lim, element_hi_lim, total_matrix_min_sum, total_matrix_max_sum, column_sum_min_lst, column_sum_max_lst, element_vals_dict)
equations = ms.simplify(equations, all=True)
constrain = ms.generate_constraint(ms.generate_solvers(equations), join=my.constraints.and_)

# Define Objective function
def obj_func(matrix):
    return np.sum(output_matrix)

mon = my.monitors.VerboseMonitor(1)

objs = []
def callback(x):
    kx = constrain(x)
    y = -obj_func(x)
    mon(kx, y)
    objs.append(y)
   
# create a starting matrix
start_matrix = [random.randint(0,3) for i in range(200)]

# run optimizer
solution = so.minimize(obj_func, start_matrix, method='SLSQP', tol=0.01, options={'disp': True, 'maxiter':100}, callback=callback)

问题排查与修复要点

1. 变量维度完全不匹配

代码里定义了260个变量(对应52×5矩阵),但你要优化的是10×5矩阵,同时起始矩阵只生成了200个元素,维度混乱会导致约束和优化变量对应错误,直接引发不符合预期的计算结果。

  • 修复:统一维度为10×5(50个变量),将var_num改为['x'+str(i) for i in range(50)],start_matrix改为[random.randint(0,3) for i in range(50)],matrix_in改为np.zeros((10,5))。

2. 约束函数存在未定义变量与参数错误

  • 调用constraints_func时传入了未声明的column_sum_min_lst和column_sum_max_lst,函数定义里也没有这两个参数;同时拼接约束时用到的constraint_column_sum从未定义,会直接触发运行错误。
  • 修复:删除无关的constraint_column_sum拼接代码,或者补充列和约束的逻辑;同时修正函数调用参数,只传入函数定义中要求的参数。

3. 目标函数逻辑错误

目标函数obj_func返回np.sum(output_matrix),但output_matrix从未定义,这会导致返回错误值(比如依赖环境中残留的同名变量或抛出异常),直接导致返回值y异常偏小。

  • 修复:目标函数基于输入的优化变量计算,比如改为return np.sum(matrix)(如果目标是最大化矩阵元素和)。

4. 最大化问题处理错误

你需要最大化目标值,但使用了scipy.optimize.minimize(最小化接口),未对目标函数做取负处理,导致优化方向完全相反。

  • 修复:将目标函数改为返回负的目标值(如return -np.sum(matrix)),让最小化等价于原目标的最大化;或者使用mystic自带的mystic.solvers.maximize接口。

5. 约束未应用到优化器

当前代码中生成的constrain约束函数并未传给so.minimize的constraints参数,导致约束完全没生效——这是优化结果出现负数的核心原因。

  • 修复:在so.minimize中添加约束参数,比如:
    solution = so.minimize(obj_func, start_matrix, method='SLSQP', tol=0.01, 
                          constraints={'type': 'eq', 'fun': lambda x: constrain(x) - x},
                          options={'disp': True, 'maxiter':100}, callback=callback)
    
    或者直接使用mystic的优化器,它能更直接地应用生成的约束。

6. 固定元素未加入约束字典

matrix_in中设置了matrix_in[0,0] = 100,但未将这个固定值转换为element_vals_dict中的条目,导致约束里没有这个固定值的限制,优化时不会自动遵守该要求。

  • 修复:创建element_vals_dict = {'x0': 100},并传入constraints_func,确保约束包含该等式限制。

内容的提问来源于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 03:55:04