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()))
作为练习,我需要解决 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()))