For an exercise i need to solve multiple mixture problems out of different substrats for 4 different products. My problem is that i have a target function to optimize for every sort separately. My goal is to add those 4 targetfunctions to one targetfunction
Thank you for your help!
My code is looking like that: How can i sum the 4 targetfunctions to one targetfunction?
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)
It works completely similar to the answer to your previous question: By using np.ndarray
s instead of classes, i.e.
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
])
you can write the objective function as:
# 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()))