Linear modeling solver with set restrictions in pulp python - python

I have this integer linear modeling problem
xn = {0,1}
xn integer
max 12*x1+3*x2+4*x3+1*x4+23*x5+44*x6+55*x7+31*x8+4*x9+17*x10
1000*x1+3000*x2+3500*x3+1200*x4+1023*x5+2044*x6+5050*x7+2100*x8+3500*x9+1700*x10 <= 10000
T1 = {x1,x2,x3}
T2 = {x4}
T3 = {x5,x6,x7,x8}
T4 = {x9,x10}
I need at least one element of 3 different T1,T2,T3,T4 sets
First two are easy to code with pulp in python
import pulp
#Constraints
P_UID = ['x1','x2','x3','x4','x5','x6','x7','x8','x9','x10']
P_Var = pulp.LpVariable.dicts("x", P_UID, lowBound = 0, upBound=1, cat="Integer")
OptimizeCoef = [12,3,4,1,23,44,55,31,4,17]
OptimizeFunction = pulp.LpAffineExpression([(P_Var[P_UID[i]],OptimizeCoef[i]) for i in range(len(P_UID))])
OverBoundCoef = [1000,3000,3500,1200,1023,2044,5050,2100,3500,1700]
OverBoundFunction = pulp.LpAffineExpression([(P_Var[P_UID[i]],OverBoundCoef[i]) for i in range(len(P_UID))])
OverBoundFunction = pulp.LpConstraint(e=OverBoundFunction,sense = pulp.LpConstraintLE, rhs=10000)
SelectionX = pulp.LpProblem('SelectionX', pulp.LpMaximize)
SelectionX += OptimizeFunction
SelectionX += OverBoundFunction
#Solvers
SelectionX.writeLP("SelectionPlayersModel.lp")
solver = pulp.solvers.PULP_CBC_CMD()
pulp.LpSolverDefault.msg = 1
SelectionX.solve(solver)
print (pulp.value(SelectionX.objective))
for v in SelectionX.variables():
if v.varValue > 10e-4:
print ( v.name, v.varValue)
I obtain next result with this code
139.0
x_x10 1.0
x_x5 1.0
x_x6 1.0
x_x7 1.0
But I don't know how to program set restrictions

A bit tricky but I would add a binary variable for each set
T1 >= x1
T1 >= x2
T1 >= x3
T1 <= x1 + x2 + x3
...
Then add
T1 + T2 + T3 + T4 >= 3

Thanks, that's a very good trick.
I changed "T" restrictions like that
T1-x1>=0
T1-x2>=0
T1-x3>=0
x1 + x2 + x3-T1>=0
...
I paste here all code
import pulp
#Constraints
P_UID = ['x1','x2','x3','x4','x5','x6','x7','x8','x9','x10']
P_Var = pulp.LpVariable.dicts("x", P_UID, lowBound = 0, upBound=1, cat="Integer")
T_UID = ['T1','T2','T3','T4']
T_Var = pulp.LpVariable.dicts("y", T_UID, lowBound = 0, upBound=1, cat="Integer")
PinT = [[1,1,1,0,0,0,0,0,0,0],[0,0,0,1,0,0,0,0,0,0],[0,0,0,0,1,1,1,1,0,0],[0,0,0,0,0,0,0,0,1,1]]
OptimizeCoef = [12,3,4,1,23,44,55,31,4,17]
OptimizeFunction = pulp.LpAffineExpression([(P_Var[P_UID[i]],OptimizeCoef[i]) for i in range(len(P_UID))])
OverBoundCoef = [1000,3000,3500,1200,1023,2044,5050,2100,3500,1700]
OverBoundFunction = pulp.LpAffineExpression([(P_Var[P_UID[i]],OverBoundCoef[i]) for i in range(len(P_UID))])
OverBoundFunction = pulp.LpConstraint(e=OverBoundFunction,sense = pulp.LpConstraintLE, rhs=10000)
PInTBound = []
PAllInTBound = []
TNum = 0
for T in T_UID:
for p in range(len(P_UID)):
if PinT[TNum][p]>0:
PInTBoundTemp = pulp.LpAffineExpression(T_Var[T_UID[TNum]]-P_Var[P_UID[p]])
PInTBoundTemp = pulp.LpConstraint(e=PInTBoundTemp,sense = pulp.LpConstraintGE, rhs=0)
PInTBound.append(PInTBoundTemp)
PAllInTBoundTemp = pulp.LpAffineExpression([(P_Var[P_UID[i]],PinT[TNum][i]) for i in range(len(P_UID))])+\
pulp.LpAffineExpression(-T_Var[T_UID[TNum]])
PAllInTBoundTemp = pulp.LpConstraint(e=PAllInTBoundTemp,sense = pulp.LpConstraintGE, \
rhs=0)
PAllInTBound.append(PAllInTBoundTemp)
TNum += 1
TBoundFunction = pulp.LpAffineExpression([(T_Var[T_UID[i]],1) for i in range(len(T_UID))])
TBoundFunction = pulp.LpConstraint(e=TBoundFunction,sense = pulp.LpConstraintGE, rhs=3)
SelectionX = pulp.LpProblem('SelectionX', pulp.LpMaximize)
SelectionX += OptimizeFunction
SelectionX += OverBoundFunction
SelectionX += TBoundFunction
for Bound in PAllInTBound:
SelectionX += Bound
for Bound in PInTBound:
SelectionX += Bound
#Solvers
SelectionX.writeLP("SelectionXModel.lp")
solver = pulp.solvers.PULP_CBC_CMD()
pulp.LpSolverDefault.msg = 1
SelectionX.solve(solver)
print ('Maximized Value:', pulp.value(SelectionX.objective))
print(pulp.LpStatus[SelectionX.status])
for v in SelectionX.variables():
if v.varValue > 10e-4:
print ( v.name, v.varValue)
This is result
Maximized Value: 128.0
Optimal
x_x1 1.0
x_x10 1.0
x_x4 1.0
x_x5 1.0
x_x6 1.0
x_x8 1.0
y_T1 1.0
y_T2 1.0
y_T3 1.0
y_T4 1.0

Related

Define a decision variable of M0 in CPLEX

Good day to you.
From a previous model with cplex (MIP 1), I use M0 as a parameter.
Total_P = 8
M0 = np.array([[0,1,0,1,0,0,0,2]]).reshape(Total_P,1)
Then, I tried to develop a different model (MIP 2) with adjusted objectives and constraints from MIP2, however, the M0 now becomes a decision variable and use for several constraints (#constraint 38). So, I created a code as follows:
Total_P = 8
M0 = np.empty((Total_P,1), dtype = object)
for l in range(0,Total_P):
M0[l][0]= mdl.integer_var(name='M0'+ str(',') + str(l+1))
for l in range(0,Total_P):
if M0[l][0] is not None:
mdl.add_constraint((M0[1][0] + M0[5][0]) == 1)
mdl.add_constraint((M0[3][0] + M0[6][0]) == 1)
mdl.add_constraint((M0[0][0] + M0[2][0] + M0[4][0] + M0[7][0]) == 2)
After running the cplex with the same parameters input:
The result from MIP 1: obj_lambda=213
The result from MIP 2: obj_lamba= 205.0 and the M0 is [[0,1,1,0,0,0,1,1]]
The correct result of M0 from the MIP 2 should be [[0,1,0,1,0,0,0,2]] as in the M0 (parameter in MIP 1) and obj_lambda=213.
Here is the full code of MIP 1:
import cplex
from docplex.mp.model import Model
import numpy as np
mdl = Model(name='Scheduling MIP 1')
inf = cplex.infinity
bigM= 10000
Total_P = 8 # number of places
Total_T = 6 # number of transitions
r1 = 100 #processing time for PM1 (second)
r2 = 200 #processing time for PM2 (second)
v = 3 #robot moving time (second)
w = 5 #loading or unloading time (second)
M0 = np.array([[0,1,1,0,0,0,1,1]]).reshape(Total_P,1)
M0_temp = M0.reshape(1,Total_P)
M0_final = M0_temp.tolist()*Total_T
h = np.array([v+w,w+r1,v+w,w+r2,v+w,0,0,0]).reshape(Total_P,1)
#Parameter
AT =np.array([[1,-1,0,0,0,0],
[0,1,-1,0,0,0],
[0,0,1,-1,0,0],
[0,0,0,1,-1,0],
[0,0,0,0,1,-1],
[0,-1,1,0,0,0],
[0,0,0,-1,1,0],
[-1,1,-1,1,-1,1]])
AT_temp = AT.transpose()
places = np.array(['p1','p2','p3','p4','p5','p6','p7','p8'])
P_conflict = np.empty((1,Total_P), dtype = object)
P_zero = np.empty((1,Total_P), dtype = object)
#Define the place without conflict place
CP = np.count_nonzero(AT, axis=1, keepdims=True) #calculate the nonzero elements for each row
P_conflict = []
P_zero = []
for a in range(0, len(CP)):
if CP[a].item(0) > 2:
P_conflict.append(places[a])
else:
P_zero.append(places[a])
print('p_zero', np.shape(P_zero))
obj_lambda = [ ]
obj_lambda = mdl.continuous_var(lb = 0, ub=inf, name='obj_lambda')
x = np.array(mdl.continuous_var_list(Total_T, 0, inf, name='x')).reshape(Total_T,)
ind_x = np.where(AT[0] == 1)
print('ind_x', ind_x)
def get_index_value(input):
data = []
for l in range(len(P_zero)):
ind_x = np.where(AT[l] == input)
get_value = x[ind_x]
data.append(get_value)
return data
x_in = get_index_value(1)
x_out = get_index_value(-1)
#constraint 16
for l in range(0,len(P_zero)): #only for P non conflict
#if x_in is not None and x_out is not None and obj_lambda is not None:
mdl.add_constraint(x_out[l][0]-x_in[l][0] >= h[l][0] - M0[l][0]*obj_lambda)
#Decision Var
Z = np.empty((Total_T, Total_T), dtype = object)
for k in range(Total_T):
for i in range(Total_T):
Z[k][i] = mdl.binary_var(name='Z' + str(k+1) + str(',') + str(i+1))
storage_ZAT = []
for k in range(Total_T):
ZAT = np.matmul(Z[k].reshape(1,Total_T),AT_temp)
storage_ZAT.append(ZAT) #storage_ZAT = np.append(storage_ZAT, ZAT, axis=0)
ZAT_final = np.asarray(storage_ZAT).reshape(Total_T,Total_P)
M = np.empty((Total_T, Total_P), dtype = object)
for k in range(0,Total_T):
for l in range (0,Total_P):
if k == Total_T-1:
M[Total_T-1][l] = M0_final[0][l]
else:
M[k][l] = mdl.continuous_var(name='M' + str(k + 1) + str(',') + str(l + 1))
M_prev = np.empty((Total_T, Total_P), dtype = object)
if M is not None:
for k in range(0,Total_T):
for l in range (0,Total_P):
if k is not 0:
M_prev[k][l] = M[k-1][l]
else:
M_prev[0][l] = M0_final[0][l]
#Constraint 17
for k in range(Total_T):
for l in range(Total_P):
mdl.add_constraint(M[k][l] == M_prev[k][l] + ZAT_final[k][l])
#Constraint 18
mdl.add_constraints(mdl.sum(Z[k][i] for k in range(Total_T)) == 1 for i in range(Total_T))
# Constraint 19
mdl.add_constraints(mdl.sum(Z[k][i] for i in range(Total_T)) == 1 for k in range(Total_T))
# # Parameters
VW_temp = [[v + w]]
VW_temp = VW_temp*Total_T
VW = np.array(VW_temp) #eshape(Total_T,)
#Define S
S = np.array(mdl.continuous_var_list(Total_T, 0, inf, name='S')).reshape(Total_T,1)
#Constraint 20
for k in range(Total_T-1):
mdl.add_constraint(S[k][0] - S[k+1][0] <= -VW[k][0])
# # Constraint 21
mdl.add_constraint(S[Total_T-1][0] - (S[0][0] + obj_lambda) <=-VW[Total_T-1][0])
x_temp = x.reshape(Total_T,1)
print('x_temp',x_temp)
# Constraint 22
for k in range(Total_T):
for i in range(Total_T):
mdl.add_constraint(S[k][0] - x_temp[i][0] <= (1-Z[k][i])*bigM) #why x_temp? because it is the reshape of x
# Constraint 23
for k in range(Total_T):
for i in range(Total_T):
mdl.add_constraint(S[k][0] - x_temp[i][0] >= (Z[k][i]-1)*bigM)
mdl.minimize(obj_lambda)
mdl.print_information()
solver = mdl.solve() #(log_output=True)
if solver is not None:
mdl.print_solution()
miu = 1 / obj_lambda.solution_value
print('obj_lamba=', obj_lambda.solution_value)
print('miu =', miu)
else:
print("Solver is error")
Here is the code of MIP 2:
import cplex
from docplex.mp.model import Model
import numpy as np
mdl = Model(name='Scheduling MILP 2')
inf = cplex.infinity
bigM= 10000
Total_P = 8 # number of places
Total_T = 6 # number of transitions
r1 = 100 #processing time for PM1 (second)
r2 = 200 #processing time for PM2 (second)
v = 3 #robot moving time (second)
w = 5 #loading or unloading time (second)
h = np.array([v+w,w+r1,v+w,w+r2,v+w,0,0,0]).reshape(Total_P,1)
#Parameter
AT =np.array([[1,-1,0,0,0,0],
[0,1,-1,0,0,0],
[0,0,1,-1,0,0],
[0,0,0,1,-1,0],
[0,0,0,0,1,-1],
[0,-1,1,0,0,0],
[0,0,0,-1,1,0],
[-1,1,-1,1,-1,1]])
AT_temp = AT.transpose()
places = np.array(['p1','p2','p3','p4','p5','p6','p7','p8'])
P_conflict = np.empty((1,Total_P), dtype = object)
P_zero = np.empty((1,Total_P), dtype = object)
#Define the place without conflict place
CP = np.count_nonzero(AT, axis=1, keepdims=True) #calculate the nonzero elements for each row
P_conflict = []
P_zero = []
for a in range(0, len(CP)):
if CP[a].item(0) > 2:
P_conflict.append(places[a])
else:
P_zero.append(places[a])
print('p_zero', P_zero)
y = [ ] #miu
y = mdl.continuous_var(lb = 0, ub=inf, name='miu') #error: docplex.mp.utils.DOcplexException: Variable obj_lambda cannot be used as denominator of 1
x = np.array(mdl.continuous_var_list(Total_T, 0, inf, name='x')).reshape(Total_T,)
ind_x = np.where(AT[0] == 1)
def get_index_value(input):
data = []
for l in range(len(P_zero)):
ind_x = np.where(AT[l] == input)
get_value = x[ind_x]
data.append(get_value)
return data
x_in_hat = get_index_value(1)
x_out_hat = get_index_value(-1)
M0 = np.empty((Total_P,1), dtype = object)
for l in range(0,Total_P):
M0[l][0]= mdl.integer_var(name='M0'+ str(',') + str(l+1))
M0_temp= M0.reshape(1,Total_P)
M0_final = M0_temp.tolist()*Total_T
for k in range(Total_T):
for l in range(Total_P):
if M0_final[k][l] is not None:
mdl.add_constraint((M0_final[0][1] + M0_final[0][5]) == 1)
mdl.add_constraint((M0_final[0][3] + M0_final[0][6]) == 1)
mdl.add_constraint((M0_final[0][0] + M0_final[0][2] + M0_final[0][4] + M0_final[0][7]) == 2)
#constraint 30
for l in range(0,len(P_zero)): #only for P non conflict
mdl.add_constraint(x_out_hat[l][0]-x_in_hat[l][0] >= h[l][0]*y - M0[l][0])
#Decision Var
Z = np.empty((Total_T, Total_T), dtype = object)
for k in range(Total_T):
for i in range(Total_T):
# if k == 0 and i == 0:
# Z[0][0]=1
# else:
Z[k][i] = mdl.binary_var(name='Z' + str(k+1) + str(',') + str(i+1))
#
storage_ZAT = []
for k in range(Total_T):
ZAT = np.matmul(Z[k].reshape(1,Total_T),AT_temp)
storage_ZAT.append(ZAT) #storage_ZAT = np.append(storage_ZAT, ZAT, axis=0)
ZAT_final = np.asarray(storage_ZAT).reshape(Total_T,Total_P)
M = np.empty((Total_T, Total_P), dtype = object)
for k in range(0,Total_T):
for l in range (0,Total_P):
if k == Total_T-1:
M[Total_T-1][l] = M0_final[0][l]
else:
M[k][l] = mdl.continuous_var(name='M' + str(k + 1) + str(',') + str(l + 1))
M_prev = np.empty((Total_T, Total_P), dtype = object)
if M is not None:
for k in range(0,Total_T):
for l in range (0,Total_P):
if k is not 0:
M_prev[k][l] = M[k-1][l]
else:
M_prev[0][l] = M0_final[0][l]
#
#Constraint 31
for k in range(Total_T):
for l in range(Total_P):
mdl.add_constraint(M[k][l] == M_prev[k][l] + ZAT_final[k][l])
#
#Constraint 32
mdl.add_constraints(mdl.sum(Z[k][i] for k in range(Total_T)) == 1 for i in range(Total_T))
# Constraint 33
mdl.add_constraints(mdl.sum(Z[k][i] for i in range(Total_T)) == 1 for k in range(Total_T))
# #
# # # # Parameters
VW_temp = [[v + w]]
VW_temp = VW_temp*Total_T
VW = np.array(VW_temp) #eshape(Total_T,)
#
S_hat = np.array(mdl.continuous_var_list(Total_T, 0, inf, name='S_hat')).reshape(Total_T,1)
#Constraint 34
for k in range(0,Total_T-1):
if k < (Total_T-1):
mdl.add_constraint(S_hat[k][0] - S_hat[k+1][0] <= -VW[k][0]*y)
if k == (Total_T - 1):
mdl.add_constraint(S_hat[k][0] - (S_hat[0][0] + 1) <= -VW[Total_T - 1][0] * y)# Constraint 35
#
#
x_temp_hat = x.reshape(Total_T,1)
#
# Constraint 36
for k in range(Total_T):
for i in range(Total_T):
mdl.add_constraint((S_hat[k][0] - x_temp_hat[i][0]) <= (1-Z[k][i])*bigM) #why x_temp? because it is the reshape of x
# Constraint 37
for k in range(Total_T):
for i in range(Total_T):
mdl.add_constraint((S_hat[k][0] - x_temp_hat[i][0]) >= (Z[k][i]-1)*bigM)
mdl.maximize(y)
mdl.print_information()
solver = mdl.solve()
if solver is not None:
mdl.print_solution()
obj_lambda = 1/y.solution_value
print('miu =', y.solution_value)
print('obj_lamba=', obj_lambda)
print('M0 final=', M0_temp)
else:
print("Solver is error")
In this case, could anyone tell me: did I define the M0 as a decision variable and put them into the constraints correctly, please?
Thank you.

Find optimal value of model by Koshi simulated annealing

I should find optimal value of model by Koshi simulated annealing.
Model:
Index Height Weight
0 1 65.78331 112.9925
1 2 71.51521 136.4873
2 3 69.39874 153.0269
3 4 68.21660 142.3354
4 5 67.78781 144.2971
def mse(w):
height = dataset['Height']
weight = dataset['Weight']
predicts = list(map(lambda x: w[0] + w[1] * x, weight))
mse = mean_squared_error(height, predicts)
return mse
Initial values:
Tmax = 13
Tmin = -9.5
T = Tmax
wop0 = 1
wop1 = 100
Eglob = random.random()
w0_ = random.uniform(0, 100)
w1_ = random.uniform(0, 5)
w0 = w0_
w1 = w1_
E = mse([w0, w1])
Main function:
iteration = 0
while T > Tmin:
i = 1
for i in range(1,6000):
w0 = w0 + T * np.random.standard_cauchy()
w1 = w1 + T * np.random.standard_cauchy()
E = mse([w0, w1])
dE = E - mse([wop0, wop1])
if dE < 0:
wop0 = w0
wop1 = w1
Eglob = E
else:
a = random.random()
#h = 1 / (1 + np.exp(dE / T))
h = np.exp(-dE / T)
if a < h:
wop0 = w0
wop1 = w1
Eglob = E
T= Tmax / math.log(1+i);
iteration += 1
break
Result:
iteration: 5999
wop0: -706.4779870159789
wop1: 3.716864959467018
mse: 93084.16405699923
But if I use basinhopping function:
from scipy.optimize import basinhopping
ret = basinhopping(mse, [0, 1], niter = 50)
print("global min: w = [%.4f, %.4f], mse(w0, w1) = %.4f" % (ret.x[0], ret.x[1], ret.fun))
Result:
global min: w = [57.5718, 0.0820], mse(w0, w1) = 2.7018
What I'm doing wrong?
Thanks

GEKKO error in model expression with array of variables and intermediates

I am trying to use GEKKO for fitting and function parameters estimation.
I need to use arrays of variables and arrays of intermediate-type variables because of changing number of parameters to fit.
And got an error I think in a model.
apm some_ip_here_gk_model14 <br><pre> ----------------------------------------------------------------
APMonitor, Version 1.0.1
APMonitor Optimization Suite
----------------------------------------------------------------
--------- APM Model Size ------------
Each time step contains
Objects : 0
Constants : 2
Variables : 15
Intermediates: 22
Connections : 0
Equations : 24
Residuals : 2
#error: Model Expression
*** Error in syntax of function string: Invalid element: none
Position: 1
none
?
how to check what is this error?
I am running this code in jupyter notebook and I tried to look apm file - didn't find it in the folder where this jupyter notebook is situated. Where should I search?
Here is the code.
import numpy as np
from gekko import GEKKO
import math
M = 10; m = 1; gj =1; n = 1
num_pulses_in_window = 4
сonstant = 1; ac = 1
el_init_guess = [1,2,3,4]
borders_left = [1,2,3,4]
borders_right = [1,2,3,4]
A1_c = (M/(M+m))*сonstant
gj_c = gj
# using GEKKO for preliminary estomation
xData = np.array([1,2,3,4])
yData = np.array([2.5,1.2,3.2,1.1])
model = GEKKO()
# parameters
x = model.Param(value = xData)
z = model.Param(value = yData)
# constants
A1 = model.Const(A1_c)
gj = model.Const(gj_c)
# variables
E = model.Array(model.Var, num_pulses_in_window)
G1 = model.Array(model.Var, num_pulses_in_window)
G2 = model.Array(model.Var, num_pulses_in_window)
Gg = model.Array(model.Var, num_pulses_in_window)
#Intermediates
k_alfa = model.Intermediate(A1*model.sqrt(x))
ro = model.Intermediate(k_alfa*ac)
phi = model.Intermediate(ro)
G = model.Array(model.Intermediate, num_pulses_in_window, equation=None)
d = model.Array(model.Intermediate, num_pulses_in_window, equation=None)
f = model.Array(model.Intermediate, num_pulses_in_window, equation=None)
for i in range(0, num_pulses_in_window):
E[i].value = el_init_guess[i]
E[i].lower = borders_left[i]
E[i].upper = borders_right[i]
#G1
G1[i].lower = 0.0000001
G1[i].upper = 1
#G2
G2[i].lower = 0
G2[i].upper = 0
#Gg
Gg[i].lower = 0.0000001
Gg[i].upper = 1
G[i] = model.Intermediate(G1[i]+G2[i]+Gg[i])
d[i] = model.Intermediate((E[i]-x)**2+(G[i]/2)**2)
f[i] = model.Intermediate((1-(1-(G[i]*G1[i]/(2*d[i])))*model.cos(2*phi)-((E[i]-x)*G[i]/d[i])*model.sin(2*phi)))
sigma_sum = model.Intermediate(2*math.pi*gj/k_alfa * (model.sum(f)))
y = model.Var()
model.Equation(y == model.exp(-n*sigma_sum))
model.Minimize(((y-z))**2)
model.options.IMODE = 2
model.options.SOLVER = 3
model.options.MAX_ITER = 1000
model.solve(disp=1)
Intermediates are not defined with m.Array() because they are defined with the m.Intermediate() method. Try using an empty list instead:
G = [None]*num_pulses_in_window
d = [None]*num_pulses_in_window
f = [None]*num_pulses_in_window
For troubleshooting, open the run folder with model.open_folder() and inspect gk_model0.apm with a text editor. This is a plain text version of the model. The 4th and onward intermediates are not defined correctly.
Model
Constants
i0 = 0.9090909090909091
i1 = 1
End Constants
Parameters
p1
p2
End Parameters
Variables
v1 = 1, <= 1, >= 1
v2 = 2, <= 2, >= 2
v3 = 3, <= 3, >= 3
v4 = 4, <= 4, >= 4
...
v13 = 0, <= 1, >= 1e-07
v14 = 0, <= 1, >= 1e-07
v15 = 0, <= 1, >= 1e-07
v16 = 0, <= 1, >= 1e-07
v17 = 0
End Variables
Intermediates
i2=((i0)*(sqrt(p1)))
i3=((i2)*(1))
i4=i3
i5=None
i6=None
i7=None
i8=None
i9=None
...
Here is a script that runs successfully:
import numpy as np
from gekko import GEKKO
import math
M = 10; m = 1; gj =1; n = 1
num_pulses_in_window = 4
сonstant = 1; ac = 1
el_init_guess = [1,2,3,4]
borders_left = [1,2,3,4]
borders_right = [1,2,3,4]
A1_c = (M/(M+m))*сonstant
gj_c = gj
# using GEKKO for preliminary estomation
xData = np.array([1,2,3,4])
yData = np.array([2.5,1.2,3.2,1.1])
model = GEKKO()
# parameters
x = model.Param(value = xData)
z = model.Param(value = yData)
# constants
A1 = model.Const(A1_c)
gj = model.Const(gj_c)
# variables
E = model.Array(model.Var, num_pulses_in_window)
G1 = model.Array(model.Var, num_pulses_in_window)
G2 = model.Array(model.Var, num_pulses_in_window)
Gg = model.Array(model.Var, num_pulses_in_window)
#Intermediates
k_alfa = model.Intermediate(A1*model.sqrt(x))
ro = model.Intermediate(k_alfa*ac)
phi = model.Intermediate(ro)
G = [None]*num_pulses_in_window
d = [None]*num_pulses_in_window
f = [None]*num_pulses_in_window
for i in range(0, num_pulses_in_window):
E[i].value = el_init_guess[i]
E[i].lower = borders_left[i]
E[i].upper = borders_right[i]
#G1
G1[i].lower = 0.0000001
G1[i].upper = 1
#G2
G2[i].lower = 0
G2[i].upper = 0
#Gg
Gg[i].lower = 0.0000001
Gg[i].upper = 1
G[i] = model.Intermediate(G1[i]+G2[i]+Gg[i])
d[i] = model.Intermediate((E[i]-x)**2+(G[i]/2)**2)
f[i] = model.Intermediate((1-(1-(G[i]*G1[i]/(2*d[i])))*model.cos(2*phi)-((E[i]-x)*G[i]/d[i])*model.sin(2*phi)))
sigma_sum = model.Intermediate(2*math.pi*gj/k_alfa * (model.sum(f)))
y = model.Var()
model.Equation(y == model.exp(-n*sigma_sum))
model.Minimize(((y-z))**2)
model.options.IMODE = 2
model.options.SOLVER = 3
model.options.MAX_ITER = 1000
model.solve(disp=1)
Don't forget to include dummy values in your script so that it runs and produces the error. I edited the question to include sample values in your question:
M = 10; m = 1; gj =1; n = 1
num_pulses_in_window = 4
сonstant = 1; ac = 1
el_init_guess = [1,2,3,4]
borders_left = [1,2,3,4]
borders_right = [1,2,3,4]
A1_c = (M/(M+m))*сonstant
gj_c = gj
# using GEKKO for preliminary estomation
xData = np.array([1,2,3,4])
yData = np.array([2.5,1.2,3.2,1.1])

System of seven ODEs solve using solve_ivp or implement RK4

I'm trying solve a system of coupled ordinary differential equations, formed by 7 ODEs in python, using solve_ivp or either implement a fuction for RK4.
The general physical problem is as follows:
Cooling of photovoltaic modules with heat exchanger coupling to the module. In this way, the module generates electrical energy and thermal energy.
I have a polynomial function, G(t) = 9.8385e-13*t^4 - 1.82918e-8*t^3 + 5.991355e-05*t^2 + 2.312059e-1*t + 25, which works for an approximate range of 0 < t < 9000, which represents solar radiation as a function of time of day.
This function was obtained through a "polyfit" applied to real data (file upload here. Its a CSV - https://files.fm/u/9y4evkf6c).
This function is used as input for the ODEs, which represent an electrical and a thermal system as a function of time.
To solve the electrical model, I created some scripts that solve the diode equation for the photovoltaic module in question, and the output of this script is the photovoltaic power (called in the PPV thermal model) generated as a function of the module temperature and radiation. This script works great and solves part of my problem.
My difficulty lies in solving the equations of the thermal model, which receives as input parameters G(t) and PPV.
The equations result in this system:
System of EDOS
Labels:
Tvidro = Tglass = T1
Tcel = Tpv = T2
Ttedlar = T3
Tabs = Tabsorber = T4
Ttubo = Ttube = T5
Tfsai = Tfluid_out = T6
Tiso = Tinsulation = T7
Using method/function for RK4, the complete code is like this (you can go direct to part "#DEFINE MODEL EQUATIONS - ODES)" :
import numpy as np
import matplotlib.pyplot as plt
import csv
from numpy.polynomial.polynomial import polyval
############################################################
with open('directory of data called teste_dados_radiacao',"r") as i:
rawdata = list(csv.reader(i, delimiter = ";"))
exampledata = np.array(rawdata[1:], dtype=float)
xdata = exampledata[:,0]
ydata = exampledata[:,1]
curve = np.array(np.polyfit(xdata, ydata, 4))
rev_curve = np.array(list(reversed(curve)), dtype=float)
print(rev_curve)
#G_ajustado = polyval(xdata, rev_curve)
""" plt.plot(xdata, ydata, label = "dados experimentais")
plt.plot(xdata, model, label = "model")
plt.legend()
plt.show() """
#############################################################
#CONSTANTS
Tamb = 25 #°C #ambient temperatura
SIGMA = 5.67e-8 #W/m2K4
E_VIDRO = 0.90 #between 0.85 e 0.83 #nasrin2017 0.04
VENTO = 2 #m/s
T_GROUND = Tamb + 2 #°C
T_CEU = 0.00552*Tamb**1.5
Vf = 1 #m/s
Do = 10e-3 #m
Di = 8e-3 #m
NS = 6*10 #number of cells
T_F_ENT = 20 #°C
#INPUTS
Tcel = 25
Tv = 25
Tiso = 30
Av = 1.638*0.982
ALPHA_VIDRO = 0.9
L_VIDRO = 3e-3 #m
RHO_VIDRO = 2500 #kg/m3
M_VIDRO = Av*L_VIDRO*RHO_VIDRO #kg
CP_VIDRO = 500 #j/kgK
K_VIDRO = 2 #W/mK
TAU_VIDRO = 0.95
Pac = 0.85
H_CELL = 0.156 #m
A_CELL = NS*H_CELL**2
ALPHA_CELL = 0.9
L_CEL = 3e-3
RHO_CEL = 2330
M_CEL = A_CELL*L_CEL*RHO_CEL #kg - estimated
CP_CEL = 900 #J/kgK
K_CEL = 140 #W/mK
BETA_T = 0.43/100 # %/°C
N_ELE_REF = 0.1368 #13.68%
N_ELE = N_ELE_REF*(1 - BETA_T*(Tcel - 25)) #273 + 25 - tcel kelvin
A_tedlar = Av
L_TEDLAR = 0.33e-3
RHO_TEDLAR = 1500
M_TEDLAR = Av*L_TEDLAR*RHO_TEDLAR
CP_TEDLAR = 1090 #1090 OU 2090
K_TEDLAR = 0.35
ALPHA_TEDLAR = 0.34 #doc nasa ou zero
#parameters
RHO_ABS = 2700
A_ABS = Av
CP_ABS =900
L_ABS = 3e-3 #mm
M_ABS = A_ABS*RHO_ABS*L_ABS
K_ABS = 300
A_ABS_TUBO = 10*1.60*0.01+0.154*9*0.01
A_ABS_ISO = Av-A_ABS_TUBO
RHO_TUBO = 2700
CP_TUBO = 900
N_TUBOS = 10
L_TUBO = N_TUBOS*1.6
M_TUBO = RHO_TUBO*L_TUBO*(3.1415/4)*(Do**2 - Di**2)
K_TUBO = 300
A_TUBO_F = 0.387 #pi*Di*(L*10 VOLTAS + R(156MM)*9)
A_TUBO_ISO = 0.484 #pi*Do*(L*10 VOLTAS + R(156MM)*9)
A_ISO = Av
RHO_ISO = 50
L_ISO = 40e-3
M_ISO = A_ISO*RHO_ISO*L_ISO
CP_ISO = 670
K_ISO = 0.0375
E_ISO = 0.75 #ESTIMATED
RHO_FLUIDO = 997
M_FLUIDO = L_TUBO*(3.1415/4)*Di**2*RHO_FLUIDO
CP_FLUIDO = 4186 #j/kgK
MI_FLUIDO = 0.890e-3 #Pa*s ou N/m2 * s
K_FLUIDO = 0.607
M_PONTO = 0.05 #kg/s ou 0.5 kg/m3
#DIMENSIONLESS
Pr = CP_FLUIDO*MI_FLUIDO/K_FLUIDO #water 25°C
Re = RHO_FLUIDO*Vf*Di/MI_FLUIDO
if (Re<=2300):
Nuf = 4.364
else:
Nuf = 0.023*(Re**0.8)*(Pr*0.4)*Re
#COEFFICIENTS
h_rad_vidro_ceu = SIGMA*E_VIDRO*(Tv**2 - T_CEU)*(Tv + T_CEU)
h_conv_vidro_amb = 2.8 + 3*VENTO
h_conv_tubo_fluido = 0.5*30#Nuf
h_cond_vidro_cel = 1/((L_VIDRO/K_VIDRO) + (L_CEL/K_CEL))
h_cond_cel_tedlar = 1/((L_TEDLAR/K_TEDLAR) + (L_CEL/K_CEL))
h_cond_tedlar_abs = 1/((L_TEDLAR/K_TEDLAR) + (L_ABS/K_ABS))
h_cond_abs_tubo = 1/((L_TUBO/K_TUBO) + (L_ABS/K_ABS))
h_cond_abs_iso = 1/((L_ISO/K_ISO) + (L_ABS/K_ABS))
h_cond_tubo_iso = 1/((L_ISO/K_ISO) + (L_TUBO/K_TUBO))
h_conv_iso_amb = h_conv_vidro_amb
h_rad_iso_ground = SIGMA*E_ISO*(Tiso**2 - T_GROUND**2)*(Tiso + T_GROUND)
#GROUPS
A1 = (1/(M_VIDRO*CP_VIDRO))*(ALPHA_VIDRO*Av)#*G(t)) G_ajustado = polyval(dt,rev_curve)
A2 = (1/(M_VIDRO*CP_VIDRO))*(Av*(h_rad_vidro_ceu + h_conv_vidro_amb + h_cond_vidro_cel))
A3 = (1/(M_VIDRO*CP_VIDRO))*Av*h_cond_vidro_cel
A4 = (1/(M_VIDRO*CP_VIDRO))*Av*(h_conv_vidro_amb + h_rad_vidro_ceu)
A5 = (1/(M_CEL*CP_CEL))*(Pac*A_CELL*TAU_VIDRO*ALPHA_CELL) #*G(t)
A6 = -1*A5*N_ELE #*G(t)
A7 = (1/(M_CEL*CP_CEL))*A_CELL*h_cond_vidro_cel
A8 = (1/(M_CEL*CP_CEL))*A_CELL*(h_cond_vidro_cel + h_cond_cel_tedlar)
A9 = (1/(M_CEL*CP_CEL))*A_CELL*h_cond_cel_tedlar
A10 = (1/(M_TEDLAR*CP_TEDLAR))*A_tedlar*(1 - Pac)*TAU_VIDRO*ALPHA_TEDLAR#G(t)
A11 = (1/(M_TEDLAR*CP_TEDLAR))*A_tedlar*(h_cond_cel_tedlar + h_cond_tedlar_abs)
A12 = (1/(M_TEDLAR*CP_TEDLAR))*A_tedlar*h_cond_cel_tedlar
A13 = (1/(M_TEDLAR*CP_TEDLAR))*A_tedlar*h_cond_tedlar_abs
A14 = (1/(M_ABS*CP_ABS))*A_ABS*h_cond_tedlar_abs
A15 = (1/(M_ABS*CP_ABS))*(A_ABS*h_cond_tedlar_abs + A_ABS_TUBO*h_cond_abs_tubo + A_ABS_ISO*h_cond_abs_iso)
A16 = (1/(M_ABS*CP_ABS))*A_ABS_TUBO*h_cond_abs_tubo
A17 = (1/(M_ABS*CP_ABS))*A_ABS_ISO*h_cond_abs_iso
A18 = (1/(M_TUBO*CP_TUBO))*A_ABS_TUBO*h_cond_abs_tubo
A19 = (1/(M_TUBO*CP_TUBO))*(A_ABS_TUBO*h_cond_abs_tubo + A_TUBO_F*h_conv_tubo_fluido + A_TUBO_ISO*h_cond_tubo_iso)
A20 = (1/(M_TUBO*CP_TUBO))*A_TUBO_F*h_conv_tubo_fluido*0.5
A21 = (1/(M_TUBO*CP_TUBO))*A_TUBO_ISO*h_cond_tubo_iso
A22 = (1/(M_FLUIDO*CP_FLUIDO))*A_TUBO_F*h_conv_tubo_fluido
A23 = (1/(M_FLUIDO*CP_FLUIDO))*(A_TUBO_F*h_conv_tubo_fluido*0.5 + M_PONTO*CP_FLUIDO)
A24 = (1/(M_FLUIDO*CP_FLUIDO))*(T_F_ENT*(M_PONTO*CP_FLUIDO - h_conv_tubo_fluido*A_TUBO_F*0.5))
A25 = (1/(M_ISO*CP_ISO))*A_ABS_ISO*h_cond_abs_iso
A26 = (1/(M_ISO*CP_ISO))*(A_ABS_ISO*h_cond_abs_iso + A_TUBO_ISO*h_cond_tubo_iso + A_ISO*h_conv_iso_amb + A_ISO*h_rad_iso_ground)
A27 = (1/(M_ISO*CP_ISO))*A_TUBO_ISO*h_cond_tubo_iso
A28 = (1/(M_ISO*CP_ISO))*A_ISO*(h_conv_iso_amb*Tamb + h_rad_iso_ground*T_GROUND)
#DEFINE MODEL EQUATIONS - ODES - (GLASS, PV CELL, TEDLAR, ABSORBER, TUBE, FLUID, INSULATION) # dT1dt = A1*G_ajustado - A2*x[0] + A3*x[1] + A4 # dT2dt = A5*G_ajustado - A6*G_ajustado + A7*x[0] - A8*x[1] + A9*x[2]# dT3dt = A10*G_ajustado - A11*x[2] + A12*x[1] +A13*x[3]
def SysEdo(x, k):#tv-x[0] tcel-x[1] ttedlar-x[2] tabs-x[3] ttubo-x[4] tiso-x[5] tfs-x[6]
dT1dt = A1*polyval(k,rev_curve) - A2*x[0] + A3*x[1] + A4
dT2dt = A5*polyval(k,rev_curve) - A6*polyval(k,rev_curve) + A7*x[0] - A8*x[1] + A9*x[2]
dT3dt = A10*polyval(k,rev_curve) - A11*x[2] + A12*x[1] +A13*x[3]
dT4dt = A14*x[2] - A15*x[3] + A16*x[4] + A17*x[5]
dT5dt = A18*x[3] - A19*x[4] + A20*x[6] + A20*T_F_ENT + A21*x[5]
dT6dt = A22*x[4] - A23*x[6] + A24
dT7dt = A25*x[3] - A26*x[5] + A27*x[4] + A28
Tdot = np.array([dT1dt, dT2dt, dT3dt, dT4dt, dT5dt, dT6dt, dT7dt])
return Tdot
#RungeKutta4
def RK4(f, x0, t0, tf, dt):
t = np.arange(t0, tf, dt) #time vector
nt = t.size #lenght of time vector
nx = x0.size #length of state variables?
x = np.zeros((nx,nt)) #initialize 2D vector
x[:,0] = x0 #initial conditions
#RK4 constants
for k in range(nt-1):
k1 = dt*f(t[k], x[:,k],k)
k2 = dt*f(t[k] + dt/2, x[:,k] + k1/2, k)
k3 = dt*f(t[k] + dt/2, x[:,k] + k2/2, k)
k4 = dt*f(t[k] + dt, x[:,k] + k3, k)
dx = (k1 + 2*k2 + 2*k2 + k4)/6
x[:,k+1] = x[:,k] + dx
return x,t
#Define problems
f = lambda t, x, k : SysEdo(x, k)
#initial state - t0 is initial time - tf is final time - dt is time step
x0 = np.array([30, 30, 30, 30, 30, 30, 30])
t0 = 0
tf = 1000
dt = 1
#EDO SOLVE
x, t = RK4(f, x0, t0, tf, dt)
plt.figure()
plt.plot(t, x[0], '-', label='Tvidro')
"""
plt.plot(t, x[1], '-', label='Tpv')
plt.plot(t, x[2], '-', label='Ttedlar')
plt.plot(t, x[3], '-', label='Tabs')
plt.plot(t, x[4], '-', label='Tiso')
plt.plot(t, x[5], '-', label='Ttubo')
plt.plot(t, x[6], '-', label='Tfsai')"""
plt.title('Gráfico')
plt.legend(['Tvidro', 'Tpv', 'Ttedlar', 'Tabs', 'Tiso', 'Ttubo', 'Tfsai'], shadow=False)
plt.xlabel('t (s)')
plt.ylabel('Temperatura (°C)')
plt.xlim(0,20)
plt.ylim(0,150)
plt.grid('on')
plt.show()
Thank you in advance, I am also open to completely start the implementation from scratch if there is a better way to do this with python or matlab.
You can just replace
x, t = RK4(f, x0, t0, tf, dt)
with
t = arange(t0,tf+0.5*dt,dt)
res = solve_ivp(f,(t0,tf),x0,t_eval=t,args=(k,), method="DOP853", atol=1e-6,rtol=1e-8)
x = res.y[0]
Adapt the last 3 parameters to your liking.

Scipy.fmin_bfgs passing to many arguments to function

I am trying to program a neural network and was trying to minimize the cost function using scipy.optimize_bfgs() and after attempting to use this I get the error that "TypeError: cost() takes 3 positional arguments but 4 were given". Where are these four arguments coming from and how can I rectify this?
The cost function is defined by:
def cost(param,X,y):
Theta1 = np.reshape(param[0:106950:1],(75,1426))
Theta2 = np.reshape(param[106950:112650:1],(75,76))
Theta3 = np.reshape(param[112650::1],(1,76))
m = len(X)
J = 0
a1 = X
z2 = np.dot(a1,np.transpose(Theta1))
a2 = sigmoid(z2)
a2 = np.concatenate((np.ones((len(a2),1)),a2),axis=1)
z3 = np.dot(a2,Theta2.T)
a3 = sigmoid(z3)
a3 = np.concatenate((np.ones((len(a3),1)),a3),axis=1)
z4 = np.dot(a3,Theta3.T)
a4 = sigmoid(z4)
h = a4
##Calculate cost
J = np.sum(np.sum(np.multiply(-y,np.log(h)) - np.multiply((1-y),np.log(1-h))))/(2*m)
theta1_reg[:,0] = 0
theta2_reg[:,0] = 0
theta3_reg[:,0] = 0
Reg = (lamb/(2*m))*(np.sum(np.sum(np.square(theta1_reg)))+np.sum(np.sum(np.sqaure(theta2_reg)))+np.sum(np.sum(np.square(theta3_reg))))
J = J + Reg
return J
The gradient is then calculated with:
def grad(param,X,y):
Theta1 = np.reshape(param[0:106950:1],(75,1426))
Theta2 = np.reshape(param[106950:112650:1],(75,76))
Theta3 = np.reshape(param[112650::1],(1,76))
Theta1_grad = np.zeros(Theta1.shape)
Theta2_grad = np.zeros(Theta2.shape)
Theta3_grad = np.zeros(Theta3.shape)
m = len(X)
##Forward propogation
a1 = X
z2 = np.dot(a1,np.transpose(Theta1))
a2 = sigmoid(z2)
a2 = np.concatenate((np.ones((len(a2),1)),a2),axis=1)
z3 = np.dot(a2,Theta2.T)
a3 = sigmoid(z3)
a3 = np.concatenate((np.ones((len(a3),1)),a3),axis=1)
z4 = np.dot(a3,Theta3.T)
a4 = sigmoid(z4)
h = a4
##Backward propogation
d4 = a4 - y
d3 = np.multiply(np.dot(d4,Theta3[:,1:]),sigmoidGradient(z3))
d2 = np.multiply(np.dot(d3,Theta2[:,1:]),sigmoidGradient(z2)) ## or sigmoid(z2) .* ( 1 - sigmoid(z2))
D1 = np.dot(d2.T,a1)
D2 = np.dot(d3.T,a2)
D3 = np.dot(d4.T,a3)
##Unregularized gradients
Theta1_grad = (1/m)*D1
Theta2_grad = (1/m)*D2
Theta3_grad = (1/m)*D3
##Regularize gradients
theta1_reg = Theta1
theta2_reg = Theta2
theta3_reg = Theta3
theta1_reg[:,0] = 0
theta2_reg[:,0] = 0
theta3_reg[:,0] = 0
theta1_reg = (lamb/m)*theta1_reg
theta2_reg = (lamb/m)*theta2_reg
theta3_reg = (lamb/m)*theta3_reg
Theta1_grad = Theta1_grad + theta1_reg
Theta2_grad = Theta2_grad + theta2_reg
Theta3_grad = Theta3_grad + theta3_reg
##Concatenate gradients
grad = np.concatenate((Theta1_grad,Theta2_grad,Theta3_grad),axis=None)
return grad
Other functions defined are
def sigmoid(z):
sig = 1 / (1 + np.exp(z))
return sig
def randInitializeWeights(l_in, l_out):
epsilon = 0.12;
W = np.random.rand(l_out, 1+l_in)*2*epsilon - epsilon;
return W
def sigmoidGradient(z):
g = np.multiply(sigmoid(z),(1-sigmoid(z)))
return g
As an example:
import numpy as np
import scipy.optimize
X = np.random.rand(479,1426)
y1 = np.zeros((frames,1))
y2 = np.ones((framesp,1))
y = np.concatenate((y1,y2),axis=0)
init_param = np.random.rand(112726,)
lamb = 0.5
scipy.optimize.fmin_bfgs(cost,fprime=grad,x0=init_param,args=(param,X,y))
Then the error appears.
Thanks for any help
The arguments passed into the cost functions are the parameters, followed by the extra arguments. The parameters are chosen by the minimization function, the extra arguments are passed through.
When calling fmin_bfgs, only pass the extra arguments as args, not the actual parameters to optimize:
scipy.optimize.fmin_bfgs(..., args=(X,y))

Categories