Changed after first review for comp.sources.reviewed:

- Bug with row singletons and assignment fixed.
- Makefile fixed.
- Formatted man page (lp_solve.man) added + target to generate it in the
  Makefile
- install signal handler after reading the input to avoid dumping core
- changed names of some examples to make them uniform
- added correct results for all examples

Changes since the comp.sources.reviewed release:

- added more input sanity checking
- removed a bug in the Branch-and-Bound code which could cause umlimited
  recursion and finally a core dump
- removed the duplicate declaration of global variable Rows
- replaced bcopy by the ANSI standard memcopy
- various small cosmetic changes

Changes for version 1.1

- added KNOWN_BUGS file.
- accept x <= 0 as a sane bound.

Changes for version 1.2

- added (unsupported by me) VMS_SUPPORT file
- made lp_solve print the reason a problem cannot be solved (unbounded or
  infeasible)
- added input format extension to optionally indicate whether the objective
  function should be minimized or maximized.
- Added output(!) in real MPS format for the -v option.

Changes for version 1.3

- Added #ifdefs to handle the different definitions necessary for yytext on
  different computers. Why is there no standard???
- Fixed a very nasty bug in the parser which would handle variables on the
  right hand side of the relational operator which had an effective negative
  sign wrongly (actually, the negative sign was ignored).
- added -p option to print the values of the dual variables.
- Added test target in Makefile to allow automatic testing with the standard
  examples ex[1-5].lp.
- Added syntax extension for optional user specified constraint (dual) names.
- Fixed bug in the combination of minimization of the objective function
  (min: <obj fun>) and MILP problems. Pure LP worked ok.
- From now on lp_solve refuses problems with just bounds (0 real constraints).
  This does not work anyway.

Changes for version 1.4

- Various cosmetic changes to the sources
- Added ex6.lp just for fun (read it!).
- Added results obtained on netlib and miplib benchmark sets (thanks to
  mps2eq).
- removed pragmas for Alliant computers (they're out of business anyway).
- changed the default "double" type to REAL, which can be changed during
  compilation (-DREAL=float or -DREAL='long double')

Changes for version 1.5

- Added -scale option for global scaling of the problem.
- Fixed problem with Endetacol being written out of bounds.
- Added -autoscale option for automatic scaling of rows and columns.
- Added ex7.lp, an example which can only be solved when scaled properly.
- Added -solve_dual option to let lp_solve solve the dual of the problem it is
  reading. This is not a very useful option, but I needed it to check the
  results generated by the updated -p option (see next item). It will not work
  with equality constraints.
- The -p option now produces real dual values, thanks to a code hint by
  Jeroen Dirks (jeroend@tor.numetrix.com)
- The MILP branch-and-bound loop was rearranged by Jeroen Dirks resulting in
  significantly increased performance (2 - 10 times faster).


Changes for 2.0a

- Added a procedural interface (the lp toolkit).
- removed -scale and -solve_dual options
- renamed option -autoscale to -s

Changes for 2.0b1

- Added -mps option to read MPS files. And also included some mps associated
  functions in the toolkit.

Changes for 2.0b2

- Fixed bug in:
	delete_lp
	del_constraint
	write_MPS
- added:
	write_LP
	msp2lp
	lp2mps

Changes for 2.0b3

- Changed default integer/noninteger value to 1e-3
- Added Epsb in Iteration function at minit detection
  (lp_solve gave infeasible for some feasible problems)
- Added -degen perturbation option for degenerate problems.

Changes for 2.0

- Removed "Parsing" message
- Made CHECK Warning output print to stderr

Changes for 2.1beta

- added '-time' option to print CPU times of parsing and optimization
- fixed some MPS reading problems
- allow empty OF in lp_solve format to get just a feasible solution
- added filtering of very small pivots to improve numerical stability
- fixed several bugs in lpkit.c and readmps.c

Changes for 2.1

- improved the speed of the MPS reader (considerably!) by introducing hash
  tables
- fixed bug in column_in_lp
- updated Jeroen Dirks' email address in the sources
- added HARTMUT_DOCUMENTATION to the distribution

Changes for 2.2

- fixed memory leak in delete_lp
- fixed some more lpkit.c bugs
- got rid of the ugly global variables used in solve.c.

Changes for 2.3

- fixed memory problem in solve.c (eta arrays were not always realloc-ed on
  time).
- support for RANGES in MPS reworked; should now be according to standard
- option -degen could sometimes produce "results" for infeasible problems,
  fixed.
- previous versions of lp_solve would not scale any column when integer
  variables were present. Now only the actual integer columns are not scaled.
- copy_lp now also copies the rowname and colname hash tables

Changes for 3.0

- lp_solve now has an official open source license, 3.0 and up will have the
  LGPL license attached.
- there was a problem in write_MPS, where numbers were printed with up to 16
  digits instead of the maximum of 12

Changes for 3.0

- Bug fix with -degen option (constants were not so constant any more)

Changes for 3.1

- copy name strings in copy_hash_table to avoid crashes when old lp's are freed
- added call to btran at line 925 of solve.c according to an analysis by Joerg
  Herbers

Changes for 3.1a

- fixed memory management problem in read.c introduced in 3.1

Changes for 3.2

- fixed eta realloc problem in solve.c

Changes for 4.0.0.0

- Added files fortify.c, fortify.h, ufortify.h, declare.h
  fortify is a memory management wrapper. It redirects all memory management
  routines like malloc, calloc, realloc, free, ... to own routines. The purpose
  of this is purely for debugging. This 'library' adds leading and trailing
  bytes to each allocated piece of memory which makes it possible to check if
  no memory before or after the allocated block was written. Although this is
  not a perfect method of finding memory overruns, it is a big help in finding
  95% of them. It also checks if all allocated memory is freeed again between a
  given starting and ending point. This 'library' has helped me already
  numerious times to easilly find and pinpoint these problems on the place and
  on the variable where the problem occurs and not on totally different one
  which is very common to this kind of problems.
  Use of this library is very easily.
   - Just include fortify.h in the source file(s) where memory allocation
     functions are used.
   - Define the constant FORTIFY

- Corrected some spelling in different source files.

- Removed exit functions.
  This change is needed when lp_solve is used as a library which is called
  from an application.
  Terminating the process is certainly not a good idea in that case. When a
  severe error occurs, the called function will return exit false to indicate
  that a problem occured and lp->spx_status indicates what the problem is.

- Modified the MALLOC, CALLOC, REALLOC functions to not exit the program if no
  memory could be allocated. Instead the calling functions exit with a return
  code FALSE to indicate there was a problem. The cller program then has to
  check lp->spx_status to see what the problem is. If out of memory then its
  value is the constant OUT_OF_MEMORY.

- The lprec structure has changed considerably. This means that programs must
  be recompiled when they link with this new library.
  A couble of members are deleted, some have changed and several new members
  are created. Be aware of this.
  However the interface to the library is kept as much as possible, so
  recompilation should be possible without modification. One thing is to be
  considered however. Several routines that previously returned a void now
  return int to indicate if they succeeded. They can fail if there is not
  enough memory available. The return status should always be checked ...

- The lpkit.h include file defines some constants like
  DEF_INFINITE, DEF_EPSB, DEF_EPSEL, DEF_EPSD, DEF_EPSILON, PREJ, ...
  It is now possible to overrule these defaults at compile time by defining them
  at that time (generally via the -D compiler option).

- Some constants like DEF_EPSB, DEF_EPSD, DEF_EPSILON
  have now better default values.
  For example in the past, DEF_EPSILON was set to 0.001. This value is the
  tolerance to determine if a REAL is integer. This is used for integer
  optimization. 0.0005 was in the past accepted as an integer value.
  This is now changed to 1e-6

- mps2lp and lp2mps now accept optionally input and output files via the
  command line. It is still possible to work via stdin and stdout (redirection)
    Usage:
      mps2lp [inputfile.mps [outputfile.lp]] [<inputfile.mps] [>outputfile.lp]
      lp2mps [inputfile.lp [outputfile.mps]] [<inputfile.lp] [>outputfile.mps]
- mps2lp and lp2mps now return meaningfull exit codes
   0: File converted successfully
   1: Usage screen was shown
   2: Unable to open input file
   3: Unable to open output file
   4: Unable to read mps/lp file
   5: Unable to write lp/mps file

- Rearranged include header files in hash.c, read.c, lpkit.c
  First the standard C headers are included and then own project headers.
  Some compilers gave warning otherwise.

- Until version 3 there was no presolve implemented in lp_solve. From this
  version there is. The routine is implemented in presolve.c
  By default lp_solve does not do a presolve.
  Member do_presolve of the lprec structure must be set on TRUE before the
  solve() routine is called to do a presolve.
  Presolve can do the following operations:
   - remove empty rows
   - remove empty columns
   - convert rows with only 1 coefficient on a variable to a bound
  A presolve can make the lp problem smaller so that solution time is shorter.

- Debugging/tracing routines in debug.c were always printing results to stderr.
  There is now a new routine print_file() to make the output go to a file.
  Default the output still goes to stderr. If the provided filename is NULL,
  then output is set (back) to stderr.
  The return value of this routine is TRUE or FALSE indicating if file could
  be created (TRUE) of not (FALSE).
  Some debugging routines were moved from lpkit.c to debug.c:
   print_lp()
   print_solution()

- Routine print_solution() is split in several routines:
   print_objective()
   print_solution()
   print_constraints()
   print_duals()
   print_scales()

- A new routine report is added in debug.c to report messages. These messages
  are mostly debugging and tracing messages shown in verbose mode.
  In fact this routine is a replacement for an already existing routine
  error() which always printed to stderr.
  Until version 3 these messages were always reported to stderr or stdout.
  Default this routine reports to stderr, but via a new member in the lprec
  structure (writelog), it is now possible to define an own reporting routine.
  How much the routine will report depends on the verbose level. Until
  version 3 there were only two possible values for the verbose member in the
  lprec structure: TRUE or FALSE: report or not. From version 4 there are seven
  possible verbose levels. They are defined via constants:

    #define CRITICALSTOP    0
    #define CRITICAL        1
    #define SEVERE          2
    #define IMPORTANT       3
    #define NORMAL          4
    #define DETAILED        5
    #define FULL            6

  The bigger the number, the more reporting. 0 is as good as no reporting.
  This will only occur when a severe error occurs. It is the default verbose
  level. It is only generated by the lp parse routine and will raise a
  termination signal SIGABRT if it occurs.
  FULL is report everything.
  The lp_solve executable supports these different levels via an extra number
  to be added with the -v option. For example -v4 indicates verbose level 4.
  When only -v is specified, thus with a number, then verbose level NORMAL (4)
  is used.

- Row and column names can be provided. This is indicated by the member
  names_used op the lprec structure. Until version 3 one had to check this
  value to know if lp->col_name and lp->row_name could be accessed to get this
  name and if now one was constructed either as Row[x] or r_x
  From version 4 it is better to use the new routines get_col_name() and
  get_row_name() to get a name. It may always be called, even if no names
  were provided. In that case a name r_x or v_x is generated.
  That way names are always consequent, which was not the case until version 3.

- Reading and writing lp model. Now supports also ranges. This means that a
  minimum and maximum on a row can be one line. This was already supported by
  the MPS format, but not in the lp format. Not only this gives this the
  advantage that a row doesn't have to be repeated with the same coefficients
  and only a different restriction, but more important the algorithm will
  perform better when this is done. Less memory is needed and a solution
  will be found faster.

- Added a routine read_LP to read an lp file. This is identical to
  read_lp_file, except that read_LP accepts a file name while read_lp_file
  needs a file pointer to an already opened file.

- read_lp_file now uses a common routine to allocate the lp structures instead
  of building it by itself. This makes it easier to modify the lp structures.

- Reading MPS files gave sometimes a parsing error when extra spaces were at
  the end of a line.

- Added a routine read_MPS to read an MPS file. This is identical to
  read_mps, except that read_MPS accepts a file name while read_mps
  needs a file pointer to an already opened file.

- Some memory leaks could occur in several surcomstances.

- Added a new routine set_bounds() to specify lower and upper bound of a
  variable at once. Routines set_upbo() and set_lowbo() still exists.

- Added semi-continuous optimization. The MPS BOUNDS section now support types
  SC and SI and a new routine is added to specify a variable as semi-continuous
  set_semicont(). Routine is_semicont() returns TRUE if column is set as semi-continuous.
  SC stands for Semi Continious and SI for Semi-continius Integer.
  The lp-format doesn't know the SC and SI restrictions.

- Added SOS optimization. A new routine is added to specify a variable as SOS:
  add_SOS(). Routine is_SOS_var() returns TRUE if column is set as SOS.
  In the MPS files SOS restrictions can be specified in the SOS section.
  The lp-format doesn't know the SOS restrictions.
  See SOSInterpolation.pdf for a description about SOS optimization.

- Added max_allowed_columns and set_magic(). Purpose ???

- Added a new routine lp_solve_version() to get the version number of lp_solve
  The version number is still kept in patchlevel.h, however no longer as a
  string, but as 4 numbers:
   #define MAJORVERSION    4
   #define MINORVERSION    0
   #define RELEASE         0
   #define BUILD           0
  This new routine returns those 4 values.

- Added new routine is_int which returns TRUE if column variable is integer.

- Added a new routine make_lpext() which allows to create a new lprec structure
  like make_lp does, but with more parameters so that it can also be used by
  the lp parser. make_lp calles this routine also. By doing this all code to
  create the lprec structure is in only one routine. Is mend for internal use.

- Scaling routine is improved considerably. Some bug were fixed.
  Also added scaling to lagrange variables.
  The new member scalemode in the lprec structure specifies what kind of
  scaling must be done.
  This can be:
    - MMSCALING:  Do numerical range-based scaling (default, original)
    - GEOSCALING: Do geometric mean scaling
    - POWERSCALE: create a scalar of power 2, if specified; may improve compute
    - CURTISREIDSCALE: Do Curtis-Reid scaling.
    - LAGRANGESCALE: Also scale Lagrange columns. Default they are not scaled.
    - INTEGERSCALE: Also scale Integer columns. Default they are not scaled.

  Either MMSCALING or GEOSCALING or CURTISREIDSCALE may be chosen.
  MMSCALING and GEOSCALING can be combined with POWERSCALE by ORing this value
  These values may be ORed to combine several scaling methods
  The default is MMSCALING scaling.
  For Curtis-Reid scaling the routine scaleCR must be called instead of (auto_)scale.

- Added two new routines for getting the unscaled lower and upper bounds
  on variables:
    get_upbo()
    get_lowbo()

- Added routines set_uprange() and set_lowrange() to specify upper and lower
  ranges. Scaling is applied in the routines.

- Added routine get_rh() to retrieve unscaled RHS value.

- Added routine set_rh_range() to set a range on RHS value and get_rh_range()
  to retrieve the unscaled value.

- Added routine get_constr_type() to get contraint type.

- Added routine get_mat() as an alternative for mat_elm()

- Bug corrections in routine get_reduced_costs(). Did not work correct if
  scaling was used. This routine also returns the same as lp->duals.

- get_reduced_costs() and lp->duals now return also the reduced costs of the
  variables. It now returns an array of 1 + rows + columns elements.

- get_reduced_costs() returned wrong values if integer variables were used.

- Added routines calculate_sensitivity_duals, setpivrow,
  calculate_sensitivity_obj to calculated sensitivity analysis on reduced costs
  (lp->dualsfrom, lp->dualsto) and on objective function
  (lp->objfrom, lp->objto)
  This to provide post-optimal sensitivity analysis on the model.

- Added members objfrom, objtill to lprec structure. These contain the
  from-till ranges of the object coefficients where the variables keep their
  values. This is part of post-optimal sensitivity analaysis.

- Added new routine set_lp_name() to set the name of the lp problem.
  Should be used instead of manipulating lp->lp_name

- Added a test to unscale_columns() if columns are already unscaled that
  nothing happens.

- Added routine set_basis() to set an inititial base and get_basis() to get the
  base variables.

- Added printing of ranges in write_LP()

- Added routine write_lp(). This routines does the same as write_LP, but allows
  to specify the filename directly.

- Corrected write_MPS() routine to make sure that column and row labels aren't
  printed outside of MPS field bounds (name max 8 characters). Longer names are
  truncated. This could result in duplicate names, so be careful if this
  happens.

- Corrected write_MPS() routine to print only a BOUNDS section when at least
  one bound exists.

- Added routine write_mps(). This routines does the same as write_MPS, but
  allows to specify the filename directly.

- Added the new field sectimeout in lprec structure to specify a timeout. When
  solving takes longer than this timeout, the solver stops with a TIMEOUT
  return value.

- Added the new field abort in lprec structure to specify an abort routine
  which is regularly called to check if the user didn't abort. This can be set
  via the new routine put_abortfunc()

- Added the new field usermessage in lprec structure to specify a message
  routine which will be called by lp_solve so that the user can receive some
  messages from the algothm what it is doing. This can be set via the new
  put_msgfunc() routine.
  The following constants in lpkit.h can be used to specify what can be reported
    #define MSG_NONE             0
    #define MSG_PRESOLVE         1
    #define MSG_ITERATION        2
    #define MSG_INVERT           4
    #define MSG_LPFEASIBLE       8
    #define MSG_LPEQUAL         16
    #define MSG_LPBETTER        32
    #define MSG_MILPFEASIBLE    64
    #define MSG_MILPEQUAL      128
    #define MSG_MILPBETTER     256
    #define MSG_MILPSTRATEGY   512

- Added some double precision calculations on critical points to improve
  numerical stability.

- Improved branch-and-bound integer algorithm.

- Improved lagrange solver.

- Added several other improvements to the algorithm.

- Extended check_solution routine to check if found solution is valid. This
  is only used for debugging purposes and only called when CHECK_SOLUTION is
  defined at compile time. Default it is not defined.

- Extended floor_first member of lprec structure with a value AUTOMATIC (2)
  Used for integer optimization in branch-and-bound algorithm.
   - When set to FALSE (0), the algorithm will always choose the floor branch
     first.
   - When set to TRUE (1), the algorithm will always choose the ceiling branch
     first.
   - When set to AUTOMATIC (2), the algorithm will deside what branch to take
     first. This could lead to a faster solution time.
  The lp_solve executable supports this via the -c and -ca command line options.

- Added a new member improve to the lprec structure.
  This is used internally by the algorithm for iterative improvement.
  The possible values can be:
    IMPROVE_NONE    0
    IMPROVE_FTRAN   1
    IMPROVE_BTRAN   2
    IMPROVE_FULL    (IMPROVE_FTRAN + IMPROVE_BTRAN)

  IMPROVE_NONE is the default.

- Extended bb_rule in lprec structure.
  The possible constants are now:
    FIRST_SELECT  0: Lowest indexed non-integer column
    RAND_SELECT   1: Random non-integer column
    WORST_SELECT  2: Largest deviation from an integer value
    BEST_SELECT   3: ???
    MEDIAN_SELECT 4: Median value deviation from an integer value
    GREEDY_SELECT 5: ???

  The constants FIRST_NI and RAND_NI are still defined for backward
  compatibility.

- Extended solve exit codes:

    #define UNKNOWN        -5
    #define NOTRUN         -4
    #define USERABORT      -3
    #define TIMEOUT        -2
    #define IGNORED        -1
    #define OPTIMAL         0
    #define MILP_FAIL       1
    #define INFEASIBLE      2
    #define UNBOUNDED       3
    #define FAILURE         4
    #define RUNNING         5

    /* lag_solve extra status values */
    #define FEAS_FOUND      6
    #define NO_FEAS_FOUND   7
    #define BREAK_BB        8

- The lp_solve command line program is modified to handle the new functionality
  of version 4 and there are also some bug fixes. Following thing have changed:
   - If a file name was provided to the command line then it was ignored when
     data is read from an lp-file (-mps option not provied). Input was still
     read from stdin instead. This is now solved.
   - -min and -max options were accepted, but ignored. Corrected.
   - Option -v is extended with a number to specify a verbose level.
     See description above of verbose member in lprec structure for possible
     values. For example -v4 indicates verbose level 4.
     When only -v is specified, thus with a number, then verbose level
     NORMAL (4) is used. If the option is not provided, then SEVERE (2) is used.
   - A new option -lp is added to indicate that the input file is lp. This is
     the default if neither -lp or -mps is specified.
   - A new option -presolve is added to enable presolving.
   - A new option -S is added to specify how much of the solution must be
     outputed. This option has an optional number:
       -S0: Print nothing
       -S1: Only objective value
       -S2: Objective value + variables (default)
       -S3: Objective value + variables + constraints
       -S4: Objective value + variables + constraints + duals
       -S5: Objective value + variables + constraints + duals + lp model
       -S6: Objective value + variables + constraints + duals + lp model + lp scales
     If only -S is specified then -S2 is used.
     Until version 3 this was controled with the -v option. It was an al or
     nothing flag which also resulted in printing details of the algorithm.
     This new option allows to specify more detailed what is wanted.
   - Option -trej
   - option -improve to specify an iterative improvement level.
   - Option -ca: sets lp->floor_first to automatic
   - Option -s is extended with an optional mode
      -s0: Numerical range-based scaling (default)
      -s1: Geometric scaling
      -s2: Curtis-reid scaling
   - New option -sp
     This option only makes sense if -s option was used. It specifies that
     scales must be power of two. Can improve numerical stability.
   - New option -sl
     enables Lagragrange scaling.
   - New option -si
     enables Integer scaling.

- Following is a list of new functions which can be called:

   void lp_solve_version(int *majorversion, int *minorversion, int *release, int *build);

   void set_magic(int code, int param);

   lprec *read_LP(char *input, short verbose, char *lp_name);

   void set_uprange(lprec *lp, int row, REAL value);

   void set_lowrange(lprec *lp, int row, REAL value);

   short is_int(lprec *lp, int column);

   void set_semicont(lprec *lp, int column, short must_be_sc);

   short is_semicont(lprec *lp, int column);

   int add_SOS(lprec *lp, char *name, short sostype, int priority, int count, int *sosvars, REAL *weights);

   short is_SOS_var(lprec *lp, int column);

   int set_lp_name(lprec *lp, char *name);

   REAL get_rh(lprec *lp, int row);

   void set_rh_range(lprec *lp, int row, REAL deltavalue);

   REAL get_rh_range(lprec *lp, int row);

   short get_constr_type(lprec *lp, int row);

   char *get_row_name(lprec *lp, int row);

   char *get_col_name(lprec *lp, int column);

   REAL scale(lprec *lp, REAL *myrowscale, REAL *mycolscale);

   int scaleCR(lprec *lp);

   void set_basis(lprec *lp, int *bascolumn);

   void get_basis(lprec *lp, int *bascolumn);

   lprec *read_MPS(char *input, short verbose);

   int write_mps(lprec *lp, char *output);

   int write_lp(lprec *lp, char *output);

   void print_objective(lprec *lp);

   void print_constraints(lprec *lp);

   int print_file(char *filename);


- Following functions now return a status if they succeeded or not. The
  return value should always be checked. TRUE is ok, FALSE is not ok

   int set_mat(lprec *lp, int row, int column, REAL value);

   int set_obj_fn(lprec *lp, REAL *row);

   int str_set_obj_fn(lprec *lp, char *row);

   int add_constraint(lprec *lp, REAL *row, short constr_type, REAL rh);

   int str_add_constraint(lprec *lp, char *row_string ,short constr_type,
                          REAL rh);

   int add_lag_con(lprec *lp, REAL *row, short con_type, REAL rhs);

   int str_add_lag_con(lprec *lp, char *row, short con_type, REAL rhs);

   int add_column(lprec *lp, REAL *column);

   int str_add_column(lprec *lp, char *col_string);

   int str_set_rh_vec(lprec *lp, char *rh_string);

   int set_col_name(lprec *lp, int column, char *new_name);

   int write_MPS(lprec *lp, FILE *output);

   int write_LP(lprec *lp, FILE *output);

- write_MPS, write_mps is enhanced. The COLUMNS, RHS, RANGES sections now also use
  columns 40-47 and 50-61 to write the data. This results in smaller MPS files.
  The routines also write SOS and SC data.

Changes for 4.0.1.0

- Added in each header file (*.h) a condition so that each file is parsed only once.
  Some compilers give errors otherwise.

- Renamed structure hashtable to hashstruct. This because some compilers give errors
  because this name is already used in one of its header files.

- lookup of matrix elements is now considerably faster thanks to a binary search
  algorithm. This affects set_matrix(), get_mat_raw(), get_mat()
  Especially for larger problems the effect should be considerable.

- Following routines now return an integer value instead of void to indicate if they
  succeeded or not. return value FALSE is failure and TRUE is success:
  del_constraint(), del_column(), set_upbo(), set_lowbo(), set_bounds(),
  set_uprange(), set_lowrange(), set_int(), set_semicont(), set_rh(), set_rh_range(),
  set_constr_type(), get_row(), get_column(), mult_column(), get_reduced_costs()

- Following new routines are added to allow to access data without having to access
  the lprec structure. This makes it less release dependent and certainly less
  language dependent. It is advised to use these routine as much as possible and
  only to read/write in the lprec structure when nothing else is possible:
  set_verbose(), get_verbose(), set_timeout(), put_abortfunc(), put_logfunc(),
  put_msgfunc(), set_print_duals, is_print_duals(), set_print_sol(), is_print_sol(),
  set_debug(), is_debug(), set_print_at_invert(), is_print_at_invert(), set_trace(),
  is_trace(), set_anti_degen(), is_anti_degen(), set_do_presolve(), is_do_presolve(),
  set_max_num_inv(), get_max_num_inv(), set_bb_rule(), get_bb_rule(), set_obj_bound(),
  get_obj_bound(), set_floor_first(), get_floor_first(), set_infinite(),
  get_infinite(), set_epsilon(), get_epsilon(), set_epsb(), get_epsb(), set_epsd(),
  get_epsd(), set_epsel(), get_epsel(), set_scalemode(), get_scalemode(),
  set_improve(), is_improve(), set_lag_trace(), is_lag_trace(), set_piv_rule(),
  get_piv_rule(), set_break_at_first(), is_break_at_first(), set_bb_floorfirst(),
  is_bb_floorfirst(), set_break_at_value(), get_break_at_value(), set_negrange(),
  get_negrange(), set_epsperturb(), get_epsperturb(), set_epspivot(), get_epspivot(),
  get_max_level(), get_total_nodes(), get_total_iter(), get_objective(), get_Nrows(),
  get_Ncolumns(), get_variables(), get_ptr_variables(), get_constraints(),
  get_ptr_constraints(), get_sensitivity_rhs(), get_ptr_sensitivity_rhs(),
  get_sensitivity_obj(), get_ptr_sensitivity_obj()
  Note that routines get_variables(), get_constraints(), get_sensitivity_rhs(),
  get_sensitivity_obj() return with a copy of the values and that the provided
  variable arrays must already be allocated. These routines are especially mend
  to be called from other languages via a dll. When the library is called from
  C, then the get_ptr_ routines will be preferred by most users since they don't
  need extra memory. They just return a pointer.

- With the routines set_timeout(), get_timeout() it is possible to set a timeout
  in seconds. This makes it possible to interrupt a calculation after a specific
  time.

- With the routine put_abortfunc it is possible to set a abort routine. This routine
  will be called frequently. The user can add any logic he wants in this routine
  and its return value determines if the process should be aborted or not. The normal
  return value of this routine must be 0 and to abort <> 0.

- set_upbo(), set_lowbo(), set_bounds(), set_uprange(), set_lowrange() no longer
  complains about setting bounds smaller than the lower bound or larger than the upper
  bound. The values are just accepted. However when the model is optimised, the
  isvalid() routine is called and there the bounds are checked. If there is a lower
  bound larger than its upper bound then this is reported there and the model is not
  optimised.
  Another change is that the routines also accept and apply bounds that are less
  restrictive then previous set bounds. Previously these new bounds were ignored.
  Ifthe old behaviour is still needed then the caller must check this.
  This change allows to temporary set incorrect bounds.

- lp_solve.1 is updated.

- Changed demo.c and lp_solve.c to use new routines on places where lpstruct
  structure was accessed. This makes them less release dependent.

- When compiled as a windows DLL, following routines are now also available:
  set_verbose(), get_verbose(), set_timeout(), get_timeout(), set_print_duals(),
  is_print_duals(), set_print_sol(), is_print_sol(), set_debug(), is_debug(),
  set_print_at_invert(), is_print_at_invert(), set_trace(), is_trace(),
  set_anti_degen(), is_anti_degen(), set_do_presolve(), is_do_presolve(),
  set_bb_rule(), get_bb_rule(), set_obj_bound(), get_obj_bound(), set_floor_first(),
  get_floor_first(), set_infinite(), get_infinite(), set_epsilon(), get_epsilon(),
  set_epsb(), get_epsb(), set_epsd(), get_epsd(), set_epsel(), get_epsel(),
  set_scalemode(), get_scalemode(), set_improve(), is_improve(), set_lag_trace(),
  is_lag_trace(), set_piv_rule(), get_piv_rule(), set_break_at_first(),
  is_break_at_first(), set_bb_floorfirst(), is_bb_floorfirst(), set_break_at_value(),
  get_break_at_value(), set_negrange(), get_negrange(), set_epsperturb(),
  get_epsperturb(), set_epspivot(), get_epspivot(), get_max_level(),
  get_total_nodes(), get_total_iter(), get_objective(), get_variables(),
  get_constraints(), get_Nrows(), get_Ncolumns(), put_abortfunc(), put_logfunc(),
  put_msgfunc()

Changes for 4.0.1.1

- Added a new option to lp_solve: -timeout <sec>
  This option needs an extra argument (sec). It specifies the number of seconds before
  lp_solve times out. If no solution is found before this time the solver stops with
  return code Timeout.

- Fixed some problems in presolve module.

- Fixed a problem with copy_lp routine.

- set_bounds routine was not available in dll; Fixed.

- Read MPS model. Allows now an empty line in the MPS file. Some models are formulated
  with empty lines (ex netlib files)

- Fixed crash when presolve was done, but no scaling

- -p options of lp_solve didn't work anymore.

- When scaling was in effect, write_lp() and write_LP() wrote the wrong (ie scaled)
  values for the RHS, ranges and bounds. Fixed.

- Changed auto_scale. In the past auto_scale had to be for Numerical range-based scaling
  and Geometric scaling. For Curtis-reid scaling, the function scaleCR had to be called.
  This is now changed. You can always call auto_scale and depending on scalemode it
  performs the required scaling.

- lp_solve required that the -sp, -sl and -si options came after the -s <mode> option.
  This is no longer so. These options may now precde the -s <mode> option.

- There was a problem when an lp-model was read (read_lp()) and there was a row with only
  one variable in. In that case the internal rowcount was wrong resulting in writing to
  unallocated memory. The model was also build wrong. This is now fixed. Note that lp.y
  was changed for this. So lp.c must be rebuild!
  This problem did not occur when the model was read from an mps file or when build via
  the api calls.

- Update NETLIB_RESULTS and MIPLIB_RESULTS for version 4. Several more models can be solved
  with version 4 in comparison to version 3!

- set_row_name, get_row_name, set_column_name, get_column_name routines did not check if
  specified row/column was a correct value. An incorrect value could result in writing to
  unallocated space with possible dramatic results. Now the routines check this and if
  not within bounds then they return FALSE (0)

- get_rh routine did not check if specified row was a correct value. An incorrect value
  could result in reading from unallocated space with possible dramatic results. Now the
  routine check this and if not within bounds it returns then they return the value 0.0

- Added new enums to lpsolve.bas

- Added read_lp that is the replacement for read_lp_file. This to be consequent with
  read_LP, read_mps, read_MPS. To be backwards compatible added
  #define read_lp_file read_lp
  It is advised to use read_lp from now on (or read_LP which is probably handier).

- Deleted the trailing ; after the define IMPROVE_FULL in lpkit.h

- Added routine get_lp_name to get the name of the model.

- Negative bounds on variables were not accepted in lp format. This is now solved.

- Corrected a problem in routine column_in_lp().

- Added routine log_file. Is an easier way to specify a log file for messages that are
  reported. Especially for VB users much easier than put_logfunc since no callback
  routine must be provided. Messages are written in the provided file.

- Added routines set_mip_gap() and get_mip_gap(). set_mip_gap() allows to set a MIP gap
  which specifies a tolerance for the branch and bound algorithm. This tolerance is the
  difference between the best found solution yet and the current solution. If the
  difference is smaller than this tolerance then the solution (and all the sub-solutions)
  is rejected. This can result in faster solving times, but results in a solution which
  is not the perfect solution. So be careful with this tolerance.

- Renamed some enums in the VB module lpsolve.bas
    Added lpsolve_ before the names to be sure that they are unique.

- Added new enums in the VB module lpsolve.bas
    lpsolve_scales, lpsolve_improves, lpsolve_BBstrategies

- Added forgotten routines in the VB module lpsolve.bas
    lpsolve_get_lp_name, lpsolve_put_logfunc

- In the VB module lpsolve.bas, changed Sub lpsolve_Init to a Function. This function now
  returns TRUE if lpsolve.dll can be found in the specified directory or not. That way it
  is possible to disable features in the program if the dll is not available. No error is
  generated if the dll can not be found. See the example in module1.bas for its usage.

Changes for 4.0.1.2

- When a column/row is deleted, its name was not deleted. If then a new column/row was
  added, it got the name of the previously deleted column/row instead of no name. Fixed.

- When a lp-model is read, some memory was not freed. This problem only occurs if lex.y
  is parsed by flex. Not if lex is used. The change should only affect flex.
  Note that this is a bit tricky since this seems not very well documented. The change is
  in lp.y
  There is a new routine yy_delete_allocated_memory(). If you have any problems to get
  it compiled, see the remarks in this routine.
  See http://groups.google.be/groups?hl=nl&lr=&ie=UTF-8&oe=UTF-8&th=82758f176e264166&rnum=7

- When a variable had a negative value (because of a negative bound), or the upper bound
  was equal to the lower bound, then the reduced cost (dual value) was not calculated.
  Also the ranges were not calculated when the variable had a negative value. Fixed.

- Some SOS models gave not the optimal value. Corrected.

- Routines set_print_duals() and is_print_duals() no longer exist. If you want the duals
  to be printed, call routine print_duals(). The member print_duals also no longer exists
  in the lprec structure.

- Routine is_improve() is renamed to get_improve().

- routine read_mps() treated MI and PL bounds not 100% correct.
  For MI variables, it did set the upper bound to 0 instead of leaving it to its already
  set value.
  For PL variables, it did not set the upper bound to infinity. If went only wrong if
  there was already set an upper bound on this variable.

- In some cases, a variable must be split in two. A positive part and a negative part. This
  only happens when a variable can become negative. This will not happen by default since
  there is an implicit lower bound of 0 on all variables. So an explicit negative lower
  bound must be set on a variable to have a split.
  Several things are improved/correct concerning splitting:
   - Spit variables were also shown to the user. The name of such a automatically generated
     variable is __AntiBodyOf(x)__. This is no longer the case. The user does not have any
     information on there variables. So they are hidden now in the print_* functions.
     This affect print_solution(), print_duals(), print_scales().
     Also write_lp(), write_LP(), write_mps() and write_MPS() no longer write the split
     variables.
   - lp->orig_columns is deleted from the lprec structure. It isn't used anymore.
   - A new item is added to the lprec structure: splitnegvars.
     It can be set via routine set_splitnegvars() and read via get_splitnegvars().
     It can have the value AUTOMATIC or TRUE. If set on AUTOMATIC, lp_solve only creates a
     split variable when absolutely needed. That is when the variable is free bounded
     (lower bound -infinite and upper bound +infinite). In all other cases the variable is
     not split, even when negative upper or lower bounds are set. Instead a transformation
     of the bounds is done to a positive var. After the solve this transformation is undone
     again. So the user never sees this. This is the default setting.
     When it is set on TRUE, splits are done as in previous versions of lpsolve. In that case
     splits occur more often, but also only when there is some negative upper or lower bound.
     The algorithm will perform better if no splits must be done since the solving time
     increases if there are more variables. So to default setting of AUTOMATIC should normally
     always be used.
   - set_mat() function now also sets the value in the split column. Before this was not done
     resulting in wrong results when a restart was done.
   - add_column() function first deletes all added split columns. This to guarantee that split
     columns are always at the end.
   - del_column() function now also deletes added split column. Previously the split column
     stayed in the lp, which could result in bad results.
   - Added a test in set_negrange(). If provided negrange value is positive, 0 is taken.
   - When variables were split, and a restart was done, things went wrong. The model was
     corrupted. This because preprocess was not working good on split vars. This is corrected.
   - The dual values and their sensitivity were not always correct on split variables. Corrected.
   - If a lower bound of -infinity was set, then write_lp(), write_LP(), write_mps() and write_MPS()
     wrote wrong values for this bound. When an mps file was written, no MI bound was generated in
     this case.
   - read_mps(), read_MPS(). When the mps file contained a MI bound (-infinity range) AFTER an
     upper bound on this variable, then the upper bound was ignored.
   - postprocess was not done in some cases (no valid model, no solution, ...) which resulted in a
     corrupted model so that a restart gave wrong results.

Changes for 4.0.1.3

- Deleted routines set_bb_floorfirst(), is_bb_floorfirst() and member bb_floorfirst of lprec structure.
  It was not used. set_floor_first(), is_floor_first() and member floor_first are the correct names.

- When an mps file contained an extra carridge return or linefeed, the file could not be read.Corrected.

- When numbers in an mps file contained spaces, then they were not read correctly. Corrected.

- Improved SOS optimisation. It's now faster and can solve more models.

- New routine set_var_branch/get_var_branch gives the ability to specify a branch mode per integer column.

- New routine set_varweights gives the ability to specify priorities on variables.

- New routines get_lambda and get_ptr_labda added to retrieve lambda values of the Lagrange optimization.

- New routine get_Lrows returns number of Lagrangian rows.

- lp_solve now also returns the dual information of variables on a lower bound of zero.

- mps2lp now checks if mps format didn't contain any type of restrictions which can not be written
  in the lp format. For example semi-continuous variables and SOS variables.

- get_Nrows and get_Ncolumns functions didn't return the number of rows/columns if no valid base was
  present.

- set_floor_first, get_floor_first has now different constants: BRANCH_CEILING, BRANCH_FLOOR, BRANCH_AUTOMATIC.
  FALSE, TRUE, AUTOMATIC are still supported.

- Added new options -o and -f to lp_solve.
  -o option specifies a value to stop the branch-and-bound algorithm when the object value is better than the
     given value.
  -f options specifies to stop the branch-and-bound algorithm at first found solution.

- Added new options -epsd and -epsb to lp_solve to specify a tolerance for reduced costs and RHS.

- Added a test/demo project for VB.NET

- Routine put_msgfunc has an extra argument mask which allows you to specify what messages are reported.

Changes for 4.0.1.4

- Routines get_ptr_constraints, get_ptr_lambda, get_ptr_sensitivity_obj, get_ptr_sensitivity_rhs,
  get_ptr_variables are now also available in the windows dll lp_solve.dll
- Modified lpkit.h header file so that the windows dll can also be called from C.
  Include lpdll.h in the project instead of lpkit.h. There is now also a C demo example.
- make test didn't reported all different results. corrected

Changes for 4.0.1.5

- add_column, str_add_column considerly made faster when there are *lots* of columns.
- set_mat, set_matrix considerly made faster when there are *lots* of columns and values are set
  column by column.
- When an mps file is read, an error occured when there is a bound set, but no variables are
  defined in the COLUMNS section. Fixed.
- When the model was read from an lp file then an empty objective function was not accepted if there
  are no constraints. Fixed.
- lp_solve now accepts models without constraints. It is possible to construct models with variables
  with only lower and/or upper bounds. These models are not very common or practical, but beginners
  seem to start these kind of models and have problems with the fact that lp_solve would not handle them.
- Added an install option to the Makefile. make install will copy the lp_solve file to the proper
  directories automatically.

Changes for 4.0.1.6

- demo program did not release memory (via delete_lp). Fixed.
- added two new functions:
   get_orig_index: Returns the original row/column where a constraint/variable was before presolve
   get_lp_index: Returns the index in the lp of the original row/column
- added functions get_primal_solution, get_ptr_primal_solution
   They return the solution of the model
   (objective value + values of the constraints + values of the variables)
- added functions get_Norig_rows, get_Norig_columns. They return the original number of rows/columns
  before a presolve was done.
- added function get_ptr_reduced_costs. Is analog to get_reduced_costs, but returns a pointer to an
  already created variable by lp_solve.
- added new functions set_bounds_tighter, get_bounds_tighter
  Specifies if set bounds may only be tighter or also less restrictive
- added function get_varpriority
  Returns, for the specified variable, the priority the variable has in the branch-and-bound algorithm.
- Improved the SC/SOS logic. Got another solution time improvement and more models can be solved.
- compilation failed if CHECK was defined (error on Warn_count). Fixed.
- When an integer solution is found that is equal to the real solution, then the B&B is stopped
  now since there can be now better solution. This can improve performance considerably in some
  cases.
- B&B options break-at-first and break-at-value did not stop immediately. Fixed. A solution is
  now faster found in most cases when these options are active.
- set_infinite did not work properly. Corrected.
- get_basis/set_basis dit not work properly. Corrected.
- added option -epsel to lp_solve command to be able to set epsel tolerance.

Changes for 4.0.1.7
- fixed some compiler warnings
- changed some tolerance to minimize
  'An attempt was made to divide by zero'
  'Trying to recover. Reinverting Eta'
  'Inverting failed'
  messages when the model is infeasible.
- when the model is read from lp-format and a new bound is set to a variable which had already
  a bound that is equal to the new bound resulted in a warning about it will be ignored.
  This warning should not occur in this case. Fixed.
- When the model is read from lp-format and conflicting bound was detected (for example
  a minimum larger than a maximum), then lp_solve generated a core dump on some platforms.
- sometimes when read_lp was used more than once in the same instance, a core dump/memory
  protection error occured.
- serious bug in add_constraint introduced in version 4.0.1.5. matrix got corrupted. Solved.

Changes for 4.0.1.8
- added option -piv to lp_solve executable to choose pivot rule
- added option -timeoutok to lp_solve executable. This option means that if the timeout option
  is used and a timeout occurs in a MIP model and an integer solution is found within this
  timeout that this is accepted as a good solution.
- added anti-cycling code for degenerate models that cycle and thus made lp_solve hang.
  This anti-cycling code is automatic, so no option must be set to enable this.
- Corrected a small internal problem in lp_solve such that lp->rhs[0] did not corresponded to the
  objective value function.
- Corrected problems with pivot rule FIRST_SELECT (used for anti-cycling).

Changes for 4.0.1.9
- functions set_bounds_tighter/get_bounds_tighter were not in the windows dll. Corrected.
- functions write_MPS/write_mps sometimes (especially under Windows) created an MPS file that
  did not conform to the standard. Small negative numbers were longer than the allowed
  12 characters which shifted the rest of the line to the right and thus makes the file
  incorrect. Corrected.
- added routines get_ptr_work_solution, get_work_solution.
- made reading of lp-formatted file considerly faster. The larger the model, the more performance
  gain.
- a range of 0 in the RANGES section in a MPS file was ignored. Corrected.
- If a row has all-zero coefficients, then write_LP wrote this row like r_1: < 5;
  which is considered as a range by lp_solve, but because there is no other definition
  on this row, it is an illegal line. Now a variable with 0 coefficient is written to solve
  this. Like r_1: 0 v1_1 < 5;
- On some platforms a redeclaration of yytext occured which is not equal. Some platform generated
  an error. Fixed.
- Added makefile of AIX (Makefile.AIX)
- In some very rare circumstances lp_solve didn't return a solution that not furfilled all restrictions.
  Fixed.
- Modified the code such that fortify.h, ufortify.h, declare.h are not needed when lpdll.h or lpkit.h
  is included in your own source code. These include files are only needed for debugging purposes of
  lp_solve, not by users that use lp_solve however in the past these files were always required.
  Now only lpdll.h, hash.h, lpkit.h are required as include files.

Changes for 4.0.1.10
- It is now allowed to put spaces between min/max and the colon (:). Also the words may also be
  minimise, minimize, maximise, maximize.
- When scaling was done on a model without rows, the routine scale() returned an invalid floating point
  number with possible strange effects in the calling program (ex VB).
- The lp-format now supports semi-continuous variables. This is in a new section analog to the int
  section, but called sec or semi-continuous or semi or semis.
- write_mps routine now checks if there are no variables with names longer than 8 characters that
  conflicts with each other and if so, lp_solve's variable names are used which are normally shorter
  than 8 characters.
- If there is no lower bound set on a semi-continuous variables then the default of 1 is taken.
  Before it was 0, which is not consistent with documentations.
- There was an error in the semi-continuous solver when these variables were also integer. Fixed.
- A protection error occured when scaling was done, then unscaling and then add a constraint or a
  column. Fixed.
- In some rare circumstances, when a matrix value is changed after a solve (set_mat) and then a new
  solve is done, the solve hangs. Solved.
- SOSx with x > 3 did not work. Fixed.

Changes for 4.0.1.11
- Revised the lp-parser because there were some serious warnings (conflicts) when compiled with yacc/bison.
  The new code gives now warnings anymore.
- The lp-format now supports Special Ordered Sets (SOS). See the lp_solve help file for an explanation.
- The lp-format now supports the INF constant.
- lp2mps now shows all warnings when reading the input file.
- The mps format requires that all variables in the COLUMNS section are consecutively. lp_solve didn't
  check this. When this occured, a solution was given that is not correct. Now lp_solve doesn't accept
  this wrong input file anymore.
- The mps reader now also accepts mps input files where the column name isn't repeated each time, but
  a blank is used to indicate that it is the same variable are before.
- The lp-format now accepts restrictions in the form of
   min < constraint < max
           or
   max > constraint > min

  min and max must be constants
- The lp_solve html help manual has several new valuable entries like a description of integer variables,
  semi-continious variables, special ordered sets (SOS), sensitivity...
- mps2lp now has an option -max to change the default objective function from the mps format from
  minimize to maximize.
- write_lp and write_mps now write more significant digits of the floating point numbers.
  Before the precision was very limited which resulted in loss of accuracy.
- On UNIX/LINUX, lp files may now also have the cr lf (0d0a) character combination for newlines instead
  of just a linefeed.
- When the SOS weights were not incremental, the model was interpreted wrong. Corrected.
- make test or gmake test to check lp_solve with the provided examples sometimes gave differences, not
  because the build was unsuccessfull, but because of platform differences. Fixed.
- Source files are again in UNIX format. This is no problem under windows because the Microsoft visual C
  compiler and development environment accepts also UNIX formatted files, but MSDOS formatted files are
  not accepted by all UNIX/LINUX systems.
- When an lp model was read (via read_lp) and a syntax error was detected, then a SIGABRT signal was send
  to the application to stop it. This is not a good approach when lp_solve is used as a library (dll,
  linked to application). Now this isn't done anymore. read_lp now returns NULL to indicate that the
  model could not be read. It is up to the caller to handle this situation.
  As a consequence, the option -v0 (CRITICALSTOP) isn't listed anymore in the lp_solve usage because it
  isn't used anymore. Use -v1 (CRITICAL) instead. However -v0 is still accepted. It is treated as -v1.
- When an lp model was read (via read_lp) and a syntax error was detected, not all allocated memory
  was freeed. Fixed.
- The lp-format now supports the C++ one-line comment //
- There is no default Makefile anymore. Each platform has its own makefile called Makefile.x
  To generate the binaries give (g)make -f makefile.platform
- lpglob.h doesn't exist anymore
- When compiled with Microsoft .NET, with compiler optimization, the optimization sometimes hanged
  because of a compiler optimization bug. Code was changed so that bug doesn't occur.
- The dll did not contain the routines get_lowbo(), get_upbo(), get_bounds(). Fixed
- Removed all global variables from the lp parser.
  Finally, there are no global variables anymore in lp_solve. This makes is completely reentrant.
- Changed lp parser code so that it is possible now to add another parser that also uses yacc & lex
  Before this was not possible because link error would occur in that case because of double defined
  yacc symbols like yyparse, yylineno, ...
- Changed MALLOC, CALLOC, REALLOC, MALLOCCOPY code so that the code also compiles with a pure C++ compiler.
- In some very special cases, Curtis Reid scaling could result in a divition by zero. Fixed.
