问题
I have some Pyomo code (see below) which produces one possible solution to the linear equation:
3a + 2b + 2c = 15
Where:
-20 <= a <= 0
0 <= b <= 20
20 <= c <= 50
a, b, c are real numbers
How could I rewrite the program to produce a random solution every time it is run? I am open to using Pulp as well.
My Code:
# Coefficients
coeffs = [3,2,2]
y_target = 15
# Define model and variables
model = ConcreteModel()
model.a = Var(bounds=(-20,0))
model.b = Var(bounds=(0,20))
model.c = Var(bounds=(20,50))
model_x = [model.a, model.b, model.c]
# Model Constraint
def weight_rule(model):
return sum(coeffs[i] * model_x[i] for i in range(len(coeffs))) == y_target
model.weight = Constraint( rule=weight_rule )
# Model Objective
obj = sum(coeffs[i] * model_x[i] for i in range(len(coeffs))) - y_target
model.objective = Objective(expr=obj, sense=minimize)
# Solve the model
solver = SolverFactory('glpk')
solver.solve(model)
# Print results
print([value(model_x[i]) for i in range(len(coeffs))])
# Current Output:
[-8.33333, 0, 20]
EDIT - New approach (still not working): Below I adapted some helpful code supplied here by @kabdulla using the approach described by @Erwin Kalvelagen, but can't quite get it working for my case. Any advice would be appreciated.
import pulp as pulp
# Accounting:
# n structural varuables (n = 3)
# m constraints (m = 2)
# => No. of basics = 2 (no. of constraints)
# => No. of non-basics = 2 (no. of variables)
A = [] # Empty list for solutions to exclude
nb = 3
M = 100 # large M value - upper bound for x1, x2, x3 * the slacks
numSolutions = 5 # How many solutions we seek by iterating
# Set lower and upper bound ranges for respective variables
lowers = [-20,0,20]
uppers = [0,20,50]
for _ in range(numSolutions):
model = pulp.LpProblem('get all basis', pulp.LpMaximize)
# Variables
x = pulp.LpVariable.dicts('x', range(3), cat='Continuous')
for i in x.keys():
x[i].lowBound = lowers[i]
x[i].upBound = uppers[i]
# Non-negative Slack Variables - one for each constraint
s = pulp.LpVariable.dicts('s', range(1), lowBound=0, upBound=None, cat='Continuous')
# Basis variables (binary)
# one for each variable & one for each constraint (& so slack)
B_x = pulp.LpVariable.dicts('b_x', range(len(x)), cat='Binary')
B_s = pulp.LpVariable.dicts('b_s', range(len(s)), cat='Binary')
# Objective
model += 3*x[0] + 2*x[1] + 2*x[2]
# Constraints - with explicit slacks
model += 3*x[0] + 2*x[1] + 2*x[2] + s[0] == 15
# No. of basics is correct:
model += pulp.lpSum(B_x) + pulp.lpSum(B_s) == nb
# Enforce basic and non-basic behaviour
for i in range(len(x)):
model += x[i] <= M*B_x[i]
for i in range(len(s)):
model += s[i] <= M*B_s[i]
for a in A:
model += (B_x[0]*a[0] + B_x[1]*a[1] + B_x[2]*a[2] + B_s[0]*a[3]) <= nb - 1
model.solve()
# Cuts - already discovered solutions
exc = [v.varValue for v in model.variables()][:4]
exc = exc[1:4] + exc[0:1]
A.append(exc)
print('Status:', pulp.LpStatus[model.status])
print('Objective:', pulp.value(model.objective))
for v in model.variables():
print (v.name, "=", v.varValue)
来源:https://stackoverflow.com/questions/65677194/how-to-solve-for-multiple-solutions-to-linear-program-in-python