scipy.minimize 如何将多个目标函数相加到一个目标函数?

scipy.minimize How can i sum multiple targetfunctions to one targetfunction?

作为练习,我需要解决 4 种不同产品的不同底物的多个混合问题。我的问题是我有一个目标函数来分别优化每种排序。我的目标是将这 4 个目标函数添加到一个目标函数

感谢您的帮助!

我的代码看起来像这样: 我如何将 4 个目标函数加到一个目标函数?

import numpy as np
import matplotlib.pyplot as plt
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
class sort_3:
    C = 0.4
    N = 0.2
    P = 0.1
    Si = 0.3
class sort_4:
    C = 0.5
    N = 0.05
    P = 0.3
    Si = 0.15

#Pflanzensorte 1:

def targetFun1(y):
    amount_sort1_C = substrat_1.C*y[0] + substrat_2.C*y[1] + substrat_3.C*y[2] + substrat_4.C*y[3]
    amount_sort1_N = substrat_1.N*y[0] + substrat_2.N*y[1] + substrat_3.N*y[2] + substrat_4.N*y[3]
    amount_sort1_P = substrat_1.P*y[0] + substrat_2.P*y[1] + substrat_3.P*y[2] + substrat_4.P*y[3]
    amount_sort1_Si = substrat_1.Si*y[0] + substrat_2.Si*y[1] + substrat_3.Si*y[2] + substrat_4.Si*y[3]
    
    return (np.abs(amount_sort1_C-sort_1.C)+np.abs(amount_sort1_N-sort_1.N)+np.abs(amount_sort1_P-sort_1.P)+np.abs(amount_sort1_Si-sort_1.Si)) 

#Pflanzensorte 2:

def targetFun2(y):
    amount_sort2_C = substrat_1.C*y[4] + substrat_2.C*y[5] + substrat_3.C*y[6] + substrat_4.C*y[7]
    amount_sort2_N = substrat_1.N*y[4] + substrat_2.N*y[5] + substrat_3.N*y[6] + substrat_4.N*y[7]
    amount_sort2_P = substrat_1.P*y[4] + substrat_2.P*y[5] + substrat_3.P*y[6] + substrat_4.P*y[7]
    amount_sort2_Si = substrat_1.Si*y[4] + substrat_2.Si*y[5] + substrat_3.Si*y[6] + substrat_4.Si*y[7]
    
    return (np.abs(amount_sort2_C-sort_2.C)+np.abs(amount_sort2_N-sort_2.N)+np.abs(amount_sort2_P-sort_2.P)+np.abs(amount_sort2_Si-sort_2.Si))

#Pflanzensorte 3:

def targetFun3(y):
    amount_sort3_C = substrat_1.C*y[8] + substrat_2.C*y[9] + substrat_3.C*y[10] + substrat_4.C*y[11]
    amount_sort3_N = substrat_1.N*y[8] + substrat_2.N*y[9] + substrat_3.N*y[10] + substrat_4.N*y[11]
    amount_sort3_P = substrat_1.P*y[8] + substrat_2.P*y[9] + substrat_3.P*y[10] + substrat_4.P*y[11]
    amount_sort3_Si = substrat_1.Si*y[8] + substrat_2.Si*y[9] + substrat_3.Si*y[10] + substrat_4.Si*y[11]
    
    return (np.abs(amount_sort3_C-sort_3.C)+np.abs(amount_sort3_N-sort_3.N)+np.abs(amount_sort3_P-sort_3.P)+np.abs(amount_sort3_Si-sort_3.Si))
#Pflanzensorte 4:

def targetFun4(y):
    amount_sort4_C = substrat_1.C*y[12] + substrat_2.C*y[13] + substrat_3.C*y[14] + substrat_4.C*y[15]
    amount_sort4_N = substrat_1.N*y[12] + substrat_2.N*y[13] + substrat_3.N*y[14] + substrat_4.N*y[15]
    amount_sort4_P = substrat_1.P*y[12] + substrat_2.P*y[13] + substrat_3.P*y[14] + substrat_4.P*y[15]
    amount_sort4_Si = substrat_1.Si*y[12] + substrat_2.Si*y[13] + substrat_3.Si*y[14] + substrat_4.Si*y[15]
    
    return (np.abs(amount_sort4_C-sort_4.C)+np.abs(amount_sort4_N-sort_4.N)+np.abs(amount_sort4_P-sort_4.P)+np.abs(amount_sort4_Si-sort_4.Si))

bnds=((0,1),(0,1),(0,1),(0,1),(0,1),(0,1),(0,1),(0,1),(0,1),(0,1),(0,1),(0,1),(0,1),(0,1),(0,1),(0,1)) 
y0 = np.zeros((16,))

res = minimize(lambda y: targetFun1(y) + targetFun2(y)+ targetFun3(y) + targetFun4(y), x0 = y0, method='SLSQP', bounds=bnds)
y = res.x.reshape(4,4)
print(y)

它的工作原理与 完全相似:通过使用 np.ndarray 而不是 类,即

substrat = np.array([
    [0.93, 0.005, 0.031, 0.034],  # substrat_1
    [0.523, 0.3, 0.123, 0.054],   # substrat_2
    [0.257, 0.176, 0.461, 0.106], # substrat_3
    [0.694, 0.005, 0.003, 0.298], # substrat_4
])

sort = np.array([
    [0.7, 0.15, 0.05, 0.1], # sort_1
    [0.8, 0.03, 0.1, 0.07], # sort_2
    [0.4, 0.2, 0.1, 0.3],   # sort_3
    [0.5, 0.05, 0.3, 0.15], # sort_4
])

您可以将 objective 函数编写为:

# create the block diagonal matrix:
# 
# ( substrat.T      0           0           0      )
# (    0        substrat.T      0           0      )
# (    0            0       substrat.T      0      )
# (    0            0.          0       substrat.T )
#
DiagSubstrat = np.kron(np.eye(4), substrat.T)

def targetFun(y): 
    return np.sum(np.abs(DiagSubstrat @ y - sort.flatten()))