jdw
jdw

Reputation: 11

python facility open order SCIP optimization

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

Answers (1)

Ksenia
Ksenia

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

Related Questions