I'm trying to solve a problem similar to this simpler example.
Target | Constraint |
---|---|
12 | 25 |
15 | 50 |
14 | 10 |
8 | 2 |
etc
I'm trying to maximize the sum of a selection of the target column while keeping the product of the constraint column < a certain number. So for example, if the constraint was 500, one possible solution would be 34, and another would be 29.
How would I code that constraint?
As @AirSquid has pointed out multiplication of variables is not allowed in the objective or constraints of a linear program (this would make it non-linear).
However, the problem you have described can be straight-forwardly and exactly linearised by taking logs. The log of a product of some numbers is equal to the sum of the logs of those numbers. So somthing like:
import pulp
import numpy as np
targets = [12, 15, 14, 8]
constrs = [25, 50, 10, 2]
max_prod = 500
row_idxs = range(len(targets))
log_constrs = [np.log(i) for i in constrs]
log_max_prod = np.log(max_prod)
prob = pulp.LpProblem('so_74304315', pulp.LpMaximize)
z = pulp.LpVariable.dicts('z', indexs=row_idxs, cat='Binary')
# Objective
prob += pulp.lpSum([targets[i]*z[i] for i in row_idxs])
# Constraint (linearised from product to sum of logs)
prob += pulp.lpSum([log_constrs[i]*z[i] for i in row_idxs]) <= log_max_prod
# Solve & print results:
prob.solve()
print("Status:", pulp.LpStatus[prob.status])
print("Objective value: ", pulp.value(prob.objective))
print ("Decision variables: ")
for v in prob.variables():
print(v.name, "=", v.varValue)
Which gives me:
Status: Optimal
Objective value: 34.0
Decision variables:
z_0 = 1.0
z_1 = 0.0
z_2 = 1.0
z_3 = 1.0
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.