Problem 2 - Desks, Tables, Chairs - Learn to Use Sets and Parameters

Spelling out linear equations in "expr"s is ok for a start, but it's better to use a more professional framework that scales to a 100 variables.

Anyways, here was a surprise - very similar to the last problem. Here, it's desks, chairs, tables. How many should we make? We can sell as many D and C as we make, but only 5 tables a mo. That's one constraint. Then, there's lumber, finishing hours and carpentry hours - all of which are limited - so that's four constraints total.

And, it spat out no solution. Why? I followed the usual ConcreteModel path.

I must have done something wrong, because reducing to two constraints also gave me zilch. So, what?

OK. Instead of

results = optm.solve(model)

I did just

optm.solve(model)

With the former, you get

Problem: - Name: unknown Lower bound: 280.0 Upper bound: 280.0 Number of objectives: 1 Number of constraints: 4 Number of variables: 3 Number of nonzeros: 10 Sense: maximize Solver: - Status: ok Termination condition: optimal Statistics: Branch and bound: Number of bounded subproblems: 0 Number of created subproblems: 0 Error rc: 0 Time: 0.0037925243377685547 Solution: - number of solutions: 0 number of solutions displayed: 0

And it does tell you something - make 2 desks, 8 chairs and no tables. Nice! Though you wouldn't guess looking at "number of solutions: 0" 😊

What if you say Chairs only bring in $10 each instead of $20 (tables are $30)? Then it says produce only desks and nothing else. These are from Winston, W and Goldberg J "Operations Research : Applications and Algorithms, Fourth Ed", Cengage, Boston, MA, 2004 Pg 140.

Now, following the more mature approach (sets and parameters) (which also replaces "expr" with "rule")

model = pyo.ConcreteModel()

# Sets
model.i = pyo.Set(initialize = ['Desks', 'Tables', 'Chairs'])

# Parameters
model.L = pyo.Param(model.i, initialize = {'Desks':8, 'Tables':6, 'Chairs':1})
L_lim = 48
...
...
# Decision variables
model.x = pyo.Var( model.i, within=pyo.NonNegativeIntegers) # from NonNeg Reals
x = model.x

def Objective_rule(model):
  return sum(R[i]*x[i] for i in model.i)

model.Const_L = pyo.Constraint(  rule=ConstraintL)


def ConstraintL(model):
  return sum(L[i]*x[i] for i in model.i ) <= L_lim

model.Const_L = pyo.Constraint(  rule=ConstraintL)

Likewise, for the other constraints..

optm = SolverFactory('glpk')
results = optm.solve(model)

print(results)
print("Objective fn = ", model.Obj())
for i in model.i:
  print(f"Number of {i} produced: {x[i](i)}")

Gave me the same, good.


Comments

Popular posts from this blog

Section 5 Challenge Problem: Traveling Salesman

Integer Programming (Section 5) Introduces a Nice (Big "em") Coding Trick