# Solving your first model¶

In this section, we show you how modeling and solving your first problem: the classical knapsack problem. The knapsack problem is defined as follows: given a set of items, each with a weight and a value, determine a subset of items in such a way that their total weight is less than a given bound and their total value is as large as possible. This problem is hard to solve in theory.

## Knapsack toy model¶

Below is a LocalSolver Program (LSP) which models the following knapsack toy
instance (see `examples/toy`

): 8 items with weights 10, 60, 30, 40, 30, 20,
20, 2 and values 1, 10, 15, 40, 60, 90, 100, 15 respectively.
The total weight must not exceed 102.

```
/********** toy.lsp **********/
/* Declares the optimization model. */
function model() {
// 0-1 decisions
x_0 <- bool(); x_1 <- bool(); x_2 <- bool(); x_3 <- bool();
x_4 <- bool(); x_5 <- bool(); x_6 <- bool(); x_7 <- bool();
// weight constraint
knapsackWeight <- 10*x_0 + 60*x_1 + 30*x_2 + 40*x_3 + 30*x_4 + 20*x_5 + 20*x_6 + 2*x_7;
constraint knapsackWeight <= 102;
// maximize value
knapsackValue <- 1*x_0 + 10*x_1 + 15*x_2 + 40*x_3 + 60*x_4 + 90*x_5 + 100*x_6 + 15*x_7;
maximize knapsackValue;
}
/* Parameterizes the solver. */
function param() {
lsTimeLimit = 1;
}
```

All the variables of the model, called expressions, are declared using left
arrows `<-`

. Decision variables are introduced using the built-in function `bool()`

.
Intermediate expression can be built upon these decision variables by using other
operators or functions. For example, in the model aboce: product (`*`

),
sum (`+`

), less than or equal to (`<=`

). Many other mathematical operators are
available, allowing you to model and solve highly-nonlinear combinatorial
optimization problems. The keywords `constraint`

or `maximize`

are used for
tagging expressions as constrained or maximized.

To solve this model, call LocalSolver with the LSP file as argument.
In addition, the value of the built-in programming variable `lsTimeLimit`

is overwritten in order to limit the running time of the local-search solver to
1 second. Then, the following trace will appear in your console:

```
localsolver/examples/toy$ localsolver toy.lsp lsTimeLimit=2
LocalSolver 5.0 (Linux64, build 20141222)
Copyright (C) 2014 Innovation 24, Aix-Marseille University, CNRS.
All rights reserved (see Terms and Conditions for details).
Load toy.lsp...
Run model...
Preprocess model 100% ...
Close model 100% ...
Preprocessing transformed 3 expressions.
Run param...
Run solver...
Initialize threads 100% ...
Push initial solutions 100% ...
Model:
expressions = 27, constants = 11, operands = 50
decisions = 8, constraints = 1, objectives = 1
Param:
time limit = 2 sec, no iteration limit
seed = 0, nb threads = 2, annealing level = 1
Objectives:
Obj 0: maximize, bound = 331
Phases:
Phase 0: time limit = 2 sec, no iteration limit, optimized objective = 0
Phase 0:
[0 sec, 0 itr]: obj = (0)
[1 sec, 3031 itr]: obj = (280)
[2 sec, 68641 itr]: obj = (280)
[2 sec, 68641 itr]: obj = (280)
68641 iterations, 136816 moves performed in 2 seconds
Feasible solution: obj = (280)
```

If no time limit is set, the search will continue until you force the stop of
the program by pressing `Ctrl+C`

. The trace in console starts with the key
figures of the model: number of expressions, operands, decisions, constraints
and objectives. They are followed by the time limit with other default parameters
(number of threads, simulated annealing level, ...). The trace about objectives
and phases will be detailed later in the guide, when multiobjective optimization
will be addressed.

Once the search is finished, the total number of iterations and the total number
of moves are displayed (note that we can have more moves than iterations when
using several threads), as well as the status and the value of the best solution
found. The solution status can be `Inconsistent`

, `Infeasible`

,
`Feasible`

or `Optimal`

.

## Classical knapsack model¶

The previous model was very limited as it was not possible to solve arbitrary
knapsack without changing the whole program. To read the knaspack instances
from a formatted file, the LSP program can be modified as follows
(see `examples/knapsack`

).

```
/********** knapsack.lsp **********/
use io;
/* Reads instance data. */
function input() {
local usage = "Usage: localsolver knapsack.lsp "
+ "inFileName=inputFile [solFileName=outputFile] [lsTimeLimit=timeLimit]";
if (inFileName == nil) throw usage;
local inFile = io.openRead(inFileName);
nbItems = inFile.readInt();
weights[i in 0..nbItems-1] = inFile.readInt();
prices[i in 0..nbItems-1] = inFile.readInt();
knapsackBound = inFile.readInt();
}
/* Declares the optimization model. */
function model() {
// 0-1 decisions
x[i in 0..nbItems-1] <- bool();
// weight constraint
knapsackWeight <- sum[i in 0..nbItems-1](weights[i] * x[i]);
constraint knapsackWeight <= knapsackBound;
// maximize value
knapsackValue <- sum[i in 0..nbItems-1](prices[i] * x[i]);
maximize knapsackValue;
}
/* Parameterizes the solver. */
function param() {
if (lsTimeLimit == nil) lsTimeLimit = 20;
}
/* Writes the solution in a file */
function output() {
if(solFileName == nil) return;
local solFile = io.openWrite(solFileName);
solFile.println(knapsackValue.value);
for [i in 0..nbItems-1 : x[i].value == 1]
solFile.print(i + " ");
solFile.println();
}
```

By launching it with the following command line, you will obtain an output
similar to the previous model. Note that for more flexibility, we have defined
some of our variables in command line (`inFileName`

, `lsTimeLimit`

).

```
localsolver/examples/knapsack$ localsolver knapsack.lsp inFileName=instances/toy.in lsTimeLimit=1
```

All mathematical operators can be both used for modeling and for programming.
For instance, the statement `c <- a * b`

means that we declare a modeling
expression `c`

corresponding to the product of the modeling expressions `a`

and `b`

, while `c = a * b`

means that we assign to the programming variable
`c`

the result of the product of the programming variables `a`

and `b`

.
For n-ary operators, the n-ary functional form (for example `sum(a, b, c)`

)
allows to declare expressions with an arbitrary number of operands. When the
number of operands is fixed, the binary infix form (for example `a + b + c`

)
can also be used. For example, the statement:

```
knapsackWeight <- sum[i in 0..nbItems-1](weights[i] * x[i]);
```

declares the expression `knapsackWeight`

as the sum of the product of
expressions `weights[i]`

and `x[i]`

for all items from `0`

to `nbItems-1`

.

As explained in the introduction to LocalSolver’s modeler, a singularity of the
LSP language is to offer no `main`

function. The LSP language induces a
modeling framework composed of 5 predefined functions `input()`

, `model()`

,
`param()`

, `display()`

, `output()`

. These functions, called in this order,
induce the flow of the program launched by the LocalSolver executable:

`input`

: for declaring your data or reading them from files.`model`

: for declaring your optimization model.`param`

: for parameterizing the local-search solver before running.`display`

: for displaying some info in console or in some files during the resolution.`output`

: for writing results in console or in some files, once the resolution is finished.

These 5 predefined functions have a default implementation.
So you only have to implement and write the functions you need (at least, the function `model()`

).