source: trunk/Clp/doc/basicmodelclasses.xml @ 1369

Last change on this file since 1369 was 754, checked in by andreasw, 14 years ago

first version

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 25.7 KB
Line 
1<?xml version="1.0" encoding="ISO-8859-1"?>
2  <chapter id="basicmodelclasses">
3  <title>
4  Basic Model Classes
5  </title>
6  <section id="hierarchy">
7  <title>
8  Hierarchy
9  </title>
10  <para>
11  The basic CLP model class hierarchy is simple.  The top three levels of the
12  hierarchy are depicted in the figure below. The first two levels  (i.e.
13  <classname>ClpModel</classname>, <classname>ClpSimplex</classname>,
14  <classname>ClpInterior</classname>) contain all the problem data which define
15  a model (that is, a problem instance). The third level contains most of the
16  algorithmic aspects of CLP.  There is a fourth level (for models with more general
17  objectives than linear ones), but a description of it is beyond the current scope
18  of this document.
19  </para>
20  <mediaobject>
21    <!-- Caption doesn't line-up nicely in HTML, leave out for now
22    <caption align="top">
23      <para>
24        CLP Basic Classes
25      </para>
26    </caption>
27    -->
28    <imageobject>
29      <imagedata fileref="figures/clpbasicmodelhier.gif" format="GIF"/>
30    </imageobject>
31  </mediaobject>
32  <!-- Not appropriate here and not entirely correct as worded!
33  <para>
34  The class <classname>ClpModel</classname> contains most of the  problem data.
35  There may be a few pieces of data which could be elsewhere but which are
36  permanent and so they are here.  The main example of this is a status array:
37  it makes the most sense for Simplex but has use for crossing over from any
38  solution.
39  </para>
40  <para>
41  <classname>ClpSimplex</classname> inherits from
42  <classname>ClpModel</classname>, as does <classname>ClpInterior</classname>.
43  Extra data is specific to the Simplex Algorithm and can be transient, e.g.
44  scaling arrays.  Normally a user will just be dealing with the
45  <classname>ClpSimplex</classname> class and not with the
46  <classname>ClpModel</classname> class.
47  </para>
48  -->
49  <para>
50  Most Simplex users need only concern themselves with the classes
51  <classname>ClpModel</classname> and <classname>ClpSimplex</classname>.  There
52  are algorithm-specific classes which inherit from
53  <classname>ClpSimplex</classname> (e.g. <classname>ClpSimplexDual</classname>
54  and <classname>ClpSimplexPrimal</classname>), but they have no member data and
55  rarely need be visible to the user.  These  classes are cast at algorithm
56  time.  So, for example, after instantiating an object
57  <userinput>model</userinput> of type <classname>ClpSimplex</classname>,
58  a user only need call <userinput>model.dual()</userinput> to invoke the dual
59  simplex method.
60  </para>
61  </section>
62  <section id="firstexample">
63  <title>
64  First Example
65  </title>
66  <para>
67  Below is our first CLP sample program.  It is short enough to present in full
68  (this code can be found in the CLP Samples directory, see
69  <xref linkend="moreexamples"/>).  Most of the remaining examples in this Guide
70  will take the form of small code fragments.
71  </para>
72  <example>
73  <title>minimum.cpp</title>
74  <programlisting>
75  <![CDATA[ 
76// Copyright (C) 2002, International Business Machines
77// Corporation and others.  All Rights Reserved.
78
79#include "ClpSimplex.hpp"
80int main (int argc, const char *argv[])
81{
82  ClpSimplex  model;
83  int status;
84  if (argc<2)
85    status=model.readMps("../../Mps/Sample/p0033.mps");
86  else
87    status=model.readMps(argv[1]);
88  if (!status) {
89    model.primal();
90  }
91  return 0;
92}
93  ]]>   
94  </programlisting>
95  </example>
96  <para>
97  This sample program creates a  <classname>ClpSimplex</classname> model,
98  reads an MPS file, and if there are no errors, solves it using the primal
99  algorithm.  The program is easy to follow, but it is not terribly useful:
100  it does not attempt to inspect the results of the solve.  There are two main
101  kinds of results: a &quot;status&quot; describing what happened to the model
102  during the solve, and arrays filled with solution values.  Both will be
103  addressed in this chapter.
104  </para>
105  </section>
106  <section id="gettingsolution">
107  <title>
108  Getting at the Solution
109  </title>
110  <para>
111  It is often the case with CLP that there is more than one way to do something.
112  This is a consequence of CLP's mixed heritage as a child of
113  <ulink url="http://www-306.ibm.com/software/data/bi/osl/">OSL</ulink>
114  and a cousin of <ulink url="http://www.coin-or.org/faqs.html#OSI">OSI</ulink>.
115  Finding the status of a model exemplifies this situation.
116  </para>
117  <para>
118  The OSI way to check for optimality is to call model.isProvenOptimal().  Also
119  available are <function>isProvenPrimalInfeasible()</function>,
120  <function>isProvenDualInfeasible()</function>,
121  <function>isPrimalObjectiveLimitReached()</function>,
122  <function>isDualObjectiveLimitReached()</function>,
123  <function>isIterationLimitReached()</function> or the feared
124  <function>isAbandoned()</function>.  Should one prefer the OSL way of doing
125  things, model.status() returns as it would in OSL, so 0 means optimal,
126  1 means  primal infeasible etc.
127  </para>
128  <para>
129  Similarly, to pick up the solution values, one could inhabit the virtuous
130  world of OSI, or the not-quite-so-virtuous world of OSL and &quot;pure&quot;
131  CLP.  By this it is meant that const and non-const forms of arrays are used,
132  respectively.  It is easier to deal with the non-const versions, so most of
133  the elaborate algorithms in CLP and its
134  <link linkend="moresamples">Samples</link> use them.
135  </para>
136  <table frame="none">
137  <title>
138  Methods for getting solution information
139  </title>
140  <tgroup cols="3">
141  <thead>
142    <row>
143      <entry>
144      Purpose
145      </entry>
146      <entry>
147      OSI-style (virtuous)
148      </entry>
149      <entry>
150      CLP-style (less virtuous)
151      </entry>
152    </row>
153  </thead>
154  <tbody>
155    <row>
156      <entry align="left" valign="top">
157      Primal column solution
158      </entry>
159      <entry align="left" valign="top">
160      <function>const double * getColSolution()</function>
161      </entry>
162      <entry align="left" valign="top">
163      <function>double * primalColumnSolution()</function>
164      </entry>
165    </row>
166    <row>
167      <entry align="left" valign="top">
168      Dual row solution
169      </entry>
170      <entry align="left" valign="top">
171      <function>const double * getRowPrice()</function>
172      </entry>
173      <entry align="left" valign="top">
174      <function>double * dualColumnSolution()</function>
175      </entry>
176    </row>
177    <row>
178      <entry align="left" valign="top">
179      Primal row solution
180      </entry>
181      <entry align="left" valign="top">
182      <function>const double * getRowActivity()</function>
183      </entry>
184      <entry align="left" valign="top">
185      <function>double * primalRowSolution()</function>
186      </entry>
187    </row>
188    <row>
189      <entry align="left" valign="top">
190      Dual row solution
191      </entry>
192      <entry align="left" valign="top">
193      <function>const double * getReducedCost()</function>
194      </entry>
195      <entry align="left" valign="top">
196      <function>double * dualColumnSolution()</function>
197      </entry>
198    </row>
199    <row>
200      <entry align="left" valign="top">
201      Number of rows in model
202      </entry>
203      <entry align="left" valign="top">
204      <function>int getNumRows()</function>
205      </entry>
206      <entry align="left" valign="top">
207      <function>int numberRows()</function>
208      </entry>
209    </row>
210    <row>
211      <entry align="left" valign="top">
212      Number of columns in model
213      </entry>
214      <entry align="left" valign="top">
215      <function>int getNumCols()</function>
216      </entry>
217      <entry align="left" valign="top">
218      <function>int numberColumns()</function>
219      </entry>
220    </row>
221  </tbody>
222  </tgroup>
223  </table>
224
225  <para>
226  The reader  may have noted a preference for &quot;number&quot; over
227  &quot;num&quot; and &quot;column&quot; over &quot;col&quot;.  This may be a
228  reaction to when one of the authors was young and 5 or 6 letters was the
229  maximum in FORTRAN for any name or to early days with OSL when seven characters
230  were allowed but the first three had to be &quot;ekk&quot;
231  </para>
232  <para>
233  Using the above-listed functions, our
234  <link linkend="firstexample">initial example</link> might be continued as follows:
235  </para>
236  <example>
237  <title>
238  Possible extension of minimum.cpp
239  </title>
240  <programlisting>
241  <![CDATA[ 
242  int numberRows = model.numberRows();
243  double * rowPrimal = model.primalRowSolution();
244  double * rowDual = model.dualRowSolution();
245
246  int iRow;
247
248  for (iRow=0;iRow<numberRows;iRow++)   
249    printf("Row %d, primal %g, dual %g\n",iRow,
250        rowPrimal[iRow],rowDual[iRow]);
251       
252  int numberColumns = model.numberColumns();
253  double * columnPrimal = model.primalColumnSolution();
254  double * columnDual = model.dualColumnSolution();
255
256  int iColumn;
257
258  for (iColumn=0;iColumn<numberColumns;iColumn++)       
259    printf("Column %d, primal %g, dual %g\n",iColumn,
260        columnPrimal[iColumn],columnDual[iColumn]);
261  ]]>
262  </programlisting>
263  </example>
264  <para>
265  This code sample would pretty-print information about the model's primal and
266  dual solutions.  How to additionally print row and column names is
267  illustrated in the <filename>defaults.cpp</filename> file in the
268  &quot;Samples&quot; directory (the Samples are properly addressed
269  in <xref linkend="moreexamples" />).  This sample is also useful as it
270  explicitly performs default actions (e.g. it sets the primal feasiblility
271  tolerance value to the default value).
272  </para>
273  <para>
274  The remainder of this chapter will show  more of the basic CLP tasks a user
275  might wish to perform.  Apart from presolve we will only be looking at actions
276  which can be performed when including the single header file
277  <filename>COIN/Clp/include/ClpSimplex.hpp</filename>.
278  </para>
279  </section>
280  <section id="buildandmodify">
281  <title>
282  Building and Modifying a Model
283  </title>
284  <para>
285  Rather than reading a model from an MPS file we can load a model from arrays
286  in memory.  There are various <function>loadProblem</function> methods which
287  are similar to those in OSI.  It is easy to add more such methods to CLP if the need arises.
288  </para>
289  <para>We can copy in integer information by
290  <function>copyInIntegerInformation(const&nbsp;char&nbsp;*&nbsp;array)</function> where array
291  is 0 or 1 to say integer and we can drop existing information by
292  <function>deleteIntegerInformation()</function>.  There are various ways of
293  changing the size of a model.  The simplest is by the use of the method
294  <function>resize(newNumberRows,newNumberColumns)</function> - this will either
295  truncate the model or add &quot;default&quot; rows or columns - a default row
296  has lower bound of -infinity and upper bound of +infinity, while a default
297  column has zero cost, zero lower bound and an upper bound of +infinity.
298  </para>
299  <para>
300  Normally we would use <function>deleteRows</function>,
301  <function>addRows</function>, <function>deleteColumns</function> and
302  <function>addColumns</function>, where the <function>add</function> methods
303  will also add in the elements.  A potentially very useful way of modifying a model is strictly a
304  constructor.  Given a large model and a list of rows and a list of columns it
305  constructs the model as a subset of the large model.  It is possible to change
306  the order of the columns/rows and to duplicate columns/rows.  So a list of
307  columns 4,4,1,0 will create a new model where the first two columns are copies
308  of column 4 in original model and the next two are the first two of original
309  model in reverse order.  This can be useful to form a model with piecewise
310  linear costs by duplicating columns and then modifying bounds and costs.
311  </para>
312  </section>
313  <section id="tolerances">
314  <title>Tolerances</title>
315  <para>
316  There are set and get methods for tolerances, for example,
317  <function>double&nbsp;primalTolerance()</function> and
318  <function>setPrimalTolerance(double)</function>.  Assuming that one has a
319  minimization problem, an individual variable is deemed primal feasible if it
320  is less than the tolerance referred to by these methods below its lower bound
321  and less than it above its upper bound.  Similarly for dual tolerances, a
322  variable is deemed to be dual feasible if its reduced cost is greater than
323  minus the tolerance or its distance to the upper bound is less than primal
324  tolerance and the reduced cost is less than plus the tolerance or the distance
325  to lower bound is less than primal tolerance.  In short, this is complementarity
326  conditions adadpted for tolerances and simple lower and upper bounds.(Note
327  that the above was stated as for minimization; signs are reversed for
328  maximization.)
329  </para>
330  </section>
331  <section id="setsandgets">
332  <title>Some Useful Set and Get Methods</title>
333  <table frame="none">
334  <title>Some Useful Set and Get Methods</title>
335    <tgroup cols="2">
336    <thead>
337    <row>
338    <entry>
339    Method(s)
340    </entry>
341    <entry>
342    Description
343    </entry>
344    </row>
345    </thead>
346    <tbody>
347    <row>
348      <entry align="left" valign="top">
349      <function>setMaximumIterations(int value)</function><sbr/>
350      <function>int maximumIterations()</function><sbr/>
351      <function>setMaximumSeconds(double value)</function><sbr/>
352      <function>double maximumIterations()</function>
353      </entry>
354      <entry align="left" valign="top">
355      These methods tell CLP to stop after a given number of iterations or
356      seconds (and returns these values).
357      </entry>
358    </row>
359    <row>
360      <entry align="left" valign="top">
361      <function>double&nbsp;objectiveValue()</function>
362      </entry>
363      <entry align="left" valign="top">
364      This method returns the objective value.
365      </entry>
366    </row>
367    <row>
368      <entry align="left" valign="top">
369      <function>const&nbsp;double&nbsp;*&nbsp;getObjCoefficients()</function><sbr/>
370      <function>double&nbsp;*&nbsp;objective()</function>
371      </entry>
372      <entry align="left" valign="top">
373      These methods return the objective coefficients.
374      </entry>
375    </row>
376    <row>
377      <entry align="left" valign="top">
378      <function>const&nbsp;double&nbsp;*&nbsp;getRowLower()</function><sbr/>
379      <function>double&nbsp;*&nbsp;rowLower()</function><sbr/>
380      <function>const&nbsp;double&nbsp;*&nbsp;getRowUpper()</function><sbr/>
381      <function>double&nbsp;*&nbsp;rowUpper()</function><sbr/>
382      <function>const&nbsp;double&nbsp;*&nbsp;getColLower()</function><sbr/>
383      <function>double&nbsp;*&nbsp;columnLower()</function><sbr/>
384      <function>const&nbsp;double&nbsp;*&nbsp;getColUpper()</function><sbr/>
385      <function>double&nbsp;*&nbsp;columnUpper()</function>
386      </entry>
387      <entry align="left" valign="top">
388      These methods give lower and upper bounds on row and column activities.
389      </entry>
390    </row>
391    <row>
392      <entry align="left" valign="top">
393      <function>double * infeasibilityRay()</function><sbr/>
394      <function>double * unboundedRay()</function>
395      </entry>
396      <entry align="left" valign="top">
397      If the problem was primal or dual infeasible, these methods will give a
398      pointer to a ray proving infeasibility.
399      </entry>
400    </row>
401    <row>
402      <entry align="left" valign="top">
403      <function>CoinPackMatrix * matrix()</function>
404      </entry>
405      <entry align="left" valign="top">
406      There are more options as the user has great flexibility in how the problem
407      matrix is stored, but the default matrix class is
408      <classname>CoinPackedMatrix</classname> (see
409      <xref linkend="matrixclasses"/>).
410      So we have that this method returns a pointer to a
411      <classname>CoinPackedMatrix</classname> which can be further manipulated.
412      </entry>
413    </row>
414    <row>
415      <entry align="left" valign="top">
416      <function>CoinBigIndex&nbsp;getNumElements()</function>
417      <footnote>
418        <para>
419        <type>CoinBigIndex</type> is a <function>typedef</function> which in
420        most cases is the same as <type>int</type>.
421        </para>
422      </footnote>
423      </entry>
424      <entry align="left" valign="top">
425      Returns the number of elements in the problem matrix.
426      </entry>
427    </row>
428    <row>
429      <entry align="left" valign="top">
430      <function>void setOptimizationDirection(double&nbsp;value)</function><sbr/>
431      <function>double optimizationDirection()</function>
432      </entry>
433      <entry align="left" valign="top">
434      These methods set and get the objective sense.  The parameter
435      <parameter>value</parameter> should be +1 to minimize, -1 to maximize,
436      and 0 to ignore.
437      </entry>
438    </row>
439    </tbody>
440  </tgroup>
441  </table>
442  </section>
443  <section id="simplexspecific">
444  <title>
445  Simplex-specific Methods
446  </title>
447  <para>
448  Some of the most commonly-used methods when working with Simplex are listed in
449  the table below.
450  </para>
451  <table frame="none">
452  <title>Common Simplex-specific methods</title>
453    <tgroup cols="2">
454    <thead>
455    <row>
456    <entry>
457    Method(s)
458    </entry>
459    <entry>
460    Description
461    </entry>
462    </row>
463    </thead>
464    <tbody>
465    <row>
466      <entry align="left" valign="top">
467      <function>primal(int&nbsp;mode=0)</function>
468      </entry>
469      <entry align="left" valign="top">
470      This applies the primal algorithm. If <parameter>mode</parameter> is
471      set to the default of 0, then the method uses the status variables to
472      determine basis and solution. If <parameter>mode</parameter> is 1 then
473      the method does a values pass so variables not in basis are given their
474      current values and one pass of variables is done to clean up the basis
475      with an equal or better objective value.
476      </entry>
477    </row>
478    <row>
479      <entry align="left" valign="top">
480      <function>dual(int&nbsp;mode=0)</function>
481      </entry>
482      <entry align="left" valign="top">
483      This applies the dual algorithm. if <parameter>mode</parameter> is set
484      to the default of 0, then the method uses the status variables to
485      determine basis and solution.  If <parameter>mode</parameter> is 1 then
486      the method uses input duals and does a values pass so one pass of basic
487      variables is done to clean up the duals with an equal or better objective
488      value.
489      </entry>
490    </row>
491    <row>
492      <entry align="left" valign="top">
493      <function>scaling(int&nbsp;mode=1)</function>
494      </entry>
495      <entry align="left" valign="top">
496      This method toggles scaling on (<parameter>mode</parameter> set to 1)
497      and off (<parameter>mode</parameter> set to 0).
498      </entry>
499    </row>
500    <row>
501      <entry align="left" valign="top">
502      <function>int&nbsp;crash(double&nbsp;gap,int&nbsp;mode)</function>
503      </entry>
504      <entry align="left" valign="top">
505      This method attemps to improve on an all slack basis.
506      For dual this will move variables to the dual feasible bound
507      if the gap between bounds is less than <parameter>gap</parameter>.  Setting
508      <parameter>mode</parameter> to 0 guesses which algorithm is better, while
509      a value of 1 or 2 will result in more work being done.  The return code is
510      0 if the basis was not slacks in first case, it is negative if dual is
511      preferred or positive if primal.  &plusmn;1 means an all slack basis seemed
512      best, while &plusmn;2 means some work was done.
513      </entry>
514    </row>
515    <row>
516      <entry align="left" valign="top">
517      <function>perturb(int&nbsp;mode)</function>
518      </entry>
519      <entry align="left" valign="top">
520      This method toggles perturbation on (<parameter>mode</parameter> set to 1)
521      and off (<parameter>mode</parameter> set to 0).  It should be considered
522      a work in progress, although on some problems it gives very good results.
523      </entry>
524    </row>
525    <row>
526      <entry align="left" valign="top">
527      <function>factorizationFrequency()</function><sbr/>
528      <function>setFactorizationFrequency(int&nbsp;value)</function>
529      </entry>
530      <entry align="left" valign="top">
531      These are &quot;get&quot; and &quot;set&quot; methods for the basis matrix
532      factorization frequency.  The default is to refactor every 200 iterations,
533      but it may make more sense to use something such as 100 + the number of
534      rows divided by 50.
535      </entry>
536    </row>
537    <row>
538      <entry align="left" valign="top">
539      <function>dualBound()</function><sbr/>
540      <function>setDualBound(double&nbsp;value)</function>
541      </entry>
542      <entry align="left" valign="top">
543      These are &quot;get&quot; and &quot;set&quot; methods for the
544      &quot;dual&nbsp;bound&quot;.  The CLP dual algorithm declares all problems
545      to be dual feasible by putting non-basic variables to correct bounds for
546      the reduced cost.  If the gap between the bounds is too big then it
547      pretends the gap is only the value specified by this set method.
548      In essence, this gives a composite dual rather than a pure
549      Phase&nbsp;I- Phase&nbsp;II method.
550      </entry>
551    </row>
552    <row>
553      <entry align="left" valign="top">
554      <function>infeasibilityCost()</function><sbr/>
555      <function>setInfeasibilityCost(double&nbsp;value)</function>
556      </entry>
557      <entry align="left" valign="top">
558      These are the primal analogs to the &quot;dual&nbsp;bound&quot; methods.
559      </entry>
560    </row>
561    <row>
562      <entry align="left" valign="top">
563      <function>numberPrimalInfeasibilities()</function><sbr/>
564      <function>sumPrimalInfeasibilities()</function>
565      </entry>
566      <entry align="left" valign="top">
567      After a solve, there may be infeasibilities.  These methods serve to
568      check for said infeasibilities.  One could check the solution explicitly
569      as well.  For a code fragement illustrating this, see
570      <xref linkend="presolveexample"/>.
571      </entry>
572    </row>
573    </tbody>
574  </tgroup>
575  </table>
576  </section>
577  <section id="presolve">
578  <title>
579  Presolve
580  </title>
581  <para>
582  The header file for the use of CLP's presolve functionality is
583  <filename>COIN/Clp/include/Presolve.hpp</filename>.  The sample program below
584  illustrates some of the possibilities offered by CLP's presolve:
585  </para>
586  <example id="presolveexample">
587  <title>Presolve code fragment</title>
588  <programlisting>
589#include "ClpSimplex.hpp"
590#include "ClpPresolve.hpp"
591int main (int argc, const char *argv[])
592{
593  ClpSimplex model;
594  model.readMps("../../Mps/Sample/p0033.mps"); // initialized by readMps or whatever
595  ClpPresolve presolveInfo;
596  ClpSimplex * presolvedModel = presolveInfo.presolvedModel(model);
597  // at this point we have original model and a new model.  The  information
598  // on the operations done is in presolveInfo
599  if (presolvedModel) {
600    // was not found to be infeasible - so lets solve
601    // if presolvedModel was NULL then it was primal infeasible and ...
602    presolvedModel->dual(); // or whatever else we wish to do
603    presolveInfo.postsolve(true);  // the true updates status arrays in original       
604    /* If the presolved model was optimal then so should the
605       original be.           
606       We can use checkSolution and test feasibility */
607    model.checkSolution();         
608    if (model.numberDualInfeasibilities()||
609        model.numberPrimalInfeasibilities())
610      printf("%g dual %g(%d) Primal %g(%d)\n",
611             model.objectiveValue(),
612             model.sumDualInfeasibilities(),
613             model.numberDualInfeasibilities(),
614             model.sumPrimalInfeasibilities(),
615             model.numberPrimalInfeasibilities());
616    // Due to tolerances we can not guarantee that so you may wish to throw in
617    model.primal(1);
618  }
619}   
620  </programlisting>
621  </example>
622  <para>
623  Presolve has a few more options which can be found in the header file, for
624  example whether to treat as an integer problem or whether to keep row and
625  column names.
626  </para>
627  </section>
628  <section id="statusarray">
629  <title>Status Array</title>
630  <para>
631  The astute reader may have noticed that the status array has been mentioned
632  once or twice.  The beginning user will not need to look at it   Nevertheless,
633  for completeness the status of a variable can be found and set as shown below.
634  The possible state of a variable are listed in the following table (each may
635  have to be preceded by ClpSimplex::):
636  </para>
637  <table frame="none">
638  <title>Possible states of a variable</title>
639    <tgroup cols="2">
640      <thead>
641        <row>
642          <entry>
643          <type>Status</type><footnote><para><type>Status</type>
644            is an enumeration.</para></footnote>
645          </entry>
646          <entry>
647          Description
648          </entry>
649        </row>
650      </thead>
651      <tbody>
652        <row>
653          <entry align="left" valign="top">
654          <constant>basic</constant>
655          </entry>
656          <entry align="left" valign="top">
657          In basis
658          </entry>
659        </row>
660        <row>
661          <entry align="left" valign="top">
662          <constant>isFree</constant>
663          </entry>
664          <entry align="left" valign="top">
665          Not in basis, has infinite bounds
666          </entry>
667        </row>
668        <row>
669          <entry align="left" valign="top">
670          <constant>isFixed</constant>
671          </entry>
672          <entry align="left" valign="top">
673          Not in basis, bounds are equal
674          </entry>
675        </row>
676        <row>
677          <entry align="left" valign="top">
678          <constant>atUpperBound</constant>
679          </entry>
680          <entry align="left" valign="top">
681          At upper bound, not in basis
682          </entry>
683        </row>
684        <row>
685          <entry align="left" valign="top">
686          <constant>atLowerBound</constant>
687          </entry>
688          <entry align="left" valign="top">
689          At lower bound, not in basis
690          </entry>
691        </row>
692        <row>
693          <entry align="left" valign="top">
694          <constant>superBasic</constant>
695          </entry>
696          <entry align="left" valign="top">
697          Between bounds, but not basic or free
698          </entry>
699        </row>
700      </tbody>
701    </tgroup>
702  </table>
703  <para>
704  To get or set the status of a variable is a simple task:
705  </para>
706  <programlisting>
707  // Get row status...
708  Status status=model.getRowStatus(sequenceNumber)
709  // ... or get column status.
710  Status status=model.getColumnStatus(sequenceNumber)
711  // Set row status to basic (for example)...
712  model.setRowStatus(sequenceNumber,ClpSimplex::basic)
713  // ... or column status to basic.
714  model.setColumnStatus(sequenceNumber,ClpSimplex::basic)
715  </programlisting>
716  </section>
717  </chapter>
Note: See TracBrowser for help on using the repository browser.