Python Pulp - Multiple ADP contraints for snake draft - python

I am new to python/pulp and I am trying to replicate an excel solver snake draft problem in python. I have found a couple of python optimizer solutions for dfs. My model is similar with the exception of instead of a single constraint for salary, I have multiple constraints based on ADP. For instance, if I am in a 10 team league with the 7th pick and I want to optimize my first 8 picks. My 1st ADP constraint would be 8 of my picks would have an ADP higher than 6. 2nd constraint would be at least 7 of my picks would have an ADP higher than 13. 3rd - at least 6 picks have an ADP higher than 26 and so forth for 8 rounds. The suggestion that was made was to make a binary helper column which I have done for each round. This approach seems cumbersome and is not useful if I want to create a loop for each draft position's optimal lineup. Is there a better way to write the code for the Rnd1 thru the Rnd8 sections of the code. Thanks
Fantasy Football Data
availables = players.groupby(["Position", "Rk", "PLAYER", "TEAM", "EPPG", "Rnd1", "Rnd2",
"Rnd3", "Rnd4", "Rnd5", "Rnd6", "Rnd7", "Rnd8"]).agg('count')
availables = availables.reset_index()
ADPs = {}
points = {}
R1s = {}
R2s = {}
R3s = {}
R4s = {}
R5s = {}
R6s = {}
R7s = {}
R8s = {}
lineups_dict = {}
for pos in availables.Position.unique():
available_pos = availables[availables.Position == pos]
point = list(available_pos[['PLAYER', 'EPPG']].set_index("PLAYER").to_dict().values())[0]
R1 = list(available_pos[['PLAYER', 'Rnd1']].set_index("PLAYER").to_dict().values())[0]
R2 = list(available_pos[['PLAYER', 'Rnd2']].set_index("PLAYER").to_dict().values())[0]
R3 = list(available_pos[['PLAYER', 'Rnd3']].set_index("PLAYER").to_dict().values())[0]
R4 = list(available_pos[['PLAYER', 'Rnd4']].set_index("PLAYER").to_dict().values())[0]
R5 = list(available_pos[['PLAYER', 'Rnd5']].set_index("PLAYER").to_dict().values())[0]
R6 = list(available_pos[['PLAYER', 'Rnd6']].set_index("PLAYER").to_dict().values())[0]
R7 = list(available_pos[['PLAYER', 'Rnd7']].set_index("PLAYER").to_dict().values())[0]
R8 = list(available_pos[['PLAYER', 'Rnd8']].set_index("PLAYER").to_dict().values())[0]
points[pos] = point
R1s[pos] = R1
R2s[pos] = R2
R3s[pos] = R3
R4s[pos] = R4
R5s[pos] = R5
R6s[pos] = R6
R7s[pos] = R7
R8s[pos] = R8
pos_num_available = {
"QB": 1,
"RB": 3,
"TE": 1,
"WR": 3,
"DEF": 0,
"K": 0
}
for lineup in range(1,9):
_vars = {k: LpVariable.dict(k, v, cat='Binary') for k, v in points.items()}
prob = LpProblem("Fantasy", LpMaximize)
rewards = []
Rnd_1 = []
Rnd_2 = []
Rnd_3 = []
Rnd_4 = []
Rnd_5 = []
Rnd_6 = []
Rnd_7 = []
Rnd_8 = []
for k, v in _vars.items():
rewards += lpSum([points[k][i] * _vars[k][i] for i in v])
Rnd_1 += lpSum([R1s[k][i] * _vars[k][i] for i in v])
Rnd_2 += lpSum([R2s[k][i] * _vars[k][i] for i in v])
Rnd_3 += lpSum([R3s[k][i] * _vars[k][i] for i in v])
Rnd_4 += lpSum([R4s[k][i] * _vars[k][i] for i in v])
Rnd_5 += lpSum([R5s[k][i] * _vars[k][i] for i in v])
Rnd_6 += lpSum([R6s[k][i] * _vars[k][i] for i in v])
Rnd_7 += lpSum([R7s[k][i] * _vars[k][i] for i in v])
Rnd_8 += lpSum([R8s[k][i] * _vars[k][i] for i in v])
prob += lpSum([_vars[k][i] for i in v]) == pos_num_available[k]
prob += lpSum(rewards)
prob += Rnd_1 >= 8
prob += Rnd_2 >= 7
prob += Rnd_3 >= 6
prob += Rnd_4 >= 5
prob += Rnd_5 >= 4
prob += Rnd_6 >= 3
prob += Rnd_7 >= 2
prob += Rnd_8 >= 1
if not lineup == 1:
prob += (lpSum(rewards) <= total_score-0.01)
prob.solve()
score= str(prob.objective)
constraints = [str(const) for const in prob.constraints.values()]
lineupList = []
for v in prob.variables():
score = score.replace(v.name, str(v.varValue))
if v.varValue !=0:
lineupList.append(v.name)
ADP constraint examples

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

Can we solve Fractional Knapsack Problem by DP?

I know the Greedy approach is the best solution, but I'm so curious.
here is some of my code ...
def fractional_knapsack_dp2():
global resValue
# 각 size W를 넘지 않는 상태에서, i개의 아이템을 담은 상태에서 최대 profit을 담는 배열
P = [ [0 for x in range(W+1)] for x in range(n+1)] # [n+1][W+1] 0으로 초기화
for i in range(n+1):
currWeight = 0
for w in range(W+1):
if i==0 or w==0: # 0행 또는 0열은 skip
P[i][w] = 0;
elif weights[i-1] <= w:
currWeight = weights[i-1]
P[i][w] = max( values[i-1] + P[i-1][w - weights[i-1]], P[i-1][w] )
else:
# weight 1 단위로 설정 ... dksl d어케함 ;;
frac = 1 / weights[i-1]
if ( frac*values[i-1] + P[i-1][w - 1] > P[i-1][w] ) :
P[i][w] = P[i-1][w-1]
for k in range(w - currWeight) :
currWeight += 1
P[i][w] += frac*values[i-1]
else :
P[i][w] = P[i-1][w]
resValue = P[n][W]
I don't know how can I solve the problem.
Should I make another recurrence relation or array? 😢
I didn't learn about Dynamic Programming yet.

GEKKO - How to fix Python Gekko Max Equation error - number of elements

I have developed a script using Gekko optimisation functions. The script below runs for a number of elements. I tested the optimisation algorithm for 20 and 47 cells (shapefile dataset) and the script achieves a solution. However, when I test for a bigger dataset, with 160 elements, for example, the following error message is shown:
“APM model error: string > 15000 characters
Consider breaking up the line into multiple equations”
I read some suggestions to fix this problem. I tried using m.sum, but the problem persists.
Please, could you help me fix this problem?
Please, find below the we transfer link to download the datasets with 47 cells and with 160 cells.
https://wetransfer.com/downloads/64cc631237adacc926c67f56124b327a20210928212223/d8a2d7
Thank you
Alexandre.
import geopandas as gpd
import time
import csv
from gekko import GEKKO
import numpy as np
import math
import pandas as pd
m = GEKKO()
A = -0.00000536
B = -0.0000291
E = 0.4040771
r = 0.085
input_path = 'D:/Alexandre/shapes/Threats/Prototype/BHO50k/Velhas_BHO50k1summ4_47cells.shp'
output_folder = 'D:/Alexandre/shapes/Threats/Prototype/Small_area/resultados'
input_layer = gpd.read_file(input_path)
input_layer = input_layer[
['cocursodag', 'cobacia', 'nuareacont', 'nudistbact', 'D0c', 'Ki0', 'Kj0', 'nuareamont', 'deltai', 'It',
'cost_op_BR', 'Ii_ub', 'Itj', 'cj', 'deltaj2']]
input_layer = input_layer.astype({'cobacia': 'string', 'cocursodag': 'string'})
count_input_feat = input_layer.shape[0]
row=count_input_feat
col=10
input_cobacia = {}
ubi = {}
numareacont = {}
Ki0 = {}
Kj0 = {}
X = {}
deltai2 = {}
ai = {}
aj = {}
D0 = {}
Itj = {}
It = {}
deltaj = {}
for row1 in input_layer.iterrows():
i = row1[0]
input_cobacia[i] = row1[1]['cobacia']
Ki0[i] = row1[1]['Ki0']+0.001
Kj0[i] = row1[1]['Kj0']
X[i] = row1[1]['nuareamont']
deltai2[i] = row1[1]['deltai']
ai[i] = 5423304*(pow(X[i],-0.1406852))
aj[i] = row1[1]['cj']*100 + row1[1]['cost_op_BR']*100
ubi[i] = row1[1]['Ii_ub']
numareacont[i] = row1[1]['nuareacont']
D0[i] = row1[1]['D0c']
It[i] = row1[1]['It']
Itj[i] = row1[1]['Itj']
if Itj[i]<1:
deltaj[i] = row1[1]['deltaj2'] * 0.0001
elif Itj[i]<2:
deltaj[i] = row1[1]['deltaj2'] * 0.0001
else:
deltaj[i] = row1[1]['deltaj2'] * 0.0001
Ii = m.Array(m.Var, (row, col))
Ij = m.Array(m.Var, (row, col))
for i in range(row):
for j in range(col):
if It[i] == 0:
Ii[i, j].value = 0
Ii[i, j].lower = 0
Ii[i, j].upper = 5
Ij[i,j].value = 0
Ij[i,j].lower = 0
Ij[i,j].upper = numareacont[i]*0.05*Itj[i]/3.704545
elif It[i] <= 2:
Ii[i, j].value = 0
Ii[i, j].lower = 0
Ii[i, j].upper = 10
Ij[i, j].value = 0
Ij[i, j].lower = 0
Ij[i, j].upper = numareacont[i]*0.05*Itj[i]/3.704545
elif It[i] <= 2.5:
Ii[i, j].value = 0
Ii[i, j].lower = 0
Ii[i, j].upper = 15
Ij[i, j].value = 0
Ij[i, j].lower = 0
Ij[i, j].upper = numareacont[i]*0.05*Itj[i]/3.704545
elif It[i] <= 3:
Ii[i, j].value = 0
Ii[i, j].lower = 0
Ii[i, j].upper = 15
Ij[i, j].value = 0
Ij[i, j].lower = 0
Ij[i, j].upper = numareacont[i]*0.05*Itj[i]/3.704545
else:
Ii[i,j].value = 0
Ii[i,j].lower = 0
Ii[i,j].upper = 20
Ij[i,j].value = 0
Ij[i,j].lower = 0
Ij[i,j].upper = numareacont[i]*0.05*Itj[i]/3.704545
Ki = m.Array(m.Var, (row, col))
Kj = m.Array(m.Var, (row, col))
indicator = m.Array(m.Var, (row, col))
p = 2
numerator = m.Array(m.Var, (row, col))
denominator = m.Array(m.Var, (row, col))
for row2 in input_layer.iterrows():
input_cobacia2 = row2[1]['cobacia']
input_cocursodag = row2[1]['cocursodag']
input_distance = row2[1]['nudistbact']
numerator = 0
denominator = 0
exp = f"cobacia > '{input_cobacia2}' and cocursodag.str.startswith('{input_cocursodag}')"
for j in range(col):
for target_feat in input_layer.query(exp).iterrows():
i=target_feat[0]
target_green_area = Ij[i,j]
target_distance = target_feat[1]['nudistbact']
distance = float(target_distance) - float(input_distance)
idw = 1 / (distance + 1) ** p
numerator += target_green_area * idw
denominator += idw
i=row2[0]
sum = Ij[i,j]
if denominator:
indicator[i,j] = numerator / denominator + sum
else:
indicator[i,j] = sum
D0F = m.Array(m.Var, (row, col))
for i in range(row):
def constraintD0(x):
return x - 0.2
for j in range(col):
if j == 0:
m.fix(Ki[i,j],val = Ki0[i])
Ki[i,j].lower = 0
Ki[i,j].upper = 500000
m.fix(Kj[i,j], val = Kj0[i])
Kj[i,j].lower = 0
Kj[i,j].upper = 100000
m.Equation(D0F[i, j] == A * Ki[i, j] + B * Kj[i, j] + E)
D0[i] = D0F[i, j]
else:
D0F[i,j].lower = 0
D0F[i, j].upper = 1
Ki[i,j].lower = 0
Ki[i,j].upper = 500000
Kj[i, j].lower = 0
Kj[i, j].upper = 100000
m.Equation(Ki[i,j] - Ki[i,j-1] == Ii[i,j] - deltai2[i] * Ki[i,j-1])
m.Equation(Kj[i,j] - Kj[i,j-1] == Ij[i,j] + deltaj[i] * Kj[i,j-1]+indicator[i,j])
m.Equation(D0F[i,j] == A*Ki[i,j] + B*Kj[i,j] + E)
m.Equation(D0F[i,j]<=D0[i])
dep = 1 / (1+r)
z1 = m.sum([m.sum([pow(dep, j)*(ai[i]*Ii[i,j]+aj[i]*Ij[i,j]) for i in range(row)]) for j in range(col)])
# Objective
m.Obj(z1)
m.options.IMODE = 3
m.options.SOLVER = 3
m.options.DIAGLEVEL = 1
m.options.REDUCE=3
try:
m.solve() # solve
# Outputs
output_Ki = pd.DataFrame(columns=['cobacia'] + list(range(col)))
output_Kj = pd.DataFrame(columns=['cobacia'] + list(range(col)))
output_Ii = pd.DataFrame(columns=['cobacia'] + list(range(col)))
output_Ij = pd.DataFrame(columns=['cobacia'] + list(range(col)))
output_D0 = pd.DataFrame(columns=['cobacia'] + list(range(col)))
output_ai = pd.DataFrame(columns=['cobacia'] + list(range(col)))
output_aj = pd.DataFrame(columns=['cobacia'] + list(range(col)))
for i in range(row):
for j in range(col):
print(Ki)
output_Ii.loc[i, 'cobacia'] = input_cobacia[i]
output_Ii.loc[i, j] = Ii[i,j].value[0]
output_Ij.loc[i, 'cobacia'] = input_cobacia[i]
output_Ij.loc[i, j] = Ij[i,j].value[0]
output_Ki.loc[i, 'cobacia'] = input_cobacia[i]
output_Ki.loc[i, j] = Ki[i,j].value[0]
output_Kj.loc[i, 'cobacia'] = input_cobacia[i]
output_Kj.loc[i, j] = Kj[i,j].value[0]
output_D0.loc[i, 'cobacia'] = input_cobacia[i]
output_D0.loc[i, j] = D0F[i, j].value[0]
output_ai.loc[i, 'cobacia'] = input_cobacia[i]
output_ai.loc[i, j] = ai[i]
output_aj.loc[i, 'cobacia'] = input_cobacia[i]
output_aj.loc[i, j] = aj[i]
df_outputIi = pd.DataFrame(output_Ii)
df_outputIj = pd.DataFrame(output_Ij)
df_outputKi = pd.DataFrame(output_Ki)
df_outputKj = pd.DataFrame(output_Kj)
df_outputD0 = pd.DataFrame(output_D0)
df_outputai = pd.DataFrame(output_ai)
df_outputaj = pd.DataFrame(output_aj)
with pd.ExcelWriter('output.xlsx') as writer:
df_outputIi.to_excel(writer, sheet_name="resultado Ii")
df_outputIj.to_excel(writer, sheet_name="resultado Ij")
df_outputKi.to_excel(writer, sheet_name="resultado Ki")
df_outputKj.to_excel(writer, sheet_name="resultado Kj")
df_outputD0.to_excel(writer, sheet_name="resultado D0")
df_outputai.to_excel(writer, sheet_name="ai")
df_outputaj.to_excel(writer, sheet_name="aj")
except:
print('Not successful')
from gekko.apm import get_file
print(m._server)
print(m._model_name)
f = get_file(m._server,m._model_name,'infeasibilities.txt')
f = f.decode().replace('\r','')
with open('infeasibilities.txt', 'w') as fl:
fl.write(str(f))
for i in range(row):
for j in range(col):
print(Ki[i,j].value)
print(Kj[i,j].value)
print(D0F[i,j].value)```
Look at the APMonitor model file gk0_model.apm in m.path by opening the run folder with m.open_folder(). Start with a smaller problem size and observe the equation size as the problem scales up. This limitation (<15,000 characters per equation) is built-in to encourage more efficient model expression and solution. An intermediate with m.Intermediate() can be used to more effectively express the model. Additional information on Intermediates is available in the documentation.

Linear modeling solver with set restrictions in pulp 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

Categories