Difference: IntegerProgrammingWithAMPL (2 vs. 3)

Revision 32008-04-23 - MichaelOSullivan

Line: 1 to 1
 
META TOPICPARENT name="IntegerProgramming"

Integer Programming with AMPL

Line: 43 to 43
  ice_nofrills.jpg
Changed:
<
<
Let's look at ways to reduce the size of this branch-and-bound tree.

Looking at the LP Relaxation

Often you can gain insight into the branch-and-bound process by considering the LP relaxation. You can relax integrality without reformulating using

\begin{verbatim}
option relax_integrality 1;
\end{verbatim}



If we look at the variables we can see where our solution is fractional:



As you can see we are using 2.8 fridge units for our 2.8 sculptures. Also, if we check the {\tt TotalWeight} constraint ({\tt display TotalWeight.body;}) we can see that the truck is at its weight limit.

It looks likely that we should only use 2 fridges. We can create some new suffixes to experiment with our hypothesis.

Priorities, Searching and Directions

AMPL and CPLEX allow you to define a priority for your integer variables. This means that if more than one integer variable is fractional in a solution, CPLEX will branch on the highest priority variable first. Let’s add the priority {\tt suffix} to our run file (before solving):

\begin{verbatim}
suffix priority IN, integer, >= 0, <= 9999;
\end{verbatim}


(now we can assign variables priorities ranging from 0 – least – to 9999 – most). Let’s give the {\tt Fridges} variable a priority of 100 and the {\tt Make} variables a priority of 0 (using {\tt let} statements).

\begin{verbatim}
let Fridges.priority := 100;
let {s in SCULPTURES} Make[s].priority := 0;
\end{verbatim}




The branch-and-bound tree appears unchanged, so perhaps CPLEX had already branched on {\tt Fridges} first earlier. However, we can try a breadth-first search of the tree, since this will try different values for {\tt Fridges} before performing branching on other variables. Setting {\tt nodeselect} to 2 (best estimate) and {\tt backtrack} to 0 makes CPLEX perform a search very close to breadth-first (see The AMPL CPLEX User Guide for full details).

\begin{verbatim}
option cplex_options ('timing 1 mipdisplay 5 mipinterval 1 ' &
'presolve 0 mipcuts -1 cutpass -1 ' &
'heurfreq -1 ' &
'nodeselect 2 backtrack 0');
\end{verbatim}




Now the tree has been fathomed earlier (it only has 4 nodes instead of 6). However, we are not sure if CPLEX branched down to 2 fridges first (our hypothetical optimum).

To control the direction of the branches we can create a new suffix for the direction we should branch on each variable (-1 for down, 0 for no preference, 1 for up).

\begin{verbatim}
suffix direction IN, integer, >= -1, <= 1;
\end{verbatim}



We can force a down branch first on {\tt Fridges}:

\begin{verbatim}
let Fridges.direction := -1;
\end{verbatim}




This doesn’t seem to have decreased the size of the branch-and-bound tree. Let’s try one more thing. We have given CPLEX a good branch to try first, but we have not carefully considered what to do next. Let’s remove the breadth-first search option and let CPLEX decide how to proceed:

reset;



model ice.mod;

data ice.dat;



option solver cplex;



option presolve 0;

option cplex_options ('timing 1 mipdisplay 5 mipinterval 1' &


'presolve 0 mipcuts -1 cutpass -1 ' &


'heurfreq -1');



suffix priority IN, integer, >= 0, <= 9999;

suffix direction IN, integer, >= -1, <= 1;



let Fridges.priority := 100;

let {s in SCULPTURES} Make[s].priority := 0;



let Fridges.direction := -1;



solve;



display Fridges, Make;
<span
style="font-family: monospace;">



Now we have reduced our branch-and-bound tree to a single node by making a good choice about our first variable branch.

As stated earlier, CPLEX does a lot of good things automatically for you. Often, these “tricks” will be enough to solve your mixed-integer programming problems. However, if your problem is taking a long time to solve, you can experiment with adding some of your own control to the branch-and-bound process. History has shown that problem-specific approaches often work very well for hard integer programmes.

>
>
Let's look at ways to reduce the size of this branch-and-bound tree.

Looking at the LP Relaxation

Often you can gain insight into the branch-and-bound process by considering the LP relaxation. You can relax integrality without reformulating using option relax_integrality 1;.

If we look at the variables we can see where our solution is fractional:

ice_relaxation.jpg

As you can see we are using 2.8 fridge units for our 2.8 sculptures. Also, if we check the TotalWeight constraint (display TotalWeight.body;) we can see that the truck is at its weight limit.

It looks likely that we should only use 2 fridges. We can create some new suffixes to experiment with our hypothesis.

Priorities, Searching and Directions

AMPL and CPLEX allow you to define a priority for your integer variables. This means that if more than one integer variable is fractional in a solution, CPLEX will branch on the highest priority variable first. Let's add the priority suffix to our run file (before solving):

suffix priority IN, integer, >= 0, <= 9999;
(now we can assign variables priorities ranging from 0 - least - to 9999 - most). Let's give the Fridges variable a priority of 100 and the Make variables a priority of 0:
let Fridges.priority := 100;
let {s in SCULPTURES} Make[s].priority := 0;

ice_nofrills.jpg

The branch-and-bound tree appears unchanged, so perhaps CPLEX had already branched on Fridges early in the branch-and-bound tree. However, we can try a breadth-first search of the tree, since this will try different values for Fridges before performing branching on other variables. Setting nodeselect to 2 (best estimate) and backtrack to 0 makes CPLEX perform a search very close to breadth-first (see The AMPL CPLEX User Guide for full details).

option cplex_options ('timing 1 mipdisplay 5 mipinterval 1 ' &
                      'presolve 0 mipcuts -1 cutpass -1 ' &
                      'heurfreq -1 ' &
                      'nodeselect 2 backtrack 0');

ice_breadth.jpg

Now the tree has been fathomed earlier (it only has 4 nodes instead of 6). However, we are not sure if CPLEX branched down to 2 fridges first (our hypothetical optimum).

To control the direction of the branches we can create a new suffix for the direction we should branch on each variable (-1 for down, 0 for no preference, 1 for up).

suffix direction IN, integer, >= -1, <= 1;

We can force a down branch first on Fridges:

let Fridges.direction := -1;

ice_breadth.jpg

This doesn't seem to have decreased the size of the branch-and-bound tree.

Let's try one more thing. We have given CPLEX a good branch to try first, but we have not carefully considered what to do next. Let's remove the breadth-first search option and let CPLEX decide how to proceed:

reset;

model ice.mod;
data ice.dat;

option solver cplex;

option presolve 0;
option cplex_options ('timing 1 mipdisplay 5 mipinterval 1' &
                      'presolve 0 mipcuts -1 cutpass -1 ' &
                      'heurfreq -1');

suffix priority IN, integer, >= 0, <= 9999;
suffix direction IN, integer, >= -1, <= 1;

let Fridges.priority := 100;
let {s in SCULPTURES} Make[s].priority := 0;

let Fridges.direction := -1;

solve;

display Fridges, Make;

ice_best.jpg

Now we have reduced our branch-and-bound tree to a single node by making a good choice about our first variable branch and letting CPLEX proceed from there.

As stated earlier, CPLEX does a lot of good things automatically for you. Often, these "tricks" will be enough to solve your mixed-integer programming problems. However, if your problem is taking a long time to solve, you can experiment with adding some of your own control to the branch-and-bound process. History has shown that problem-specific approaches often work very well for hard integer programmes.

  -- MichaelOSullivan - 23 Apr 2008
 
This site is powered by the TWiki collaboration platform Powered by PerlCopyright © 2008-2025 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback