简体   繁体   中英

Using multiplication in a pulp constraint

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM