Reputation: 551
I shared below a simplified version of the problem I'm trying to solve. There must be something wrong in my formulation, perhaps regarding the decision variables. All of the flow is sent to Destination1 by the model, but I am attempting to build a model that would evenly distribute the flow. When I force Destination2 to receive flow with an additional constraint, the objective value improves, so I'm not sure why such a solution is not found instead of the less optimal.
I appreciate your thoughts and am happy to answer any questions about this model.
Warehouses = ["A","B","C","D"]
origin_supply = {"A": 53, "B": 62, "C": 45, "D": 65}
Destinations = ['Destination1','Destination2']
Routes = [(o,d) for o in origin_supply for d in destinations]
model = LpProblem("Testing-absolute-value-objective", LpMinimize)
supply = [53,62,45,65]
destination_mean = sum(supply) / len(destinations)
# decision variables
route_vars = LpVariable.dicts("Route",(Warehouses,Destinations),cat = "Integer", lowBound = 0)
sum_for_diff = LpVariable.dicts("sum",(Destinations),cat = "Continuous")
sum_for_diff_abs = LpVariable.dicts("sum_abs",(Destinations),cat = "Continuous", lowBound = 0)
# objective function is to minimize the absolute value of the difference supplied to the two destinations
obj_func = lpSum(sum_for_diff_abs)
# constraints
# absolute value constraints for the difference
for d in destinations:
model += sum_for_diff_abs[d] >= sum_for_diff[d]
model += sum_for_diff_abs[d] >= -sum_for_diff[d]
# The supply constraints (in this case all supply must be sent)
for w in Warehouses:
model += lpSum([route_vars[w][d] for d in Destinations]) == origin_supply[w]
# calculate the difference from the average amount sent to each destination
# the reasoning is that in the full model there will be many destinations, so this logic could scale
for d in Destinations:
model += sum_for_diff[d] == lpSum( route_vars[w][d] for w in Warehouses) - destination_mean
model.solve()
print(LpStatus[model.status])
print(pulp.value(obj_func))
for v in model.variables():
print (v.name + " = " + str(v.varValue))
Upvotes: 0
Views: 186
Reputation: 11929
You are not setting the objective function.
This line
obj_func = lpSum(sum_for_diff_abs)
should be
model+= lpSum(sum_for_diff_abs)
Upvotes: 1