Ignore:
Timestamp:
May 3, 2005 9:03:29 AM (15 years ago)
Author:
rlh
Message:

Rennovated Cbc user guide for INFORMS Tutorial book chapter

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Docs/otherclasses.xml

    r119 r120  
    22  <chapter id="otherclasses">
    33  <title>
    4   Selecting a Node in the Search Tree
     4  Selecting the Next Node in the Search Tree
    55  </title>
    66  <section id="comparison">
    77  <title>CbcCompare - Comparison Methods</title>
    88  <para>
    9   The order in which the nodes of the tree are explored is not predetermined and can be influenced by the user.
    10   CBC provides a abstract base class <classname>CbcCompareBase</classname>
    11   and several instances which are described in <xref linkend="compareTable"/>.
     9  The order in which the nodes of the search tree are explored can strongly influence the performance of branch-and-cut algorithms. CBC give users complete control over the search order. The search order is controlled via the <classname>CbcCompare...</classname> class. CBC provides an abstract base class, <classname>CbcCompareBase</classname>,  and several commonly used instances which are described in <xref linkend="compareTable"/>.
    1210  </para>
    1311    <table frame="none" id="compareTable">
     
    3129      <entry align="left" valign="top">
    3230      This will always choose the node deepest in tree.  It gives minimum
    33       tree size but may take a long time to find best solution.
     31      tree size but may take a long time to find the best solution.
    3432      </entry>
    3533    </row>
     
    5048      </entry>
    5149      <entry align="left" valign="top">
    52       This is designed to do a mostly depth first search until a solution has
    53       been found and then use estimates designed to give a slightly better solution.
    54       If a reasonable number of nodes have been done or a reasonable number of
    55       solutions found then it will go breadth first (i.e. on objective) unless
    56       the tree is very large when it will revert to depth first.  Probably
    57       <classname>CbcCompareUser</classname> described below is better.
     50      This is designed to do a mostly depth-first search until a solution has
     51      been found. It then use estimates that are designed to give a slightly better solution.
     52      If a reasonable number of nodes have been explored (or a reasonable number of
     53      solutions found), then this class will adopt a breadth-first search (i.e., making a comparison based strictly on objective function values) unless the tree is very large when it will revert to depth-first search. A better description of <classname>CbcCompareUser</classname> is given below.
    5854      </entry>
    5955    </row>
     
    6359      </entry>
    6460      <entry align="left" valign="top">
    65       If pseudocosts are being used then they can be used to guess a solution.
    66       This just uses guessed solution.
     61      When pseudo costs are invoked, they can be used to guess a solution.  This class uses the guessed solution.
    6762      </entry>
    6863    </row>
     
    7166  </table>
    7267  <para>
    73   It is relatively simple for an advanced user to create new compare class instances.  This describes how to build a new comparison class and the reasoning behind it. This is <filename>CbcCompareUser.hpp</filename> and <filename>CbcCompareUser.cpp</filename> (this code can be found in the CBC Samples directory, see
    74   <xref linkend="moreexamples"/>).  The key <classname>CbcCompare</classname> method is <function>bool test(CbcNode* x, CbcNode* y))</function> which returns true if node <parameter>y</parameter> is better than node <parameter>x</parameter>. In this method the user can easily use the following information available from <classname>CbcModel</classname>.
    75   <table frame="none">
     68  It is relatively simple for an experienced user to create new compare class instances. The code in <xref linkend="test"/> describes how to build a new comparison class and the reasoning behind it. The complete source can be found in <filename>CbcCompareUser.hpp</filename> and <filename>CbcCompareUser.cpp</filename>, located in the CBC Samples directory. See <xref linkend="moreexamples"/>. The key method in <classname>CbcCompare</classname> is <function>bool test(CbcNode* x, CbcNode* y))</function> which returns <parameter>true</parameter> if node <parameter>y</parameter> is preferred over node <parameter>x</parameter>. In the <function>test()</function> method, information from <classname>CbcNode</classname> can easily be used. <xref linkend="nodeTable"/> list some commonly used methods to access information at a node.
     69  <table frame="none" id="nodeTable">
    7670  <title>Information Available from <classname>CbcNode</classname></title>
    7771    <tgroup cols="2">
     
    8276      </entry>
    8377      <entry align="left" valign="top">
    84       Value of objective at that node.
     78      Value of objective at the node.
    8579      </entry>
    8680    </row>
     
    9185      <entry align="left" valign="top">
    9286      Number of unsatisfied integers (assuming branching
    93       object is an integer - otherwise might be number of unsatsified sets).
     87      object is an integer - otherwise it might be number of unsatisfied sets).
    9488      </entry>
    9589    </row>
     
    133127
    134128<para>
    135   There is no information on the state of the tree. If you wanted you could
    136   keep a pointer to the <classname>CbcModel</classname> but the way it is meant to work is that
    137   <function>newSolution()</function> is called whenever a solution is found and <function>every1000Nodes()</function> is called every 1000 nodes.  When these are called the user can modify the
    138   behavior of <function>test()</function>.  Because <classname>CbcNode</classname> has a pointer to the model, the user can also do other things such as changing the maximum time of CBC once a solution has been found (e.g., <function>CbcModel::setMaximumSeconds(double value)</function>). In <filename>CbcCompareUser.cpp</filename> in <filename>COIN/Cbc/Samples</filename> four items of data are used.
     129The node desired in the tree is often a function of the how the search is progressing. In the design of CBC, there is no information on the state of the tree. The CBC is designed so that the method
     130  <function>newSolution()</function> is called whenever a solution is found and the method <function>every1000Nodes()</function> is called every 1000 nodes.  When these methods are called, the user has the opportunity to modify the
     131  behavior of <function>test()</function> by adjusting their common variables (e.g., <varname>weight_</varname>). Because <classname>CbcNode</classname> has a pointer to the model, the user can also influence the search through actions such as changing the maximum time CBC is allowed, once a solution has been found (e.g., <function>CbcModel::setMaximumSeconds(double value)</function>). In <filename>CbcCompareUser.cpp</filename> of the <filename>COIN/Cbc/Samples</filename> directory,  four items of data are used.
    139132</para>
    140133<itemizedlist>
     
    151144  <listitem>
    152145  <para>
    153 3) A weight which is initialized to -1.0
     1463) A weight, <varname>weight_</varname>, which is initialized to -1.0
    154147  </para>
    155148  </listitem>
    156149  <listitem>
    157150  <para>
    158 4) A saved value of weight (for when we set weight back to -1.0 for special reason)
     1514) A saved value of weight, <varname>saveWeight_</varname> (for when weight is set back to -1.0 for special reason)
    159152  </para>
    160153  </listitem>
    161154</itemizedlist>
    162155<para>
    163 The full code for <function>CbcCompareUser::test()</function> is given below.
    164 </para>
    165   <example>
    166   <title>test</title>
     156The full code for the <function>CbcCompareUser::test()</function> method is given in <xref linkend="test"/>.
     157</para>
     158  <example id="test">
     159  <title><function>CbcCompareUser::test()</function></title>
    167160  <programlisting>
    168161  <![CDATA[ 
     
    180173      return x->depth() < y->depth();
    181174  } else {
    182     // after solution
     175    // after solution.
     176    // note: if weight_=0, comparison is based
     177    //       solely on objective value
    183178    double weight = CoinMax(weight_,0.0);
    184179    return x->objectiveValue()+ weight*x->numberUnsatisfied() >
     
    190185  </example>
    191186<para>
    192 Initially, <varname>weight</varname>_ is &lt; 0.0 and we are biased towards depth first.  In
    193 fact, the method prefers <parameter>y</parameter> if <parameter>y</parameter> has fewer unsatisfied variables. In the case of a tie, the method prefers the node with the greater depth in tree.
    194 
    195 Once we get a solution <function>newSolution()</function> is called.  If it was a solution
    196 achieved by branching, <!-- how do can you determine that? --> we work out how much it cost per unsatisfied integer
    197 variable to go from continuous solution to integer solution.  We then set the weight to aim at a slightly better solution.  From then on the method <function>test()</function> returns true if it looks as if <parameter>y</parameter> will lead to a better solution than <parameter>x</parameter>. This is done by <function>newSolution()</function>.
    198 </para>
    199   <example>
    200   <title>newSolution</title>
    201   <programlisting>
    202   <![CDATA[ 
    203 // This allows method to change behavior as it is called
    204 // after each solution
     187Initially, <varname>weight</varname>_ is -1.0 and the search is biased towards depth first.  In
     188fact, <function>test()</function> prefers <parameter>y</parameter> if <parameter>y</parameter> has fewer unsatisfied variables. In the case of a tie, <function>test()</function> prefers the node with the greater depth in tree. Once a solution is found, <function>newSolution()</function> is called. The method <function>newSolution()</function> interacts with <function>test()</function> by means of the variable <varname>weight_</varname>. If the solution was achieved by branching, <!-- how do can you determine that? --> a calculation is made to determine the cost per unsatisfied integer variable to go from the continuous solution to an integer solution.  The variable <varname>weight_</varname> is then set to aim at a slightly better solution.  From then on, <function>test()</function> returns <parameter>true</parameter> if it seems that <parameter>y</parameter> will lead to a better solution than <parameter>x</parameter>. This source for <function>newSolution()</function> in given in <xref linkend="newSolution"/>.
     189</para>
     190  <example id="newSolution">
     191  <title><function>CbcCompareUser::newSolution()</function></title>
     192  <programlisting>
     193  <![CDATA[ 
     194// This allows the test() method to change behavior by resetting weight_.
     195// It is called after each new solution is found.
    205196void
    206197CbcCompareUser::newSolution(CbcModel * model,
     
    209200{
    210201  if (model->getSolutionCount()==model->getNumberHeuristicSolutions())
    211     return; // solution was got by rounding so we ignore
    212   // set to get close to this solution
     202    return; // solution was found by rounding so ignore it.
     203
     204  // set weight_ to get close to this solution
    213205  double costPerInteger =
    214206    (model->getObjValue()-objectiveAtContinuous)/
     
    218210  numberSolutions_++;
    219211  if (numberSolutions_>5)
    220     weight_ =0.0; // this searches on objective
     212    weight_ =0.0; // comparison in test() will be
     213                  // based strictly on objective value.
    221214}
    222215  ]]>   
     
    225218<para>
    226219
    227 But as the search goes on this <!-- what? is "this"? --> may be modified. If a lot of nodes or got a lot of solutions have been genereated, then <varname>weight_</varname> is set to 0.0 so we are doing breadth-first search.  Breadth-first search can lead to an enormous tree. If the tree size is exceeds 10000, then we may desire to go back to a search biased towards depth first. Changing the behaviour done by the method <function>every1000Nodes</function>.
    228   </para>
    229   <example>
    230   <title>newSolution</title>
    231   <programlisting>
    232   <![CDATA[ 
    233 // This allows method to change behavior
     220As the search progresses, the comparison can be <!-- what? is "this"? -->modified. If many nodes (or many solutions) have been genereated, then <varname>weight_</varname> is set to 0.0 leading to a breadth-first search.  Breadth-first search can lead to an enormous tree. If the tree size is exceeds 10000, it may be desirable to return to a search biased towards depth first. Changing the behavior in this manner is done by the method <function>every1000Nodes</function> shown in <xref linkend="everyK"/>.
     221  </para>
     222  <example id="everyK">
     223  <title><function>CbcCompareUser::every1000Nodes()</function></title>
     224  <programlisting>
     225  <![CDATA[ 
     226// This allows the test() method to change behavior every so often
    234227bool
    235228CbcCompareUser::every1000Nodes(CbcModel * model, int numberNodes)
    236229{
    237230  if (numberNodes>10000)
    238     weight_ =0.0; // this searches on objective
     231    weight_ =0.0; // compare nodes based on objective value
    239232  else if (numberNodes==1000&&weight_==-2.0)
    240233    weight_=-1.0; // Go to depth first
     
    259252<chapter id="hueristicChap">
    260253  <title>
    261   Using Hueristics in CBC
     254  Getting Good Bounds in CBC
    262255  </title>
    263256  <section id="heuristics">
    264257  <title>CbcHeuristic - Heuristic Methods</title>
    265258  <para>
    266   In practice, it is very useful to get a good solution reasonably fast.
    267   A good bound will greatly reduce the run time and good solutions can satisfy the user
     259  In practice, it is very useful to get a good solution reasonably fast. Any MIP-feasible solution produces an upper bound, and a good bound will greatly reduce the run time. Good solutions can satisfy the user
    268260  on very large problems where a complete search is impossible.  Obviously, heuristics are
    269   problem dependent although some have more general use.
    270   At present there is only one in CBC itself. Hopefully, the number of heuristics will grow.
    271   Other hueristics are in the <filename>COIN/Cbc/Samples</filename>
     261  problem dependent, although some do have more general use.
     262  At present there is only one heuristic in CBC itself, <classname>CbcRounding</classname>. Hopefully, the number will grow. Other heuristics are in the <filename>COIN/Cbc/Samples</filename>
    272263  directory.  A heuristic tries to obtain a solution to the original
    273264  problem so it only needs to consider the original rows and does not have to use the
    274   current bounds.
    275   One to use a greedy heuristic designed for use in the miplib problem
    276   fast0507 will be developed later in this section. <!-- huh? -->
    277   CBC provides an abstract base class <classname>CbcHeuristic</classname> and a rounding heuristic in CBC.
    278   </para>
    279   <para>
    280   This describes how to build a greedy heuristic for a set covering problem.
    281    A more general version is in <filename>CbcHeuristicGreedy.hpp</filename> and
    282    <filename>CbcHeuristicGreedy.cpp</filename> which can be found in the <filename>COIN/Cbc/Samples</filename> directory, see <xref linkend="moreexamples"/>.
    283 
    284   The heuristic we will code will leave all variables which are at one at this node of the
    285   tree to that value and will
    286   initially set all others to zero.  We then sort all variables in order of their cost
    287   divided by the number of entries in rows which are not yet covered.  We may randomize that
    288   value a bit so that ties will be broken in different ways on different runs of the heuristic.
    289   We then choose the best one and set it to one and repeat the exercise. Because this is
    290   a set covering problem &ge; we are guaranteed to find a solution (not necessarily a
    291   better one though).  We could
    292   improve the speed by just redoing those affected but in this text we will keep it simple.
    293   Also if all elements are 1.0 then we could do faster.
    294   The key CbcHeuristic method is <function>int&nbsp;solution(double &amp; solutionValue,
    295                                               double&nbsp;*&nbsp;betterSolution)</function>
    296   which returns 0 if no solution found and 1 if found when it fills in the objective value
    297   and primal solution.  The actual code in <filename>CbcHeuristicGreedy.cpp</filename> is
    298   a little more complicated but this will work and gives the basic idea.  For instance
    299   the code here assumes all variables are integer.
    300   The important bit of data is a copy of the matrix (stored by column)
    301   before any cuts have been made.  The data used are bounds, objective and the matrix
    302   plus two work arrays.
     265  current bounds. CBC provides an abstract base class <classname>CbcHeuristic</classname> and a rounding heuristic in CBC. <!-- rlh: we need an example of using an existing heuristic -->
     266  </para>
     267  <para>
     268  This chapter describes how to build a greedy heuristic for a set covering problem, e.g., the miplib problem fast0507. A more general (and efficient) version of the heuristic is in <filename>CbcHeuristicGreedy.hpp</filename> and <filename>CbcHeuristicGreedy.cpp</filename> located in the <filename>COIN/Cbc/Samples</filename> directory, see <xref linkend="moreexamples"/>.
     269</para>
     270<para>
     271  The greedy heuristic will leave all variables taking value one at this node of the
     272  tree at value one, and will initially set all other variable to value zero. 
     273  All variables are then sorted in order of their cost
     274  divided by the number of entries in rows which are not yet covered. (We may randomize that
     275  value a bit so that ties will be broken in different ways on different runs of the heuristic.)
     276  The best one is choosen, and set to one. The process is repeated. Because this is
     277  a set covering problem (i.e., all constraints are &ge;), the heuristic is guaranteed to find a solution (but not necessarily an improved solution). The speed of the heuristic could be improved by just redoing those affected, but for illustrative purposes we will keep it simple.(The speed could also be improved if all elements are 1.0).
     278</para>
     279<para>
     280  The key <classname>CbcHeuristic</classname> method is <function>int&nbsp;solution(double &amp; solutionValue,
     281                                              double&nbsp;*&nbsp;betterSolution)</function>.
     282  The <function>solution()</function> method returns 0 if no solution found, and returns 1 if a solution is found, in which case it fills in the objective value and primal solution.  The code in <filename>CbcHeuristicGreedy.cpp</filename> is a little more complicated than this following example. For instance, the code here assumes all variables are integer.  The important bit of data is a copy of the matrix (stored by column) before any cuts have been made.  The data used are bounds, objective and the matrix plus two work arrays.
    303283  </para>
    304284  <example>
     
    331311  </example>
    332312<para>
    333 Then we initialize newSolution as rounded down solution.
     313The <varname>newSolution</varname> is then initialized to the rounded down solution.
    334314</para>
    335315  <example>
    336   <title>initialize newSolution</title>
     316  <title>Initialize <varname>newSolution</varname></title>
    337317  <programlisting>
    338318  <![CDATA[ 
     
    361341  </example>
    362342<para>
    363 Now some row activities will be below their lower bound so
    364 we then find the variable which is cheapest in reducing the sum of
    365 infeasibilities.  We then repeat.  This is a finite process and could be coded
    366 to be faster but this is simplest.
     343<!-- rlh: where is "direction" from? -->
     344
     345At this point some row activities may be below their lower bound. To correct this infeasibility, the variable which is cheapest in reducing the sum of infeasibilities is found and updated, and the process repeats.  This is a finite process. (Theimplementation could be faster, but is kept simple for illustrative purposes.)
    367346  </para>
    368347  <example>
    369   <title>Create feasible new solution</title>
     348  <title>Create Feasible <varname>newSolution</varname> from Initial <varname>newSolution</varname></title>
    370349  <programlisting>
    371350  <![CDATA[ 
     
    416395  </example>
    417396<para>
    418 We have finished so now we need to see if solution is better and doublecheck
    419 we are feasible.
     397A solution value of <varname>newSolution</varname> is compared to the best solution value. If <varname>newSolution</varname> is an improvement, its feasibility is validated.
    420398  </para>
    421399  <example>
    422   <title>Check good solution</title>
     400  <title>Check Solution Quality of <varname>newSolution</varname></title>
    423401  <programlisting>
    424402  <![CDATA[ 
    425403  returnCode=0; // 0 means no good solution
    426   if (newSolutionValue<solutionValue) {
     404  if (newSolutionValue<solutionValue) { // minimization
    427405    // check feasible
    428406    memset(rowActivity,0,numberRows*sizeof(double));
     
    465443 </title>
    466444  <section id="branching">
    467   <title>Branching</title>
    468   <para>
    469 If the user declares variables as integer but does no more, then Cbc will treat them
    470 as simple integer variables.  In many cases the user would like to do some more fine tuning.  This shows how to create integer variables with pseudo costs.  When pseudo costs are given then
    471 it is assumed that if a variable is at 1.3 then the cost of branching that variable down will be 0.3 times the down pseudo cost and the cost of branching up would be 0.7 times the up pseudo cost.  This can be used both for branching and for choosing a node.
    472    The full code is in <filename>longthin.cpp</filename>
    473   (this code can be found in the CBC Samples directory, see
    474   <xref linkend="moreexamples"/>). 
     445  <title>Pseudo Cost Branching</title>
     446  <para>
     447<!-- rlh: need a description of "objects" -->
     448If the user declares variables as integer but does no more, then CBC will treat them
     449as simple integer variables.  In many cases the user would like to do some more fine tuning. This section shows how to create integer variables with pseudo costs.  When pseudo costs are given then
     450it is assumed that if a variable is at 1.3 then the cost of branching that variable down will be 0.3 times the down pseudo cost and the cost of branching up would be 0.7 times the up pseudo cost.  Pseudo costs can be used both for branching and for choosing a node.
     451   The full code is in <filename>longthin.cpp</filename> located in the CBC Samples directory, see
     452  <xref linkend="moreexamples"/>.
     453</para>
     454<para> 
    475455  The idea is simple for set covering problems.
    476   Branching up gets us much closer to an integer solution so we want
    477   to encourage up - so we will branch up if variable value > 0.333333.
     456  Branching up gets us much closer to an integer solution so we will encourage that direction by branch up if variable value > 0.333333.
    478457  The expected cost of going up obviously depends on the cost of the
    479   variable so we just choose pseudo costs to reflect that.
    480   </para>
    481   <example>
    482   <title>Pseudo costs</title>
     458  variable. The pseudo costs are choosen to reflect that fact.
     459<!-- rlh: what's the difference between simple var objects and pseudo cost objects? explain. -->
     460  </para>
     461  <example id="pseudo">
     462  <title><classname>CbcSimpleIntegerPseudoCosts</classname></title>
    483463  <programlisting>
    484464  <![CDATA[ 
     
    509489  </example>
    510490<para>
    511 The actual coding in the example also tries to give more importance to variables with more
     491The code in <xref linkend="pseudo"/> also tries to give more importance to variables with more
    512492coefficients.  Whether this sort of thing is worthwhile should be the subject of experimentation.
    513 Here is another example which is for crew scheduling problems.  In this case the problem has
    514 few rows but many thousands of variables.  Branching a variable to 1 is very powerful as it
    515 fixes many other variables to zero, but branching to zero is very weak as thousands of variables
    516 can increase from zero.  But in crew scheduling each constraint is a flight leg e.g. JFK to DFW.
    517 From DFW (Dallas) there may be several flights the crew could take next - suppose one flight is
    518 the 9:30 flight from DFW to LAX (Los Angeles).  Then a binary branch is that the crew arriving
    519 at DFW either take the 9:30 flight to LAX or they don't.  This follow-on branching does not
    520 fix individual variables but instead divides all the variables with entries in the JFK-DFW
     493<!-- needs more explaination, e.g., why do you have to delete objects? -->
     494<!-- what does a pseudo cost object do for you? and how does it do it? -->
     495</para>
     496</section>
     497  <section id="followOn">
     498  <title>Follow-On Branching</title>
     499  <para>
     500In crew scheduling, the problems are long and thin. A problem may have a few rows but many thousands of variables.  Branching a variable to 1 is very powerful as it fixes many other variables to zero, but branching to zero is very weak as thousands of variables can increase from zero.  In crew scheduling problems, each constraint is a flight leg, e.g., JFK airport to DFW airport.
     501From DFW there may be several flights the crew could take next - suppose one flight is
     502the 9:30 flight from DFW to LAX airport.  A binary branch is that the crew arriving
     503at DFW either take the 9:30 flight to LAX or they don't.  This "follow-on" branching does not
     504fix individual variables. Instead this branching divides all the variables with entries in the JFK-DFW
    521505constraint into two groups - those with entries in the DFW-LAX constraint and those without
    522506entries.
    523    The full code is in <filename>crew.cpp</filename>
    524   (this code can be found in the CBC Samples directory, see
    525   <xref linkend="moreexamples"/>).  In this case we may as well leave the simple integer
    526 variables and we may have to if there are other sorts of constraints.  But we want to
    527 branch on the follow-on rules first so we use priorities to say that those are the
    528 important ones.
     507</para>
     508<para>
     509   The full sample code for follow-on brancing is in <filename>crew.cpp</filename>
     510  located in the CBC Samples directory, see
     511  <xref linkend="moreexamples"/>).  In this case, the simple integer
     512variables are left which may be necessary if other sorts of constraints exist. Follow-on branching rules are to be considered first, so the priorities are set to indicated the follow-on rules take precedence. Priority 1 is the highest priority.
     513<!-- rlh:need to explain how *priorities* work, and where they are used -->
    529514</para>
    530515  <example>
    531   <title>Follow-on branching</title>
     516  <title><classname>CbcFollowOn</classname></title>
    532517  <programlisting>
    533518  <![CDATA[ 
    534519  int iColumn;
    535520  int numberColumns = solver3->getNumCols();
    536   /* We are going to add a single follow on object but we
     521  /* We are going to add a single follow-on object but we
    537522     want to give low priority to existing integers
    538523     As the default priority is 1000 we don't actually need to give
     
    547532    }
    548533  }
    549   /* Second parameter is true if we are adding objects,
    550      false if integers.  So this does integers */
     534  /* Second parameter is set to true for objects,
     535     and false for integers. This indicates integers */
    551536  model.passInPriorities(priority,false);
    552537  delete [] priority;
    553   /* Add in objects before we can give priority.
    554      In this case just one - but this shows general method
     538  /* Add in objects before we can give them a priority.
     539     In this case just one object
     540     - but it shows the general method
    555541  */
    556542  CbcObject ** objects = new CbcObject * [1];
     
    565551  </programlisting>
    566552  </example>
     553<!-- rlh: need to explain the CbcFollowOn object -->
    567554  </section>
    568555</chapter>
    569556<chapter id="SolverChap">
    570557<title>
    571 Advance Use of Solver
     558  Advance Solver Uses
    572559</title>
    573560  <section id="solver">
    574   <title>Advanced Use of Solver</title>
    575   <para>
    576   Coin Branch and Cut uses a generic <classname>OsiSolverInterface</classname> and its <function>resolve</function> capability.
    577   This does not give much flexibility so advanced users can inherit from the interface
    578   of choice.  This describes such a solver for a long thin problem e.g. fast0507 again.
    579   As with all these examples it is not guaranteed that this is the fastest way to solve
    580   any of these problems - they are to illustrate techniques.
    581    The full code is in <filename>CbcSolver2.hpp</filename> and
    582    <filename>CbcSolver2.cpp</filename>
    583   (this code can be found in the CBC Samples directory, see
    584   <xref linkend="moreexamples"/>).
    585   <function>initialSolve</function> is called a few times so although we will not gain much
    586   this is a simpler place to start.  The example derives from <classname>OsiClpSolverInterface</classname> and the code
    587   is:
    588   </para>
    589   <example>
    590   <title>initialSolve</title>
     561  <title>Creating a Solver via Inheritance</title>
     562  <para>
     563  CBC uses a generic <classname>OsiSolverInterface</classname> and its <function>resolve</function> capability.
     564  This does not give much flexibility so advanced users can inherit from their interface
     565  of choice.  This section illustrates how to implement such a solver for a long thin problem, e.g., fast0507 again.  As with the other examples in the Guide, the sample code is not guaranteed to be the fastest way to solve the problem. The main purpose of the example is to illustrate techniques. The full source is in <filename>CbcSolver2.hpp</filename> and <filename>CbcSolver2.cpp</filename> located in the CBC Samples directory, see
     566  <xref linkend="moreexamples"/>.
     567</para>
     568<para>
     569The method <function>initialSolve</function> is called a few times in CBC, and provides a convenient starting point. The <varname>modelPtr_</varname> derives from <classname>OsiClpSolverInterface</classname>.
     570  </para>
     571  <example id="initialSolve">
     572  <title><function>initialSolve()</function></title>
    591573  <programlisting>
    592574  <![CDATA[ 
     
    606588  </programlisting>
    607589  </example>
    608 <para>
    609 The <function>resolve</function> method is more complicated.  The main pieces of data are
    610 a counter <varname>count_</varname>which is incremented each solve and an int array <varname>node_</varname> which stores the last time
    611 a variable was active in a solution.  For the first few times normal dual is called and
     590<!-- rlh: need a verbal description to go with the intialSolve() code -->
     591<para>
     592The <function>resolve()</function> method is more complicated than <function>initialSolve()</function>.  The main pieces of data are a counter <varname>count_</varname> which is incremented each solve and an integer array <varname>node_</varname> which stores the last time
     593a variable was active in a solution.  For the first few times, the normal Dual Simplex is called and
    612594<varname>node_</varname> array is updated.
    613595</para>
    614596  <example>
    615   <title>First few solves</title>
     597  <title>First Few Solves</title>
    616598  <programlisting>
    617599  <![CDATA[ 
     
    634616  </programlisting>
    635617  </example>
    636 <para>
    637 After the first few solves we only use those which took part in a solution in the last so many
    638 solves.  As fast0507 is a set covering problem we can also take out any rows which are
    639 already covered.
     618<!-- rlh: need more explanation of what's being illustrated in the code -->
     619<para>
     620After the first few solves, only those variables which took part in a solution in the last so many
     621solves are used.  As fast0507 is a set covering problem, any rows which are already covered can be taken out.
    640622  </para>
    641623  <example>
    642   <title>Create small problem</title>
     624  <title>Create Small Problem</title>
    643625  <programlisting>
    644626  <![CDATA[ 
     
    737719  </example>
    738720<para>
    739 If the variables cover the rows then we know that the problem is feasible (we are not using
    740 cuts).  If the rows
    741 were E rows then this might not be the case and we would have to do more work.  When we have solved
    742 then we see if there are any negative reduced costs and if there are then we have to go to the
    743 full problem and use primal to clean up.
     721If the variables cover the rows, then the problem is feasible (no cuts are being used). If the rows
     722were equality constraints, then this might not be the case. More work would be needed.  After the solution, the reduct costs are checked. If any reduced costs are negative, the code goes back to the full problem and cleans up with Primal Simplex.
    744723  </para>
    745724  <example>
    746   <title>Check optimal solution</title>
     725  <title>Check Optimal Solution</title>
    747726  <programlisting>
    748727  <![CDATA[ 
     
    783762        nBad++;
    784763    }
    785     // If necessary claen up with primal (and save some statistics)
     764    // If necessary clean up with primal (and save some statistics)
    786765    if (nBad) {
    787766      timesBad_++;
     
    793772  </example>
    794773<para>
    795 We then update <varname>node_</varname> array as for the first few solves.  To give some idea of the effect of this
    796 tactic fast0507 has 63,009 variables and the small problem never has more than 4,000 variables.
    797 In just over ten percent of solves did we have to resolve and then the average number of iterations
     774The array <varname>node_</varname> is updated, as for the first few solves.  To give some idea of the effect of this tactic, the problem fast0507 has 63,009 variables but the small problem never has more than 4,000 variables. In only about ten percent of solves was it necessary to resolve, and then the average number of iterations
    798775on full problem was less than 20.
    799 To give another example - again only for illustrative purposes it is possible to do quadratic
    800 mip.  In this case we make <function>resolve</function> the same as
     776</para>
     777</section>
     778 <section id="quadratic">
     779  <title>Quadratic MIP</title>
     780<para>
     781To give another example - again only for illustrative purposes -- it is possible to do quadratic
     782MIP with CBC.  In this case, we make <function>resolve</function> the same as
    801783<function>initialSolve</function>.
    802784   The full code is in <filename>ClpQuadInterface.hpp</filename> and
    803    <filename>ClpQuadInterface.cpp</filename>
    804   (this code can be found in the CBC Samples directory, see
     785   <filename>ClpQuadInterface.cpp</filename> located in the CBC Samples directory, see
    805786  <xref linkend="moreexamples"/>).
    806787  </para>
    807788  <example>
    808   <title>Solve a quadratic mip</title>
     789  <title>Solving a Quadratic MIP</title>
    809790  <programlisting>
    810791  <![CDATA[ 
Note: See TracChangeset for help on using the changeset viewer.