You need to enable JavaScript to run this app. Scipy.minimize使用教程:如何同时最小化两个函数实现基质配比优化
优惠活动
大模型
产品
解决方案
定价
更多

Scipy.minimize使用教程:如何同时最小化两个函数实现基质配比优化

问题原因

scipy.optimize.minimize 要求目标函数必须返回单个标量的损失值,你之前尝试直接返回两个产物的独立损失值不符合接口要求,只要将两个损失相加合并为一个总损失即可解决问题。
另外补充一个代码里遗漏的逻辑:如果变量里存的是基质占比,需要添加约束条件保证产物1的4个基质占比之和为1,产物2的4个基质占比之和为1,否则优化结果没有实际意义。

完整修改后的代码

import numpy as np
from scipy.optimize import minimize

# 基质组分定义
class substrat_1:
    C = 0.93
    N = 0.005
    P = 0.031
    Si = 0.034

class substrat_2:
    C = 0.523
    N = 0.3
    P = 0.123
    Si = 0.054

class substrat_3:
    C = 0.257
    N = 0.176
    P = 0.461
    Si = 0.106

class substrat_4:
    C = 0.694
    N = 0.005
    P = 0.003
    Si = 0.298

# 产物目标组分定义
class sort_1:
    C = 0.7
    N = 0.15
    P = 0.05
    Si = 0.1

class sort_2:
    C = 0.8
    N = 0.03
    P = 0.1
    Si = 0.07

# 合并后的目标函数
def combined_target(y):
    # 计算产物1的组分偏差
    s1_C = substrat_1.C*y[0] + substrat_2.C*y[1] + substrat_3.C*y[2] + substrat_4.C*y[3]
    s1_N = substrat_1.N*y[0] + substrat_2.N*y[1] + substrat_3.N*y[2] + substrat_4.N*y[3]
    s1_P = substrat_1.P*y[0] + substrat_2.P*y[1] + substrat_3.P*y[2] + substrat_4.P*y[3]
    s1_Si = substrat_1.Si*y[0] + substrat_2.Si*y[1] + substrat_3.Si*y[2] + substrat_4.Si*y[3]
    loss1 = np.abs(s1_C-sort_1.C) + np.abs(s1_N-sort_1.N) + np.abs(s1_P-sort_1.P) + np.abs(s1_Si-sort_1.Si)
    
    # 计算产物2的组分偏差
    s2_C = substrat_1.C*y[4] + substrat_2.C*y[5] + substrat_3.C*y[6] + substrat_4.C*y[7]
    s2_N = substrat_1.N*y[4] + substrat_2.N*y[5] + substrat_3.N*y[6] + substrat_4.N*y[7]
    s2_P = substrat_1.P*y[4] + substrat_2.P*y[5] + substrat_3.P*y[6] + substrat_4.P*y[7]
    s2_Si = substrat_1.Si*y[4] + substrat_2.Si*y[5] + substrat_3.Si*y[6] + substrat_4.Si*y[7]
    loss2 = np.abs(s2_C-sort_2.C) + np.abs(s2_N-sort_2.N) + np.abs(s2_P-sort_2.P) + np.abs(s2_Si-sort_2.Si)
    
    # 合并为单值损失返回,可调整权重w1、w2侧重不同产物的优化精度
    w1, w2 = 1, 1
    return w1 * loss1 + w2 * loss2

# 约束条件:两个产物的基质占比之和都为1
cons = (
    {'type': 'eq', 'fun': lambda y: np.sum(y[:4]) - 1},
    {'type': 'eq', 'fun': lambda y: np.sum(y[4:]) - 1}
)

# 变量边界:所有占比在0到1之间
bnds = ((0,1),(0,1),(0,1),(0,1),(0,1),(0,1),(0,1),(0,1))
# 初始值
y0 = np.ones(8) / 4

# 执行优化
res = minimize(combined_target, x0=y0, method='SLSQP', bounds=bnds, constraints=cons)

# 输出结果
print("优化得到的配比:")
print(f"产物1的基质占比(基质1-4):{np.round(res.x[:4], 4)},总和:{np.round(np.sum(res.x[:4]), 4)}")
print(f"产物2的基质占比(基质1-4):{np.round(res.x[4:], 4)},总和:{np.round(np.sum(res.x[4:]), 4)}")
print(f"总损失值:{np.round(res.fun, 6)}")

说明

  • 若需要优先保证某个产物的组分精度,调整目标函数里的w1、w2权重即可,比如把w1设为2代表产物1的优化优先级是产物2的2倍。
  • 如果你的y变量是基质的绝对用量而非占比,删除对应的约束条件即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.15 01:36:04