0
votes

basically i'm trying to make each destination have only one origin all destinations must have only one source and not all origins necessarily have to be used I hope someone could help me, I know that this is not the propper way but that what I got

from pulp import*
import pandas as pd 
origin = ["a","b","c","d","e","f","g","h"]
destination = ["1","2","3","4","5","6","7","8","9","10"]


offer = {"a":3,"b":3,"c":3,"d":3,"e":3,"f":4,"g":3,"h":3}
demand = {"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":1,"8":1,"9":1,"10":1}
cost_to_send = { 
"a":{"1":1,"2":1,"3":1},
"b":{"2":1,"3":1,"9":1},
"c":{"5":1,"6":1,"7":1},
"d":{"7":1,"9":1,"10":1},
"e":{"3":1,"6":1,"8":1},
"f":{"1":1,"4":1,"7":1,"9":1},
"g":{"4":1,"5":1,"9":1},
"h":{"1":1,"4":1,"8":1}
}
prob = LpProblem("Exercise", LpMinimize)

Routes = [(i,j) for i in origin for j in destination]

quantity = LpVariable.dicts("quantity de envio",(origin,destination),0)

prob += lpSum(quantity[i][j]*cost_to_send[i][j] for (i,j) in Routes)

for j in destination:
    prob += lpSum(quantity[i][j] for i in origin) == demand[j]

for i in origin:
    prob += lpSum(quantity[i][j] for j in destination) == 1

prob.solve()
print("Status: ", LpStatus[prob.status])

for v in prob.variables():
    if v.varValue > 0:
        print(v.name, "=", v.varValue)

print("Answer ", value(prob.objective))

1

1 Answers

0
votes

I think you're quite close to what you want but you have some problems. First of all you define your Routes as all possible routes, whereas you only have cost_to_send defined for some routes.

Assuming the routes for which costs are defined are the feasible routes you would be better defining Routes as:

Routes = [(i, j) for i in origin for j in destination if j in cost_to_send[i]]

The other problem I can see is with your second set of constraints:

for i in origin:
    prob += lpSum(quantity[i][j] for j in destination) == 1

This is saying that for each origin, the total flow to all destinations must be 1. But in your problem statement you say:

all destinations must have only one source and not all origins necessarily have to be used

But with this constraint you are forcing every origin to be used. Removing this constraint your problem solves:

from pulp import *
import pandas as pd 
origin = ["a","b","c","d","e","f","g","h"]
destination = ["1","2","3","4","5","6","7","8","9","10"]


offer = {"a":3,"b":3,"c":3,"d":3,"e":3,"f":4,"g":3,"h":3}
demand = {"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":1,"8":1,"9":1,"10":1}
cost_to_send = { 
"a":{"1":1,"2":1,"3":1},
"b":{"2":1,"3":1,"9":1},
"c":{"5":1,"6":1,"7":1},
"d":{"7":1,"9":1,"10":1},
"e":{"3":1,"6":1,"8":1},
"f":{"1":1,"4":1,"7":1,"9":1},
"g":{"4":1,"5":1,"9":1},
"h":{"1":1,"4":1,"8":1}
}
prob = LpProblem("Exercise", LpMinimize)

# Routes = [(i,j) for i in origin for j in destination]
Routes = [(i, j) for i in origin for j in destination if j in cost_to_send[i]]

quantity = LpVariable.dicts("quantity de envio",Routes,0)

prob += lpSum(quantity[(i,j)]*cost_to_send[i][j] for (i,j) in Routes)

for j in destination:
    prob += lpSum(quantity[(i,j)] for i in origin if (i,j) in Routes) == demand[j]

#for i in origin:
#    prob += lpSum(quantity[i][j] for j in destination) == 1

prob.solve()
print("Status: ", LpStatus[prob.status])

for v in prob.variables():
    if v.varValue > 0:
        print(v.name, "=", v.varValue)

print("Answer ", value(prob.objective))


Returns:

Status:  Optimal
quantity_de_envio_('a',_'1') = 1.0
quantity_de_envio_('a',_'2') = 1.0
quantity_de_envio_('a',_'3') = 1.0
quantity_de_envio_('b',_'9') = 1.0
quantity_de_envio_('c',_'5') = 1.0
quantity_de_envio_('c',_'6') = 1.0
quantity_de_envio_('d',_'10') = 1.0
quantity_de_envio_('f',_'4') = 1.0
quantity_de_envio_('f',_'7') = 1.0
quantity_de_envio_('h',_'8') = 1.0
Answer  10.0

Note that if you want to have demands which are more than 1 for a given destination, but want to force the destination to only receive input from a single origin - then you will need to add binary variables for each 'Route' to control whether each route is open. You would then set a constraint that the quantity variables can only be non zero if these binary variables are true, and you can then limit the sum of these binary variables into each destination to be == 1.