How to solve this linear programming problem?

118 Views Asked by At

Consider a set of city districts . There is a candidate for building a medical emergency service station in every city district. The cost of building an ambulance station is given by the parameter and the total budget for building stations throughout the city is 50 million. Furthermore, if a station is built in city district 2, it must not be station built in city district 6. Determine in which city districts to build ambulance stations so that the maximum travel time is minimized. What is the optimal maximum travel time? The cost of building stations in the city district ∈ , are: [32,20,25,30,40,29] The city districts and the driving distances between them are interpreted in the following graph:

 ([[ 0,  4, 12, 27, 25, 58],
   [ 4,  0, 24, 16, 29, 38],
   [12, 24,  0, 31, 14, 30],
   [27, 16, 31,  0, 21,  8],
   [25, 29, 14, 21,  0, 11],
   [58, 38, 30,  8, 11,  0]])

The right answer is to build stations in districts 2 and 4, and optimal travel time is 24.

I tried to solve it, and here is my code, but the answer is not right. It has to be completet with PULP

`from pulp import *
import numpy as np

# the cost of building of the stations
cost1 = [32,20,25,30,40,29]

# the city districts and the driving distances between them
d = np.array([[0,4,12,27,25,58],[4,0,24,16,29,38],[12,24,0,31,14,30],[27,16,31,0,21,8],          [25,29,14,21,0,11],[58,38,30,8,11,0]])

# set of city districts
cities1 = [1, 2, 3, 4, 5, 6]
cities2 = [1, 2, 3, 4, 5, 6]

# costs
n = dict(zip(cities1,cost1))

# dict of every distance between the cities
a1 = dict(zip(cities1, zip(*d)))

a = {key: dict(enumerate(value, 1)) for key, value in a1.items()}


# model
model = LpProblem("Set_covering", LpMinimize)

# shortcut introduction
shortcut = [(i,j) for i in cities1 for j in cities2]

# declaration of variables
x = LpVariable.dicts("x",(cities1),0, cat = 'Binary')
maximum = LpVariable("Maximum", 0, cat = 'Continuous')

# purpose function
model += maximum

# restrictive conditions
for (i,j) in shortcut:
    model += maximum >= x[i]*a[i][j]
for j in cities1:
    model += lpSum(x[i]*a[i][j] for i in cities2) >= 1

model += lpSum(n[i]*x[i] for i in cities1) <=50
model += lpSum(x[2]+x[6]) <= 1


# List of results
model.solve()
print("Status:", LpStatus[model.status])

for v in model.variables():
    if v.varValue > 0:
        print(v.name, "=", v.varValue)
    
print("The total travel time to all places from both stations is: ", value(model.objective))`
1

There are 1 best solutions below

2
On

You have created a slightly different model from the problem described. You are getting the maximum of the travel times from amongst the locations that could service another location. When you select (correctly) to build at locations 2 & 4, your "maximization" constraint is picking up the 38 because that is the maximum of all of the stations that could service location 6. But you say, "I wouldn't service station 6 from station 2, I'd do it from station 4 and take the 8 distance..." And similarly for others.

But that information is not in your model! I'd suggest a modest reformulation... you are almost there and you have many of the concepts covered. The info you want to capture is that "I want to service location j from station i." So introduce that variable and constrain it properly. Something like:

service[i, j] ∈ {0, 1}

and some necessary constraints on that and then use your max constraint across that variable.

Clearly, you'll need to link the service variable to having a station built at i (a constraint between the two, for each i). You could either make individual constraints for each i, j tied to x[i] for that or use a big-M summation if you have learned that concept already.

And you will need to ensure that every j is serviced (sounds like a summation constraint for each j) which will replace your other constraint forcing the distance to be greater than 1.

Comment back if you are stuck. Good luck w/ the assignment!