# The SIMUS tutorial¶

**SIMUS** (*Sequential Interactive Model for Urban Systems*)

Is a tool to aid decision-making problems with multiple objectives. The method solves successive scenarios formulated as linear programs. For each scenario, the decision-maker must choose the criterion to be considered objective while the remaining restrictions constitute the constrains system that the projects are subject to. In each case, if there is a feasible solution that is optimum, it is recorded in a matrix of efficient results. Then, from this matrix two rankings allow the decision maker to compare results obtained by different procedures. The first ranking is obtained through a linear weighting of each column by a factor - equivalent of establishing a weight - and that measures the participation of the corresponding project. In the second ranking, the method uses dominance and subordinate relationships between projects, concepts from the French school of MCDM.

## The Case: Land rehabilitation¶

An important port city has been affected by the change in the modality of maritime transport, since the start of containers transport in the mid-20th century. The city was left with 39 hectares of empty docks, warehouses and a railway terminal.

Three projects was developed to decide what to do with this places

**Project 1:**Corporate towers - Hotels - Navy Base - Small park**Project 2:**Habitational towers - Comercial Center in the old Railway terminal.**Project 3:**Convention center - Big park and recreational area.

The criteria for the analysis of proposals are:

- New jobs positions (
**jobs**).

- Green spaces (
**green**) - Financial feasibility (
**fin**) - Environmental impact (
**env**)

Only for the 2nd criteria a maximun limit pf \(500\) are provided. El Decisor considera a los cuatro criterios como objetivos, por lo que se deberán resolver cuatro programas lineales con tres restricciones cada uno. The data are provided in the next table:

Criteria | Project 1 | Project 2 | Project 3 | Right side value | Optimal Sense |
---|---|---|---|---|---|

jobs | 250 | 130 | 350 | Maximize | |

green | 120 | 200 | 340 | 500 | Maximize |

fin | 20 | 40 | 15 | Maximize | |

env | 800 | 1000 | 600 | Maximize |

### Data input¶

We can create a `skcriteria.Data`

object with all this information
(except the limits):

**Note:**SIMUS uses the alternatives as columns and the criteria as rows; but in

*scikit-criteria*is the oposite, so expect to see the previous table transposed.

```
In [1]:
```

```
# first lets import the DATA class
from skcriteria import Data
data = Data(
# the alternative matrix
mtx=[[250, 120, 20, 800],
[130, 200, 40, 1000],
[350, 340, 15, 600]],
# optimal sense
criteria=[max, max, min, max],
# names of alternatives and criteria
anames=["Prj 1", "Prj 2", "Prj 3"],
cnames=["jobs", "green", "fin", "env"])
# show the data object
data
```

```
Out[1]:
```

ALT./CRIT. | jobs (max) | green (max) | fin (min) | env (max) |
---|---|---|---|---|

Prj 1 | 250 | 120 | 20 | 800 |

Prj 2 | 130 | 200 | 40 | 1000 |

Prj 3 | 350 | 340 | 15 | 600 |

### Create the model¶

```
In [2]:
```

```
# import the class
from skcriteria.madm.simus import SIMUS
# create the new simus and
dm = SIMUS()
```

By default the call `SIMUS()`

create a solver that internally uses the
PuLP solver to solve the linear
programs. Other availables solvers are:

`SUMUS(solver='glpk')`

for the GNU Linear programming toolkit`SUMUS(solver='gurobi')`

to use Gurobi Optimizer`SUMUS(solver='cplex')`

for IBM ILOG CPLEX Optimization Studio

**Note:**The check the full list of available optimizers are stored in

`skcriteria.utils.lp.SOLVERS`

.Also the `njobs`

parameters determines how many cores the user want to
use to run the linear programs. For example `SIMUS(njobs=2)`

uses up
to two cores. (By default all CPUs are used).

Also the last (and most important) parameter is `rank_by`

(default is
1): determines which of the two ranks methods executed by SIMUS is the
one that determines the final ranking. If the experiment is consistent,
the two methos *must* detemines the *same* ranking (Please check the
paper
for more details).

### Solve the problem¶

This is achived by calling the method `decide()`

of the decision maker
object (`dm`

)

```
In [3]:
```

```
# store the decision inside the dec variable
dec = dm.decide(data, b=[None, 500, None, None])
# let's see the decision
dec
```

```
Out[3]:
```

**SIMUS (mnorm=none, wnorm=none) - Solution:**

ALT./CRIT. | jobs (max) | green (max) | fin (min) | env (max) | Rank |
---|---|---|---|---|---|

Prj 1 | 250 | 120 | 20 | 800 | 3 |

Prj 2 | 130 | 200 | 40 | 1000 | 2 |

Prj 3 | 350 | 340 | 15 | 600 | 1 |

If you check the last column the raking is:

- Project 3

- Project 2
- Project 1

### Analysis¶

Most of the “intermediate” data of the SIMUS method are stored in the
`e_`

field of the decision object `dec`

.

```
In [4]:
```

```
dec.e_
```

```
Out[4]:
```

```
Extra(rank_by, solver, stages, stage_results, points1, points2, tita_j_p, tita_j_d, doms, dom_by_crit)
```

for example the attribute `stages`

stores all the Linear programs
executed by SIMUS:

```
In [5]:
```

```
dec._e.stages
```

```
Out[5]:
```

```
[no-name:
MAXIMIZE
250*x0 + 130*x1 + 350*x2 + 0
SUBJECT TO
_C1: 120 x0 + 200 x1 + 340 x2 <= 500
_C2: 20 x0 + 40 x1 + 15 x2 >= 15
_C3: 800 x0 + 1000 x1 + 600 x2 <= 1000
VARIABLES
x0 Continuous
x1 Continuous
x2 Continuous, no-name:
MAXIMIZE
120*x0 + 200*x1 + 340*x2 + 0
SUBJECT TO
_C1: 250 x0 + 130 x1 + 350 x2 <= 350
_C2: 20 x0 + 40 x1 + 15 x2 >= 15
_C3: 800 x0 + 1000 x1 + 600 x2 <= 1000
VARIABLES
x0 Continuous
x1 Continuous
x2 Continuous, no-name:
MINIMIZE
20*x0 + 40*x1 + 15*x2 + 0
SUBJECT TO
_C1: 250 x0 + 130 x1 + 350 x2 <= 350
_C2: 120 x0 + 200 x1 + 340 x2 <= 500
_C3: 800 x0 + 1000 x1 + 600 x2 <= 1000
VARIABLES
x0 Continuous
x1 Continuous
x2 Continuous, no-name:
MAXIMIZE
800*x0 + 1000*x1 + 600*x2 + 0
SUBJECT TO
_C1: 250 x0 + 130 x1 + 350 x2 <= 350
_C2: 120 x0 + 200 x1 + 340 x2 <= 500
_C3: 20 x0 + 40 x1 + 15 x2 >= 15
VARIABLES
x0 Continuous
x1 Continuous
x2 Continuous]
```

The attribute `stages_results`

stores the *eficients restults
normalized matrix*

```
In [6]:
```

```
dec.e_.stage_results
```

```
Out[6]:
```

```
array([[0.125 , 0. , 0.875 ],
[0. , 0.38888889, 0.61111111],
[0. , 0. , 0. ],
[0.05681818, 0.94318182, 0. ]])
```

## References¶

Munier, N., Carignano, C., & Alberto, C. UN MÉTODO DE PROGRAMACIÓN MULTIOBJETIVO. Revista de la Escuela de Perfeccionamiento en Investigación Operativa, 24(39).