Overview
Column generation (Generation) is an effective algorithm for solving large-scale linear programming problems, which is widely used in large-scale unit scheduling. The main idea is to transform the problem into an equivalence problem that can be dealt with, the purpose of transformation:
The problem is solved by translating the problem into a specific special structure and a ready-made method;
L TRANSLATE the problem into smaller sub-problems;
The key to the success or failure of the application column generation algorithm is to divide the original problem into main problem (main problem) and sub-problem (sub problem). How to construct the column vectors skillfully and divide the original constraint into these two sets of constraints is the key factor of using the column generation algorithm.
The core idea of the column-generating algorithm is very simple, the actual original problem may be many column vectors, but the real "in-base" column vectors only account for a very small part, so if we can manually intervene to select those "better quality" column vectors to solve, it will greatly improve the efficiency of the solution. Therefore, column generation is the use of sub-problems to filter out those "high-quality columns," added to the main model, so that the main model only the better quality of the column optimization.
Next, the IBM ILOG CPLEX built-in panel cutting problem (Cutstock) is described in detail (Modeling language selection ILOG developed OPL language)
Plate cutting Problem (Cutstock):
Factory has a batch of steel plate, long and wide fixed. It is necessary to cut the width of the coil to cut into a small dry steel sheet of different widths, and each width of the steel plate to determine the number of requirements and the corresponding cutting costs, how to minimize the local use of existing steel to meet the specified requirements of the various width of the steel plate and is to be optimized.
Problem Analysis: Column creation:
The essence of the problem is a raw steel plate cut to the end of each of the number of small port, assuming the need for M-type small steel, you can use as the following vector, where x represents the number of cuts per width, each column vector p is a cutting mode (pattern).
Constraint analysis of the original problem:
L The number of small steel plates with each width is required;
L The width of all small steel slices of the original steel is less than the width of the original steel plate;
Main problem, sub-problem construction
With the help of the above-mentioned column vector creation rules, the emphasis of our optimization is to combine the structural characteristics of the proportions of various width types, to find a cost-effective cutting method (patterns), and to calculate the cutting times of these cutting methods. So the original problem is divided into two problems: the main problem (main problem) is to ask for the number of cuts per pattern, sub-problem, to filter out the cost-effective patterns according to the requirements structure of various widths.
Decision variables:
The structure of each type of pattern;
Number of cuts per pattern: cuts;
Next, build the model in OPL language:
Main question:
The dual solution of the main problem is the best price for each kind of steel sheet under the demand structure; the solution of duality problem is included in the sub-problem, the price of each steel plate is the input parameter, the width of the original sheet is constrained, and the best cutting pattern is set up to create maximum profit.
Sub-Problem:
The price of the sub-problem is the solution to the duality problem of the main problem.
Next, use the OPL language to implement these issues:
Main model:
Common width of the rolls to be cut.int rollwidth = ...;//number of items types to be cutsint Nbitems = ...; Range Items = 1..nbitems;//Size of each of the itemsint size[items] = ...;//number of Items of each types to be cutsint Amount[items] = ...;//Pattern of roll cutting that is generated.//Some simple default Pattern is given initially in CU Tstock.dattuple pattern {key int id; int cost; int fill[items];} {Pattern} Patterns = ...;//dual values used to fill in the sub model.float duals[items] = ...;//How many of all pattern is Cutdvar float cut[patterns] in 0..1000000; Minimize Cost:here each Patteran as the same constant cost so that//we Minimize the number of rolls used. Minimize sum (p in Patterns) P.cost * Cut[p];subject to {//Unique constraint in the master model are to cover the Item demand. ForAll (i in Items) Ctfill:sum (p in Patterns) p.fill[i] * Cut[p] >= amount[i];} Tuple r {pattern p; float cut;}; {R} Result = {<p,cut[p]> | p in patterns:cut[p] > 1e-3};//set dual values used to fill in the sub Model.execute fillduals {for (var i in Items) {duals[i] = ctfill[i].dual; }}
Sub-model:
int rollwidth = ...; Range Items = 1..5;int Size[items] = ...; float Duals[items] = ...; DVar int Use[items] in 0..100000;minimize 1-sum (i-Items) duals[i] * Use[i];subject to { Ctfill: sum (i in Items) size[i] * Use[i] <= rollwidth;}
Main control process:
Main {var status = 0; Thisoplmodel.generate (); This is a epsilon value to check if reduced cost is strictly negative var rc_eps = 1.0e-6; Retrieving model definition, engine and data elements from the OPL model//To reuse them latervar Mastersource = NE W Ilooplmodelsource ("Cutstock-main.mod"), var masterdef = new Ilooplmodeldefinition (Mastersource); var mastercplex = Cplex; var masterdata = thisoplmodel.dataelements; Creating the Master-model var masteropl = new Ilooplmodel (masterdef, Mastercplex); Masteropl.adddatasource (Masterdata); Masteropl.generate (); Preparing Sub-model source, definition and engine var subsource = new Ilooplmodelsource ("Cutstock-sub.mod"); var subdef = new Ilooplmodeldefinition (Subsource); var Subcplex = new Ilocplex (); var best; var curr = Infinity; while (best! = Curr) {best = Curr; Writeln ("Solve master."); if (Mastercplex.solve ()) {masteropl.postprocess (); Curr = Mastercplex.getobjvalue (); Writeln (); Writeln ("MASTER OBJECTIVE:", Curr); } else {writeln ("No Solution to Master problem!"); Masteropl.end (); Break }//Ceating the sub model var subopl = new Ilooplmodel (Subdef,subcplex); Using data elements from the master model. var subdata = new Iloopldataelements (); Subdata.rollwidth = Masteropl.rollwidth; Subdata.size = masteropl.size; Subdata.duals = masteropl.duals; Subopl.adddatasource (Subdata); Subopl.generate (); Previous Master model is not needed anymore. Masteropl.end (); Writeln ("Solve Sub."); if (Subcplex.solve () && subcplex.getobjvalue () <=-rc_eps) {writeln (); Writeln ("SUB OBJECTIVE:", Subcplex.getobjvalue ()); } else {writeln ("No new good pattern, stop."); Subdata.end (); Subopl.end (); Break }//PREpare Next Iteration MasterData.Patterns.add (Masterdata.patterns.size,1,subopl.use.solutionvalue); MASTEROPL = new Ilooplmodel (Masterdef,mastercplex); Masteropl.adddatasource (Masterdata); Masteropl.generate (); End Sub Model Subdata.end (); Subopl.end (); }//Check solution value if (Math.Abs (curr-46.25) >=0.0001) {status =-1; Writeln ("Unexpected objective value"); } subdef.end (); Subcplex.end (); Subsource.end (); status;}
Hopefully these will help you to understand the production of the children's shoes.
Generation algorithm based on OPL combined Cutstock case combing column