Adding constraints to PULP. Transportation problem

55 Views Asked by At

I am solving transportation problem using PULP.

I have a list of suppliers (supply) and list of customers (demand). The supply is always more than demand and in some cases not every supplier is chosen by PULP. However sometimes i need specific supplier to be chosen regardless of whether it is the optimal option or not. I understand that it should be added as a constraint, but i do not know how to modify my script.

prob = LpProblem("transportationproblem", LpMaximize)

routes = [(s,c) for s in suppliers for c in customers]

vars = LpVariable.dicts("Route", (suppliers, customers), 0, None, LpInteger)

prob += (
    lpSum([vars[s][c] * costs[s][c] for (s, c) in routes]),
    "sum_of_transp_cost"
)

for s in suppliers:
    prob += (
        lpSum([vars[s][c] for c in customers]) <= supply[s],
        f"sum_of_products_from_suppliers_{s}",
    )

for c in customers:
    prob += (
        lpSum([vars[s][c] for s in suppliers]) == demand[c],
        f"sum_of_products_to_customers{c}"
    )

I tried to add this constraint, but solver is not working correctly


for s in suppliers:
    if s == "specific supplier": 
        prob += (
            lpSum([vars[s][c] for c in customers]) == supply[s],
            f"sum_of_products_from_suppliers_{s}",
    )
1

There are 1 best solutions below

0
Reinderien On

Your problem is probably that you're double-applying a constraint to the supplier row that you want to be "specific". This works:

import pulp
from numpy.random import default_rng

rand = default_rng(seed=0)

prob = pulp.LpProblem(name='transportation_problem', sense=pulp.LpMaximize)
suppliers = range(9)
customers = range(7)
costs = rand.random((len(suppliers), len(customers)))
supply = rand.integers(size=len(suppliers), low=10, high=20)
demand = rand.integers(size=len(customers), low=0, high=10)

routes = pulp.LpVariable.matrix(
    name='Route_s%d_c%d',
    indices=(suppliers, customers),
    cat=pulp.LpInteger, lowBound=0,
)

sum_of_transp_cost = pulp.lpDot(routes, costs)
prob.setObjective(sum_of_transp_cost)

specific_supplier_index = 3
specific_supplier_routes = 4

for supplier, supply_avail, row in zip(suppliers, supply, routes):
    if supplier == specific_supplier_index:
        prob.addConstraint(
            constraint=pulp.lpSum(row) == specific_supplier_routes,
            name=f'products_from_specific_supplier_{supplier}',
        )
    else:
        prob.addConstraint(
            constraint=pulp.lpSum(row) <= supply_avail,
            name=f'products_from_supplier_{supplier}',
        )

for customer, cust_demand in zip(customers, demand):
    prob.addConstraint(
        constraint=pulp.lpSum(
            routes[supplier][customer] for supplier in suppliers
        ) == cust_demand,
        name=f'products_to_customer_{customer}',
    )

print(prob)
prob.solve()
assert prob.status == pulp.LpStatusOptimal

for supplier, row in zip(suppliers, routes):
    print(', '.join(f'{pulp.value(route):.0f}' for route in row))
0, 0, 0, 0, 1, 5, 2
0, 0, 3, 0, 0, 0, 0
0, 0, 0, 0, 0, 0, 0
0, 0, 0, 0, 0, 0, 4
0, 0, 0, 0, 0, 0, 0
0, 0, 0, 6, 0, 0, 0
0, 0, 0, 0, 0, 0, 0
9, 0, 0, 0, 0, 0, 0
0, 0, 0, 0, 0, 0, 0