Follow us on Twitter and LinkedIn to get the latest updates from the dev team!
Description: Pattern tradeoff example with amplpy
Tags: amplpy, example
Notebook author: Filipe Brandão <fdabrandao@gmail.com>
Model author: N/A
References: N/A
# Install dependencies %pip install -q amplpy
# Google Colab & Kaggle integration from amplpy import AMPL, ampl_notebook ampl = ampl_notebook( modules=["gurobi"], # modules to install license_uuid="default", # license to use ) # instantiate AMPL object and register magics
%%ampl_eval param roll_width > 0; set WIDTHS; param orders {WIDTHS} > 0; param nPAT integer >= 0; param nbr {WIDTHS,1..nPAT} integer >= 0; var Cut {1..nPAT} integer >= 0; minimize Number: sum {j in 1..nPAT} Cut[j]; minimize Waste: sum {j in 1..nPAT} Cut[j] * (roll_width - sum {i in WIDTHS} i * nbr[i,j]); subj to Fulfill {i in WIDTHS}: sum {j in 1..nPAT} nbr[i,j] * Cut[j] >= orders[i];
%%ampl_eval data; param roll_width := 64.5; param: WIDTHS: orders := 6.77 10 7.56 40 17.46 33 18.76 10 ; param nPAT := 9 ; param nbr: 1 2 3 4 5 6 7 8 9 := 6.77 0 1 1 0 3 2 0 1 4 7.56 1 0 2 1 1 4 6 5 2 17.46 0 1 0 2 1 0 1 1 1 18.76 3 2 2 1 1 1 0 0 0 ;
ampl.option["solver"] = "gurobi" ampl.eval("objective Number; solve;") ampl.display("Number", "Waste")
Gurobi 9.5.0: optimal solution; objective 20 3 simplex iterations 1 branch-and-cut nodes Number = 20 Waste = 63.62
ampl.eval("objective Waste; solve;") ampl.display("Number", "Waste")
Gurobi 9.5.0: optimal solution; objective 15.62 2 simplex iterations 1 branch-and-cut nodes Number = 35 Waste = 15.62
ampl.reset()
%%ampl_eval param roll_width > 0; param over_lim integer >= 0; set WIDTHS; param orders {WIDTHS} > 0; param nPAT integer >= 0; param nbr {WIDTHS,1..nPAT} integer >= 0; var Cut {1..nPAT} integer >= 0; minimize Number: sum {j in 1..nPAT} Cut[j]; minimize Waste: sum {j in 1..nPAT} Cut[j] * (roll_width - sum {i in WIDTHS} i * nbr[i,j]); subj to Fulfill {i in WIDTHS}: orders[i] <= sum {j in 1..nPAT} nbr[i,j] * Cut[j] <= orders[i] + over_lim;
%%ampl_eval data; param roll_width := 64.5; param over_lim := 10 ; param: WIDTHS: orders := 6.77 10 7.56 40 17.46 33 18.76 10 ; param nPAT := 9 ; param nbr: 1 2 3 4 5 6 7 8 9 := 6.77 0 1 1 0 3 2 0 1 4 7.56 1 0 2 1 1 4 6 5 2 17.46 0 1 0 2 1 0 1 1 1 18.76 3 2 2 1 1 1 0 0 0 ;
ampl.option["solver"] = "gurobi" ampl.eval("objective Number; solve;") min_number = ampl.get_value("Number") min_numwaste = ampl.get_value("Waste") ampl.eval("objective Waste;")
Gurobi 9.5.0: optimal solution; objective 20 7 simplex iterations 1 branch-and-cut nodes
over_lim = int(ampl.param["over_lim"].value()) prev_number = float("inf") min_waste = {} min_wastenum = {} for k in reversed(range(over_lim)): ampl.param["over_lim"] = k ampl.solve() if ampl.solve_result == "infeasible": break number = ampl.get_value("Number") if number < prev_number: min_waste[k] = ampl.get_value("Waste") min_wastenum[k] = number prev_number = number if number == min_number: break
Gurobi 9.5.0: optimal solution; objective 46.72 4 simplex iterations 1 branch-and-cut nodes Gurobi 9.5.0: optimal solution; objective 46.72 4 simplex iterations 1 branch-and-cut nodes Gurobi 9.5.0: optimal solution; objective 47.89 4 simplex iterations 1 branch-and-cut nodes Gurobi 9.5.0: optimal solution; objective 49.16 4 simplex iterations 1 branch-and-cut nodes Gurobi 9.5.0: optimal solution; objective 54.76 5 simplex iterations 1 branch-and-cut nodes
print("Min{:3.0f} rolls with waste{:6.2f}\n".format(min_number, min_numwaste)) print("Over\tWaste\tNumber") for k in sorted(min_waste.keys(), reverse=True): print("{}\t{}\t{:.0f}".format(k, min_waste[k], min_wastenum[k]))
Min 20 rolls with waste 62.04 Over Waste Number 9 46.71999999999988 22 7 47.88999999999987 21 5 54.75999999999988 20
previous
Robust Linear Programming with Ellipsoidal Uncertainty
next
Scheduling Multipurpose Batch Processes using State-Task Networks in Python