Reputation: 11
I am trying to use SCIP optimization
to find the optimal open order of facilities
given the distance away from residential blocks and weighted for the number
of residents in the area.
I have set up the distance dictionary so that the distances from the facilities to
each residential area should produce an output of [2, 1, 0]
order for the facilities.
However, the output I receive is [0, 1, 2]
.
Also, if I change alpha to a positive value it has no effect.
import pandas as pd
from pyscipopt import Model, quicksum, multidict, exp
num_fac_to_open = 3
order_to_open = []
opened_fac = []
closed_fac = [0, 1, 2]
# Facility id
S = [0, 1, 2]
# Residential block id
R = [10, 11, 12]
distance_dict = {(0, 10): 0.8, (1, 10): 150.6, (2, 10): 100007.8, (0, 11): 1.0, (1, 11): 2012.1, (2, 11): 10009.2, (0, 12): 3.2, (1, 12): 1798.3, (2, 12): 10006.3}
population_dict = {10:54, 11:46, 12:22}
alpha = -1
# n is the desired number of facilities to open
n = len(opened_fac) + num_fac_to_open
# create a model
model = Model()
z, y= {}, {}
for s in S:
# x_i is binary, 1 if service facility i is opened, 0 otherwise
z[s] = model.addVar(vtype="B")
for r in R:
# y_i,j is binary, 1 if service facility i is assigned to residential area j, 0 otherwise
y[s, r] = model.addVar(vtype="B")
for r in R:
model.addCons(quicksum(y[s, r] for s in S) == 1)
#
for s in S:
for r in R:
model.addCons(y[s, r]-z[s] <= 0)
#
model.addCons(quicksum(z[s] for s in S) == n)
#
for facility in opened_fac:
model.addCons(z[facility] == 1)
x, w = {}, {}
for r in R:
x[r] = model.addVar(vtype="C", name="x(%s)"%(r))
w[r] = model.addVar(vtype="C", name="w(%s)"%(r))
for r in R:
x[r] = quicksum(distance_dict[s, r]*y[s, r] for s in S)
exp_power = alpha*population_dict[r]*x[r]
model.addCons((w[r] - exp(exp_power)) >= 0)
#
#print(quicksum(w[r] for r in R))
model.setObjective(quicksum(w[r] for r in R), 'minimize')
model.optimize()
new_facilities = []
for s in S:
if ((model.getVal(z[s]) == 1) and (not s in opened_fac)):
new_facilities.append(s)
if len(new_facilities) == num_fac_to_open:
break
print(new_facilities)
I am trying to optimize the following problem:
The aim is to minimize sum_{r=1}^N W_r
Where W_r = exp(population_dict[r]*sum_{s∈S} d_r,s * y_r,s)
∀r ∈ R
Any help on this issue would be great!
Upvotes: 1
Views: 71
Reputation: 31
The program you have posted here only finds which facilities to open and how to assign the facilities to residential blocks. Nothing in the code would lead to the elements of S changing their order, which is why when you loop over S in the end, you get the facilities in their original order.
First you will need to define mathematically how the facilities are ordered. The implementation will depend on this definition. A simple option could be to obtain some scores reflecting the importance of facilities and to sort the facilities according to these scores.
Upvotes: 1