Zimpl

Zimpl is a language to translate the mathematical model of a problem into a linear or (mixed-) integer mathematical program expressed in .lp or .mps file format which can be read and (hopefully) solved by a LP or MIP solver.

See http://www.zib.de/koch/zimpl/ for the home page of this tool and examples.

On the above page, a command line tool is provided to read a model written in the Zimpl language and it creates a CPLEX lp file. lp_solve is able to read this generated CPLEX lp file via the xli_CPLEX XLI driver, but that would require an extra step.
lp_solve can read/write and solve these Zimpl models directly via the xli_Zimpl XLI driver (see External Language Interfaces). It reads such a model in above format and can solve it then.
Also note that the XLI driver depends on an external dll: zlib1.dll. When it cannot be found on the system, an appropriate message will be given. This dll must be in a directory specified by the Path environment variable. A common place is c:\windows\system32. The dll is distributed with the package. The latest version can be found at http://www.zlib.net/

For example:

lp_solve -rxli xli_Zimpl chvatal_diet.zpl

This gives as result:

Value of objective function: 97

Actual values of the variables:
x$Oatmeal                       4
x$Chicken                       0
x$Eggs                          0
x$Milk                          5
x$Pie                           2
x$Pork                          0

Options

The XLI accepts several options:

  -b             Enable Bison (Lex parser) debugging output.
  -D name=value  Sets the parameter name to the specified value.
                 This is equivalent with having this line in the ZIMPL program: param name:=val.
  -f             enable flex debugging output.
  -n cm|cn|cf    name column make/name/full
  -O             Try to reduce the generated LP by doing some presolve analysis.
  -s seed        Positive seed number for the random number generator.
  -v[0-5]        Set the verbosity level. 0 is quiet, 1 is default, 2 is verbose, 3 and 4 are chatter, and 5 is debug.
  -V             show version info

These options are the same as the stand-alone zimpl program.

The lp_solve command line program can provide these parameters via the -rxliopt argument.

For example:

lp_solve -rxli xli_Zimpl chvatal_diet.zpl -rxliopt "-v0 -O"

Generating ZIMPL models

The XLI can also create a ZIMPL model, however it doesn't use the strength of the language. Constraints are written out line per line. But it can be a starter. For example:

lp_solve model.lp -wxli xli_Zimpl model.zpl

This gives as model.zpl:

# Variable definitions
var x >= 0;
var y >= 0;

# Objective function
maximize obj: +143*x +60*y;

# Constraints
subto R1: +120*x +210*y <= 15000;
subto R2: +110*x +30*y <= 4000;
subto R3: +x +y <= 75;

API

Use the lpsolve API call read_XLI to read a model and write_XLI to write a model. See also External Language Interfaces.

IDE

Also from within the IDE, this XLI can be used. However, some entries must be added in LpSolveIDE.ini (in the folder where the IDE is installed).

In the [XLI] section the following must be added:

lib5=xli_ZIMPL

And a new section for the ZIMPL XLI must also be added:

[xli_ZIMPL]
extension=.zpl
language=ZIMPL

Then make sure that the xli_ZIMPL.dll is available for the IDE. This must be done by placing this dll in the IDE folder or in the Windows system32 folder.

Example models

chvatal_diet.zpl
# $Id: chvatal_diet.zpl,v 1.2 2003/10/02 08:20:12 bzfkocht Exp $
#
# From V. Chvatal: Linear Programming
# Chapter 1, Page 3ff.
#
# A diet problem
#
set Food      := { "Oatmeal", "Chicken", "Eggs", "Milk", "Pie", "Pork" };
set Nutrients := { "Energy", "Protein", "Calcium" };
set Attr      := Nutrients + {"Servings", "Price"};

param needed[Nutrients] := <"Energy"> 2000, <"Protein"> 55, <"Calcium"> 800;

param data[Food * Attr] :=
           | "Servings", "Energy", "Protein", "Calcium", "Price" |
|"Oatmeal" |         4 ,     110 ,        4 ,        2 ,      3  |
|"Chicken" |         3 ,     205 ,       32 ,       12 ,     24  |
|"Eggs"    |         2 ,     160 ,       13 ,       54 ,     13  |
|"Milk"    |         8 ,     160 ,        8 ,      284 ,      9  |
|"Pie"     |         2 ,     420 ,        4 ,       22 ,     20  |
|"Pork"    |         2 ,     260 ,       14 ,       80 ,     19  |;
#                          (kcal)        (g)        (mg)  (cents)

var x[<f> in Food] integer >= 0 <= data[f, "Servings"];

minimize cost: sum <f> in Food : data[f, "Price"] * x[f];

subto need :
  forall <n> in Nutrients do
    sum <f> in Food : data[f, n] * x[f] >= needed[n];
model.lp
/* model.lp */

max: 143 x + 60 y;

120 x + 210 y <= 15000;
110 x + 30 y <= 4000;
x + y <= 75;