使用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中添加约束参数,比如:
或者直接使用mystic的优化器,它能更直接地应用生成的约束。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)
6. 固定元素未加入约束字典
matrix_in中设置了matrix_in[0,0] = 100,但未将这个固定值转换为element_vals_dict中的条目,导致约束里没有这个固定值的限制,优化时不会自动遵守该要求。
- 修复:创建
element_vals_dict = {'x0': 100},并传入constraints_func,确保约束包含该等式限制。
内容的提问来源于stack exchange,提问作者star_it8293
相关产品推荐
相关产品推荐

