Outranking algorithms

This notebook is dedicated to the use of outranking algorithms, including the different ELECTRE algorithms and Promethee algorithms.

[1]:
%matplotlib notebook
%config Completer.use_jedi = False

Electre algorithms

Outranking problem formalization

[2]:
from mcda.matrices import *
from mcda.relations import *
from mcda.scales import *
from mcda.outranking.electre import *
[3]:
#Parameters
alternatives = ["Peugeot 505 GR",
    "Opel Record 2000 LS",
    "Citroen Visa Super E",
    "VW Golf 1300 GLS",
    "Citroen CX 2400 Pallas"]
scales = {
    0: QuantitativeScale(1, 5),
    1: QuantitativeScale(1, 5),
    2: QuantitativeScale(1, 5),
    3: QuantitativeScale(1, 5),
    4: QuantitativeScale(1, 5),
    5: QuantitativeScale(1, 5),
    6: QuantitativeScale(1, 5),
}
dataset = PerformanceTable(
    [
        [4, 2, 1, 5, 2, 2, 4],
        [3, 5, 3, 5, 3, 3, 3],
        [3, 5, 3, 5, 3, 2, 2],
        [4, 2, 2, 5, 1, 1, 1],
        [4, 1, 3, 5, 4, 1, 5],
    ],
    alternatives=alternatives,
    scales=scales
)

Electre I

[4]:
W = {
    0: 0.780, 1: 1.180, 2: 1.570, 3: 3.140,
    4: 2.350, 5: 0.390, 6: 0.590}
c_hat = 0.75
d_hat = {0: 2, 1: 2, 2: 2, 3: 2, 4: 2, 5: 2, 6: 2}
[5]:
electre1 = Electre1(dataset, W, c_hat, d_hat)

concordance matrix

[6]:
electre1.concordance().data
[6]:
Peugeot 505 GR Opel Record 2000 LS Citroen Visa Super E VW Golf 1300 GLS Citroen CX 2400 Pallas
Peugeot 505 GR 1.000 0.451 0.490 0.843 0.549
Opel Record 2000 LS 0.863 1.000 1.000 0.922 0.628
Citroen Visa Super E 0.863 0.902 1.000 0.922 0.628
VW Golf 1300 GLS 0.667 0.392 0.392 1.000 0.549
Citroen CX 2400 Pallas 0.843 0.843 0.843 0.882 1.000
[7]:
dataset.scales[0] = QuantitativeScale(1, 5, preference_direction=MIN)
concordance_mat = electre1.concordance()
concordance_mat.data
[7]:
Peugeot 505 GR Opel Record 2000 LS Citroen Visa Super E VW Golf 1300 GLS Citroen CX 2400 Pallas
Peugeot 505 GR 1.000 0.373 0.412 0.843 0.549
Opel Record 2000 LS 0.941 1.000 1.000 1.000 0.706
Citroen Visa Super E 0.941 0.902 1.000 1.000 0.706
VW Golf 1300 GLS 0.667 0.314 0.314 1.000 0.549
Citroen CX 2400 Pallas 0.843 0.765 0.765 0.882 1.000

discordance matrix

[8]:
discordance_mat = electre1.discordance()
discordance_mat.criteria_matrices[0].data
[8]:
Peugeot 505 GR Opel Record 2000 LS Citroen Visa Super E VW Golf 1300 GLS Citroen CX 2400 Pallas
Peugeot 505 GR 0 1 1 0 0
Opel Record 2000 LS 0 0 0 0 0
Citroen Visa Super E 0 0 0 0 0
VW Golf 1300 GLS 0 1 1 0 0
Citroen CX 2400 Pallas 0 1 1 0 0

outranking matrix

[9]:
outranking_matrix = electre1.outranking(concordance_mat, discordance_mat)
outranking_matrix.data
[9]:
Peugeot 505 GR Opel Record 2000 LS Citroen Visa Super E VW Golf 1300 GLS Citroen CX 2400 Pallas
Peugeot 505 GR 1 0 0 1 0
Opel Record 2000 LS 1 1 1 1 0
Citroen Visa Super E 1 1 1 1 0
VW Golf 1300 GLS 0 0 0 1 0
Citroen CX 2400 Pallas 1 0 0 1 1
[10]:
PreferenceStructure.from_outranking_matrix(outranking_matrix)
[10]:
PreferenceStructure([PreferenceRelation(Citroen CX 2400 Pallas, VW Golf 1300 GLS), PreferenceRelation(Citroen CX 2400 Pallas, Peugeot 505 GR), PreferenceRelation(Opel Record 2000 LS, VW Golf 1300 GLS), PreferenceRelation(Citroen Visa Super E, VW Golf 1300 GLS), PreferenceRelation(Citroen Visa Super E, Peugeot 505 GR), PreferenceRelation(Opel Record 2000 LS, Peugeot 505 GR), IncomparableRelation(Opel Record 2000 LS, Citroen CX 2400 Pallas), IncomparableRelation(Citroen Visa Super E, Citroen CX 2400 Pallas), IndifferenceRelation(Opel Record 2000 LS, Citroen Visa Super E), PreferenceRelation(Peugeot 505 GR, VW Golf 1300 GLS)])
[11]:
PreferenceStructure.from_outranking_matrix(outranking_matrix).outranking_matrix.data
[11]:
Citroen CX 2400 Pallas Citroen Visa Super E Opel Record 2000 LS Peugeot 505 GR VW Golf 1300 GLS
Citroen CX 2400 Pallas 1 0 0 1 1
Citroen Visa Super E 0 1 1 1 1
Opel Record 2000 LS 0 1 1 1 1
Peugeot 505 GR 0 0 0 1 1
VW Golf 1300 GLS 0 0 0 0 1
[12]:
outranking_matrix.plot()
[12]:
../../_images/notebooks_examples_outranking_algorithms_17_0.svg

We can also construct the outranking matrix using the method construct:

[13]:
outranking_matrix = electre1.construct()

Exploitation

[14]:
electre1.exploit(outranking_matrix)
[14]:
['Peugeot 505 GR',
 'Opel Record 2000 LS',
 'Citroen Visa Super E',
 'VW Golf 1300 GLS',
 'Citroen CX 2400 Pallas']
[15]:
electre1.exploit(outranking_matrix, cycle_reduction=True)
[15]:
['Citroen CX 2400 Pallas', 'Opel Record 2000 LS', 'Citroen Visa Super E']
[16]:
electre1.exploit(
    outranking_matrix, cycle_reduction=True, transitivity=True
)
[16]:
['Citroen CX 2400 Pallas', 'Opel Record 2000 LS', 'Citroen Visa Super E']
[17]:
electre1.select(
    cycle_reduction=True, transitivity=True
)
[17]:
['Citroen CX 2400 Pallas', 'Opel Record 2000 LS', 'Citroen Visa Super E']

Electre II

Init

[18]:
#Parameters
alternatives = [
    "Peugeot 505 GR",
    "Opel Record 2000 LS",
    "Citroen Visa Super E",
    "VW Golf 1300 GLS",
    "Citroen CX 2400 Pallas"
]
scales = {
    0: QuantitativeScale(1, 5),
    1: QuantitativeScale(1, 5),
    2: QuantitativeScale(1, 5),
    3: QuantitativeScale(1, 5),
    4: QuantitativeScale(1, 5),
    5: QuantitativeScale(1, 5),
    6: QuantitativeScale(1, 5),
}
dataset = PerformanceTable([
        [1, 2, 1, 5, 2, 2, 4],  # a1
        [3, 5, 3, 5, 3, 3, 3],  # a2
        [3, 5, 3, 5, 3, 2, 2],  # a3
        [1, 2, 2, 5, 1, 1, 1],  # a4
        [1, 1, 3, 5, 4, 1, 5],  # a5
    ], alternatives=alternatives, scales=scales
)
W = {
    0: 0.780, 1: 1.180, 2: 1.570, 3: 3.140,
    4: 2.350, 5: 0.390, 6: 0.590
}

electre2 = Electre2(
    dataset, W, 0.65, 0.85,
    {c: 2 for c in dataset.criteria},
    {c: 1 for c in dataset.criteria}
)

concordance and discordance

First let’s compute the concordance and discordance as it done in Electre 1

[19]:
concordance_matrix = electre2.concordance()
discordance_matrix = electre2.discordance()
print(concordance_matrix.data)
discordance_matrix.criteria_matrices[0].data
                        Peugeot 505 GR  Opel Record 2000 LS  \
Peugeot 505 GR                   1.000                0.373
Opel Record 2000 LS              0.941                1.000
Citroen Visa Super E             0.941                0.902
VW Golf 1300 GLS                 0.667                0.314
Citroen CX 2400 Pallas           0.843                0.765

                        Citroen Visa Super E  VW Golf 1300 GLS  \
Peugeot 505 GR                         0.412             0.843
Opel Record 2000 LS                    1.000             1.000
Citroen Visa Super E                   1.000             1.000
VW Golf 1300 GLS                       0.314             1.000
Citroen CX 2400 Pallas                 0.765             0.882

                        Citroen CX 2400 Pallas
Peugeot 505 GR                           0.549
Opel Record 2000 LS                      0.706
Citroen Visa Super E                     0.706
VW Golf 1300 GLS                         0.549
Citroen CX 2400 Pallas                   1.000
[19]:
Peugeot 505 GR Opel Record 2000 LS Citroen Visa Super E VW Golf 1300 GLS Citroen CX 2400 Pallas
Peugeot 505 GR 0 2 2 0 0
Opel Record 2000 LS 0 0 0 0 0
Citroen Visa Super E 0 0 0 0 0
VW Golf 1300 GLS 0 2 2 0 0
Citroen CX 2400 Pallas 0 2 2 0 0
[20]:
strong_outranking = electre2.outranking(
    concordance_matrix,
    discordance_matrix
)
strong_outranking.data
[20]:
Peugeot 505 GR Opel Record 2000 LS Citroen Visa Super E VW Golf 1300 GLS Citroen CX 2400 Pallas
Peugeot 505 GR 1 0 0 0 0
Opel Record 2000 LS 1 1 1 1 0
Citroen Visa Super E 0 0 1 1 0
VW Golf 1300 GLS 0 0 0 1 0
Citroen CX 2400 Pallas 0 0 0 1 1
[21]:
weak_outranking = electre2.outranking(
    concordance_matrix,
    discordance_matrix,
    strong=False
)
weak_outranking.data
[21]:
Peugeot 505 GR Opel Record 2000 LS Citroen Visa Super E VW Golf 1300 GLS Citroen CX 2400 Pallas
Peugeot 505 GR 1 0 0 1 0
Opel Record 2000 LS 1 1 1 1 0
Citroen Visa Super E 1 0 1 1 0
VW Golf 1300 GLS 0 0 0 1 0
Citroen CX 2400 Pallas 1 0 0 1 1

You can also return both matrices directly:

[22]:
strong_outranking, weak_outranking = electre2.construct()

Distillation

Now let’s process the ascending and descending distallation

[23]:
ascending_distillate = electre2.distillation(
    strong_outranking,
    weak_outranking,
    ascending=True
)
descending_distillate = electre2.distillation(
    strong_outranking,
    weak_outranking
)
[24]:
ascending_distillate.data
[24]:
Peugeot 505 GR Opel Record 2000 LS Citroen Visa Super E VW Golf 1300 GLS Citroen CX 2400 Pallas
Peugeot 505 GR 1 0 0 1 0
Opel Record 2000 LS 1 1 1 1 1
Citroen Visa Super E 1 0 1 1 1
VW Golf 1300 GLS 0 0 0 1 0
Citroen CX 2400 Pallas 1 0 1 1 1
[25]:
ascending_distillate.plot()
[25]:
../../_images/notebooks_examples_outranking_algorithms_37_0.svg
[26]:
descending_distillate.plot()
[26]:
../../_images/notebooks_examples_outranking_algorithms_38_0.svg

final ranking

Finally, we can compute and print the final ranking

[27]:
final_rank = ascending_distillate & descending_distillate
final_rank.data
[27]:
Peugeot 505 GR Opel Record 2000 LS Citroen Visa Super E VW Golf 1300 GLS Citroen CX 2400 Pallas
Peugeot 505 GR 1 0 0 1 0
Opel Record 2000 LS 1 1 1 1 1
Citroen Visa Super E 1 0 1 1 0
VW Golf 1300 GLS 0 0 0 1 0
Citroen CX 2400 Pallas 1 0 1 1 1
[28]:
final_rank.plot()
[28]:
../../_images/notebooks_examples_outranking_algorithms_41_0.svg

We could also directly call the exploit method:

[29]:
final_rank = electre2.exploit((strong_outranking, weak_outranking))

Direct methods

We can also compute directly the electre II algorithm if nothing needs to be changed. Besides it’s possible to reduce the matrix in term of preferences for a proper graph.

[30]:
final_rank = electre2.rank()
final_rank.data
[30]:
Peugeot 505 GR Opel Record 2000 LS Citroen Visa Super E VW Golf 1300 GLS Citroen CX 2400 Pallas
Peugeot 505 GR 1 0 0 1 0
Opel Record 2000 LS 1 1 1 1 1
Citroen Visa Super E 1 0 1 1 0
VW Golf 1300 GLS 0 0 0 1 0
Citroen CX 2400 Pallas 1 0 1 1 1
[31]:
final_rank.plot()
[31]:
../../_images/notebooks_examples_outranking_algorithms_46_0.svg

Electre III

init

[32]:
alternatives = [
    "Peugeot 505 GR",
    "Opel Record 2000 LS",
    "Citroen Visa Super E",
    "VW Golf 1300 GLS",
    "Citroen CX 2400 Pallas",
    "Renault Scenic"
]
scales = {
    0: QuantitativeScale(7, 10),
    1: QuantitativeScale(7, 10),
    2: QuantitativeScale(5, 9),
    3: QuantitativeScale(6, 9),
}
dataset = PerformanceTable(
    [
        [8.84, 8.79, 6.43, 6.95],
        [8.57, 8.51, 5.47, 6.91],
        [7.76, 7.75, 5.34, 8.76],
        [7.97, 9.12, 5.93, 8.09],
        [9.03, 8.97, 8.19, 8.10],
        [7.41, 7.87, 6.77, 7.23],
    ],
    alternatives=alternatives, scales=scales
)
W = {0: 9.00, 1: 8.24, 2: 5.98, 3: 8.48}
P = {0: 0.50, 1: 0.50, 2: 0.50, 3: 0.50}
I = {0: 0.30, 1: 0.30, 2: 0.30, 3: 0.30}
V = {0: 0.70, 1: 0.70, 2: 0.70, 3: 0.70}

electre3 = Electre3(dataset, W, I, P, V)

concordance

[33]:
electre3.concordance().data
[33]:
Peugeot 505 GR Opel Record 2000 LS Citroen Visa Super E VW Golf 1300 GLS Citroen CX 2400 Pallas Renault Scenic
Peugeot 505 GR 1.000000 1.000000 0.732492 0.693502 0.543849 0.962271
Opel Record 2000 LS 0.811356 1.000000 0.732492 0.321640 0.108770 0.784606
Citroen Visa Super E 0.267508 0.456151 1.000000 0.551420 0.267508 0.811356
VW Golf 1300 GLS 0.527445 0.716088 0.732492 1.000000 0.527445 0.811356
Citroen CX 2400 Pallas 1.000000 1.000000 0.732492 1.000000 1.000000 1.000000
Renault Scenic 0.456151 0.456151 0.661514 0.188644 0.000000 1.000000

discordance

[34]:
d = electre3.discordance().data
[35]:
for i in d.index:
    for j in d.columns:
        print(d.loc[i, j].tolist())
[0, 0, 0, 0]
[0, 0, 0, 0]
[0, 0, 0, 1]
[0, 0, 0, 1]
[0, 0, 1, 1]
[0, 0, 0, 0]
[0, 0, 1, 0]
[0, 0, 0, 0]
[0, 0, 0, 1]
[0.0, 0.5499999999999973, 0.0, 1.0]
[0, 0, 1, 1]
[0, 0, 1, 0]
[1, 1, 1, 0]
[1, 1, 0, 0]
[0, 0, 0, 0]
[0.0, 1.0, 0.4499999999999994, 0.0]
[1, 1, 1, 0]
[0, 0, 1, 0]
[1, 0, 0, 0]
[0.5000000000000028, 0.0, 0.0, 0.0]
[0.0, 0.0, 0.0, 0.8499999999999999]
[0, 0, 0, 0]
[1, 0, 1, 0]
[0, 0, 1, 0]
[0, 0, 0, 0]
[0, 0, 0, 0]
[0.0, 0.0, 0.0, 0.8000000000000009]
[0, 0, 0, 0]
[0, 0, 0, 0]
[0, 0, 0, 0]
[1, 1, 0, 0]
[1.0, 0.6999999999999985, 0.0, 0.0]
[0, 0, 0, 1]
[0.2999999999999981, 1.0, 0.0, 1.0]
[1, 1, 1, 1]
[0, 0, 0, 0]

credibility

[36]:
credibility = electre3.construct()
credibility.data
[36]:
Peugeot 505 GR Opel Record 2000 LS Citroen Visa Super E VW Golf 1300 GLS Citroen CX 2400 Pallas Renault Scenic
Peugeot 505 GR 1.0 1.000000 0.000000 0.0 0.0 0.962271
Opel Record 2000 LS 0.0 1.000000 0.000000 0.0 0.0 0.000000
Citroen Visa Super E 0.0 0.000000 1.000000 0.0 0.0 0.000000
VW Golf 1300 GLS 0.0 0.716088 0.410731 1.0 0.0 0.000000
Citroen CX 2400 Pallas 1.0 1.000000 0.547642 1.0 1.0 1.000000
Renault Scenic 0.0 0.000000 0.000000 0.0 0.0 1.000000

qualification

[37]:
qual = electre3.qualification(credibility)
qual
[37]:
Peugeot 505 GR            1
Opel Record 2000 LS      -2
Citroen Visa Super E      0
VW Golf 1300 GLS         -1
Citroen CX 2400 Pallas    4
Renault Scenic           -2
dtype: int64

Distillation

[38]:
descending_distillate = electre3.distillation(
    credibility,
)
descending_distillate.data
[38]:
Peugeot 505 GR Opel Record 2000 LS Citroen Visa Super E VW Golf 1300 GLS Citroen CX 2400 Pallas Renault Scenic
Peugeot 505 GR 1 1 1 1 0 1
Opel Record 2000 LS 0 1 1 1 0 1
Citroen Visa Super E 0 1 1 1 0 1
VW Golf 1300 GLS 0 1 1 1 0 1
Citroen CX 2400 Pallas 1 1 1 1 1 1
Renault Scenic 0 1 1 1 0 1
[39]:
ascending_distillate = electre3.distillation(
    credibility,
    ascending=True
)
ascending_distillate.data
[39]:
Peugeot 505 GR Opel Record 2000 LS Citroen Visa Super E VW Golf 1300 GLS Citroen CX 2400 Pallas Renault Scenic
Peugeot 505 GR 1 1 0 1 0 1
Opel Record 2000 LS 0 1 0 0 0 1
Citroen Visa Super E 1 1 1 1 1 1
VW Golf 1300 GLS 1 1 0 1 0 1
Citroen CX 2400 Pallas 1 1 1 1 1 1
Renault Scenic 0 1 0 0 0 1
[40]:
ascending_distillate.plot()
[40]:
../../_images/notebooks_examples_outranking_algorithms_62_0.svg
[41]:
descending_distillate.plot()
[41]:
../../_images/notebooks_examples_outranking_algorithms_63_0.svg

Final ranking

[42]:
ranking = ascending_distillate & descending_distillate
ranking.data
[42]:
Peugeot 505 GR Opel Record 2000 LS Citroen Visa Super E VW Golf 1300 GLS Citroen CX 2400 Pallas Renault Scenic
Peugeot 505 GR 1 1 0 1 0 1
Opel Record 2000 LS 0 1 0 0 0 1
Citroen Visa Super E 0 1 1 1 0 1
VW Golf 1300 GLS 0 1 0 1 0 1
Citroen CX 2400 Pallas 1 1 1 1 1 1
Renault Scenic 0 1 0 0 0 1
[43]:
ranking.plot()
[43]:
../../_images/notebooks_examples_outranking_algorithms_66_0.svg

You can also call the exploit method directly:

[44]:
ranking = electre3.exploit(credibility)

Direct methods

We can also compute directly the electre III algorithm if nothing needs to be change. Besides it’s possible to reduce the matrix in term of preferences for a proper graph.

[45]:
final_rank = electre3.rank()
final_rank.data
[45]:
Peugeot 505 GR Opel Record 2000 LS Citroen Visa Super E VW Golf 1300 GLS Citroen CX 2400 Pallas Renault Scenic
Peugeot 505 GR 1 1 0 1 0 1
Opel Record 2000 LS 0 1 0 0 0 1
Citroen Visa Super E 0 1 1 1 0 1
VW Golf 1300 GLS 0 1 0 1 0 1
Citroen CX 2400 Pallas 1 1 1 1 1 1
Renault Scenic 0 1 0 0 0 1
[46]:
final_rank.plot()
[46]:
../../_images/notebooks_examples_outranking_algorithms_71_0.svg

Electre TRI

Init

[47]:
scales = {
    0: QuantitativeScale(0, 1),
    1: QuantitativeScale(3, 4),
    2: QuantitativeScale(1, 2),
    3: QuantitativeScale(0, 1),
    4: QuantitativeScale(30, 100),
}
dataset = PerformanceTable([
    [0.720, 3.560, 1.340, 0.62, 44.340],
    [0.8, 3.940, 1.430, 0.74, 36.360],
    [0.760, 3.630, 1.380, 0.89, 48.750],
    [0.780, 3.740, 1.450, 0.72, 42.130],
    [0.740, 3.540, 1.370, 0.73, 36.990],
    [0.690, 3.740, 1.450, 0.84, 42.430],
    [0.7, 3.280, 1.280, 0.83, 47.430],
    [0.860, 3.370, 1.150, 0.8, 80.790],
], scales=scales)
w = {0: 30, 1: 30, 2: 20, 3: 10, 4: 10}
P = {0: 0.05, 1: 0.1, 2: 0.05, 3: 0.1, 4: 8}
I = {0: 0.02, 1: 0.05, 2: 0.02, 3: 0.05, 4: 2}
V = {0: 0.15, 1: 0.6, 2: 0.25, 3: 0.25, 4: 15}
profiles = PerformanceTable(
    [
        [0.750, 3.500, 1.300, 0.730, 42.00],
        [0.800, 3.700, 1.370, 0.790, 43.000],
    ],
    alternatives=["p1", "p2"],
    scales=scales
)
categories = ["Low", "Medium", "High"]

electre_tri = ElectreTri(
    dataset, W, profiles, I, P, V, lambda_=0.7, categories=categories
)

Construction step

[48]:
credibility = electre_tri.construct()
credibility.data
[48]:
0 1 2 3 4 5 6 7 p1 p2
0 1.000000 0.000000 0.000000 0.000000 0.669611 0.077514 0.730189 0.0 0.637855 0.061431
1 1.000000 1.000000 0.732492 1.000000 1.000000 0.732492 0.785994 0.0 1.000000 1.000000
2 1.000000 0.329298 1.000000 0.551420 1.000000 0.551420 1.000000 0.0 1.000000 0.706751
3 1.000000 0.740063 0.732492 1.000000 1.000000 0.732492 0.732492 0.0 1.000000 0.892997
4 1.000000 0.146081 0.510641 0.362145 1.000000 0.283912 0.732492 0.0 1.000000 0.402650
5 0.905363 0.335499 0.716088 0.716088 0.716088 1.000000 1.000000 0.0 0.716088 0.716088
6 0.551420 0.000000 0.129903 0.053363 0.362145 0.306916 1.000000 0.0 0.456151 0.089744
7 0.368776 0.000000 0.050924 0.000000 0.184388 0.000000 0.811356 1.0 0.551420 0.184388
p1 0.822250 0.095726 0.237885 0.420441 0.811356 0.198238 0.732492 0.0 1.000000 0.214006
p2 1.000000 0.551420 0.732492 0.811356 1.000000 0.811356 1.000000 0.0 1.000000 1.000000

Optimistic Procedure

[49]:
electre_tri.exploit(
    credibility
).data
[49]:
0       Low
1      High
2      High
3      High
4    Medium
5      High
6       Low
7      High
dtype: object

Pessimistic Procedure

[50]:
electre_tri.exploit(
    credibility,
    pessimistic=True
).data
[50]:
0       Low
1      High
2      High
3      High
4    Medium
5      High
6       Low
7       Low
dtype: object

Direct method

[51]:
electre_tri.assign().data
[51]:
0       Low
1      High
2      High
3      High
4    Medium
5      High
6       Low
7      High
dtype: object
[52]:
electre_tri.assign(pessimistic=True).data
[52]:
0       Low
1      High
2      High
3      High
4    Medium
5      High
6       Low
7       Low
dtype: object

Promethee algorithms

Outranking problem formalization

[53]:
from mcda import PerformanceTable
from mcda.functions import UShapeFunction, VShapeFunction, LevelFunction, GaussianFunction
from mcda.outranking.promethee import *
from mcda.scales import *
[54]:
action_names = ['a1', 'a2', 'a3', 'a4', 'a5']

scales = {
    0: QuantitativeScale(-5, 5, MAX),
    1: QuantitativeScale(-5, 5, MAX),
    2: QuantitativeScale(-5, 5, MAX),
    3: QuantitativeScale(-5, 5, MAX),
    4: QuantitativeScale(-5, 5, MAX),
    5: QuantitativeScale(-5, 5, MAX),
}

dataset = PerformanceTable([
    [1, 2, -1, 5, 2, 2],  # a1
    [3, 5, 3, -5, 3, 3],  # a2
    [3, -5, 3, 4, 3, 2],  # a3
    [2, -2, 2, 5, 1, 1],  # a4
    [3, 5, 3, -5, 3, 3],  # a5
], scales=scales, alternatives=action_names)

Promethee I

[55]:
preference_func_list = {
    0: VShapeFunction(p=1),
    1: VShapeFunction(p=4),
    2: VShapeFunction(p=3),
    3: VShapeFunction(p=1),
    4: VShapeFunction(p=2),
    5: VShapeFunction(p=2)
}
W = {0: 0.5, 1: 3, 2: 1.5, 3: 0.2, 4: 2, 5: 1}
[56]:
promethee1 = Promethee1(dataset, W, preference_func_list)
[57]:
res = promethee1.rank()
res
[57]:
PreferenceStructure([PreferenceRelation(a5, a1), PreferenceRelation(a3, a4), IncomparableRelation(a1, a3), PreferenceRelation(a5, a4), PreferenceRelation(a1, a4), IndifferenceRelation(a2, a5), PreferenceRelation(a2, a3), PreferenceRelation(a2, a4), PreferenceRelation(a5, a3), PreferenceRelation(a2, a1)])
[58]:
res.plot()
[58]:
../../_images/notebooks_examples_outranking_algorithms_91_0.svg

Promethee II

[59]:
promethee2 = Promethee2(dataset, W, preference_func_list)
[60]:
res = promethee2.rank()
res.data
[60]:
a1   -1.024390
a2    1.908537
a3   -0.701220
a4   -2.091463
a5    1.908537
dtype: float64
[61]:
PreferenceStructure.from_ranking(res).plot()
[61]:
../../_images/notebooks_examples_outranking_algorithms_95_0.svg

Promethee GAIA

[62]:
gaia = PrometheeGaia(dataset, W, preference_func_list)
[63]:
gaia.plot()
/home/nduminy/Development/pymcda/.venv/lib/python3.10/site-packages/pandas/core/algorithms.py:1743: DeprecationWarning: is_sparse is deprecated and will be removed in a future version. Check `isinstance(dtype, pd.SparseDtype)` instead.
  return lib.map_infer(values, mapper, convert=convert)
/home/nduminy/Development/pymcda/.venv/lib/python3.10/site-packages/sklearn/utils/validation.py:595: DeprecationWarning: is_sparse is deprecated and will be removed in a future version. Check `isinstance(dtype, pd.SparseDtype)` instead.
  if is_sparse(pd_dtype):
/home/nduminy/Development/pymcda/.venv/lib/python3.10/site-packages/sklearn/utils/validation.py:604: DeprecationWarning: is_sparse is deprecated and will be removed in a future version. Check `isinstance(dtype, pd.SparseDtype)` instead.
  if is_sparse(pd_dtype) or not is_extension_array_dtype(pd_dtype):
/home/nduminy/Development/pymcda/.venv/lib/python3.10/site-packages/pandas/core/algorithms.py:1743: DeprecationWarning: is_sparse is deprecated and will be removed in a future version. Check `isinstance(dtype, pd.SparseDtype)` instead.
  return lib.map_infer(values, mapper, convert=convert)
/home/nduminy/Development/pymcda/.venv/lib/python3.10/site-packages/sklearn/utils/validation.py:595: DeprecationWarning: is_sparse is deprecated and will be removed in a future version. Check `isinstance(dtype, pd.SparseDtype)` instead.
  if is_sparse(pd_dtype):
/home/nduminy/Development/pymcda/.venv/lib/python3.10/site-packages/sklearn/utils/validation.py:604: DeprecationWarning: is_sparse is deprecated and will be removed in a future version. Check `isinstance(dtype, pd.SparseDtype)` instead.
  if is_sparse(pd_dtype) or not is_extension_array_dtype(pd_dtype):
/home/nduminy/Development/pymcda/.venv/lib/python3.10/site-packages/pandas/core/algorithms.py:1743: DeprecationWarning: is_sparse is deprecated and will be removed in a future version. Check `isinstance(dtype, pd.SparseDtype)` instead.
  return lib.map_infer(values, mapper, convert=convert)
/home/nduminy/Development/pymcda/.venv/lib/python3.10/site-packages/sklearn/utils/validation.py:595: DeprecationWarning: is_sparse is deprecated and will be removed in a future version. Check `isinstance(dtype, pd.SparseDtype)` instead.
  if is_sparse(pd_dtype):
/home/nduminy/Development/pymcda/.venv/lib/python3.10/site-packages/sklearn/utils/validation.py:604: DeprecationWarning: is_sparse is deprecated and will be removed in a future version. Check `isinstance(dtype, pd.SparseDtype)` instead.
  if is_sparse(pd_dtype) or not is_extension_array_dtype(pd_dtype):

MR-Sort

[64]:
from mcda import PerformanceTable
from mcda.scales import *
from mcda.outranking.mrsort import MRSort
[65]:
scales = {
    "Cost": QuantitativeScale(
        6000,
        20000,
        preference_direction=PreferenceDirection.MIN,
    ),
    "Fuel Consumption": QuantitativeScale(
        4, 6, preference_direction=PreferenceDirection.MIN
    ),
    "Comfort": QualitativeScale(
        {"*": 1, "**": 2, "***": 3, "****": 4},
    ),
    "Color": QualitativeScale(
        {"red": 1, "blue": 2, "black": 3, "grey": 4},
        preference_direction=PreferenceDirection.MIN,
    ),
    "Range": QuantitativeScale(
        400,
        1000,
    ),
}
alternatives = [
    "Fiat 500",
    "Peugeot 309",
    "Renault Clio",
    "Opel Astra",
    "Honda Civic",
    "Toyota Corolla",
]
criteria = list(scales.keys())
performance_table = PerformanceTable(
    [
        [9500, 4.2, "**", "blue", 450],
        [15600, 4.5, "****", "black", 900],
        [6800, 4.1, "***", "grey", 700],
        [10200, 5.6, "****", "black", 850],
        [8100, 5.2, "***", "red", 750],
        [12000, 4.9, "****", "grey", 850],
    ],
    alternatives=alternatives,
    criteria=criteria,
    scales=scales,
)
performance_table.data
[65]:
Cost Fuel Consumption Comfort Color Range
Fiat 500 9500 4.2 ** blue 450
Peugeot 309 15600 4.5 **** black 900
Renault Clio 6800 4.1 *** grey 700
Opel Astra 10200 5.6 **** black 850
Honda Civic 8100 5.2 *** red 750
Toyota Corolla 12000 4.9 **** grey 850
[66]:
criteria_weights = {
    "Cost": 2,
    "Fuel Consumption": 3,
    "Comfort": 2,
    "Color": 1,
    "Range": 3,
}
profiles = PerformanceTable(
    [
        [12000, 5.0, "***", "grey", 600],
        [8000, 4.5, "****", "blue", 800],
    ],
    criteria=criteria,
    scales=scales,
)
categories = ["Bad", "Ok", "Good"]
mrsort = MRSort(
    performance_table,
    criteria_weights,
    profiles,
    8,
    categories=categories,
)
[67]:
assignments = mrsort.assign().sort()
assignments.data
[67]:
Peugeot 309       Good
Renault Clio        Ok
Opel Astra          Ok
Honda Civic         Ok
Toyota Corolla      Ok
Fiat 500           Bad
dtype: object
[68]:
assignments.scale
[68]:
QualitativeScale(values={'Bad': 0, 'Ok': 1, 'Good': 2})
[69]:
mrsort.rank().sort().data
[69]:
Peugeot 309       Good
Renault Clio        Ok
Opel Astra          Ok
Honda Civic         Ok
Toyota Corolla      Ok
Fiat 500           Bad
dtype: object

We can use a mcda.outranking.srmp.SRMP classmethod to plot the performance tables and profiles. This allows to see them both and understand intuitively the result of MR-Sort assignment. Indeed SRMP does not assign alternatives to categories but uses the same underlying comparison logic between alternatives and profiles.

[70]:
from mcda.outranking.srmp import SRMP
[71]:
SRMP.plot_input_data(
    performance_table,
    criteria_weights=criteria_weights,
    profiles=profiles,
    xticklabels_tilted=False,
    annotations=True,
    scales_boundaries=False, # better readibility
    annotations_alpha=0.5,
    figsize=(10, 8),
)
[ ]:

SRMP

[72]:
from mcda import PerformanceTable
from mcda.scales import *
from mcda.outranking.srmp import *
from mcda.relations import PreferenceStructure
[73]:
alternatives = ["Fiat 500", "Peugeot 309", "Renault Clio", "Opel Astra", "Honda Civic", "Toyota Corolla"]
criteria = ["cost", "fuel consumption", "comfort", "color", "range"]
scale1 = QuantitativeScale(6000, 20000, preference_direction=MIN)
scale2 = QuantitativeScale(4, 6, preference_direction=MIN)
scale3 = QualitativeScale({"*": 1, "**": 2, "***": 3, "****": 4})
scale4 = QualitativeScale({"red": 1, "blue": 2, "black": 3, "grey": 4}, preference_direction=MIN)
scale5 = QuantitativeScale(400, 1000)
scales = {
    criteria[0]: scale1,
    criteria[1]: scale2,
    criteria[2]: scale3,
    criteria[3]: scale4,
    criteria[4]: scale5
}
performance_table = PerformanceTable(
    [
        [9500, 4.2, "**", "blue", 450],
        [15600, 4.5, "****", "black", 900],
        [6800, 4.1, "***", "grey", 700],
        [10200, 5.6, "****", "black", 850],
        [8100, 5.2, "***", "red", 750],
        [12000, 4.9, "****", "grey", 850]
    ],
    alternatives=alternatives,
    criteria=criteria,
    scales=scales
)
[74]:
criteria_weights = {
    criteria[0]: 1,
    criteria[1]: 2,
    criteria[2]: 3,
    criteria[3]: 2,
    criteria[4]: 4
}

profiles = PerformanceTable(
    [
        [15000, 5.5, "**", "grey", 500],
        [10000, 5, "***", "black", 700],
        [7000, 4.5, "****", "blue", 900],
    ],
    criteria=criteria,
    scales=scales
)

lexicographic_order = [2, 0, 1]
srmp = SRMP(performance_table, criteria_weights, profiles, lexicographic_order)

Preference relations

[75]:
preference_matrices = srmp.construct()
preference_matrices[0].data
[75]:
Fiat 500 Peugeot 309 Renault Clio Opel Astra Honda Civic Toyota Corolla
Fiat 500 1 0 0 0 0 0
Peugeot 309 1 1 0 1 0 0
Renault Clio 1 1 1 1 1 1
Opel Astra 1 0 0 1 0 0
Honda Civic 1 1 1 1 1 1
Toyota Corolla 1 1 1 1 1 1
[76]:
preference_matrices[1].data
[76]:
Fiat 500 Peugeot 309 Renault Clio Opel Astra Honda Civic Toyota Corolla
Fiat 500 1 0 0 0 0 0
Peugeot 309 1 1 1 1 1 1
Renault Clio 1 0 1 1 1 1
Opel Astra 1 0 0 1 0 1
Honda Civic 1 0 1 1 1 1
Toyota Corolla 1 0 0 1 0 1
[77]:
preference_matrices[2].data
[77]:
Fiat 500 Peugeot 309 Renault Clio Opel Astra Honda Civic Toyota Corolla
Fiat 500 1 0 1 1 1 1
Peugeot 309 1 1 1 1 1 1
Renault Clio 0 0 1 1 1 1
Opel Astra 0 0 1 1 1 1
Honda Civic 0 0 0 0 1 0
Toyota Corolla 0 0 1 1 1 1

Ranking

[78]:
rank = srmp.exploit(
    preference_matrices,
)
rank.data
[78]:
Fiat 500          2
Peugeot 309       1
Renault Clio      3
Opel Astra        5
Honda Civic       6
Toyota Corolla    4
dtype: int64
[79]:
PreferenceStructure.from_ranking(rank).plot()
[79]:
../../_images/notebooks_examples_outranking_algorithms_120_0.svg

Direct method

[80]:
rank = srmp.rank()
rank.data
[80]:
Fiat 500          2
Peugeot 309       1
Renault Clio      3
Opel Astra        5
Honda Civic       6
Toyota Corolla    4
dtype: int64
[81]:
PreferenceStructure.from_ranking(rank).plot()
[81]:
../../_images/notebooks_examples_outranking_algorithms_123_0.svg

Plot

Input data

[82]:
SRMP.plot_input_data(
    performance_table,
    srmp,
    xticklabels_tilted=False,
    annotations=True,
    scales_boundaries=False, # better readibility
    annotations_alpha=0.5,
    figsize=(10, 8),
)

Comparison between alternatives

[83]:
SRMP.plot_input_data(
    PerformanceTable(
        performance_table.data.loc[["Fiat 500", "Renault Clio"]],
        scales=scales
    ),
    srmp,
    xticklabels_tilted=False,
    annotations=False,
    scales_boundaries=True, # to keep the same boundaries between the comparisons
)
[84]:
SRMP.plot_input_data(
    PerformanceTable(
        performance_table.data.loc[["Opel Astra", "Toyota Corolla"]],
        scales=scales
    ),
    srmp,
    xticklabels_tilted=False,
    annotations=False,
    scales_boundaries=True, # to keep the same boundaries between the comparisons
)

Concordance

[85]:
srmp.plot_concordance_index(
    performance_table,
    figsize=(10, 4),
    nrows=1,
    xlabels_tilted=False,
)

Progressive ranking

[86]:
srmp.plot_progressive_ranking(
    performance_table
)

SRMP Training

Providing relations

[87]:
from mcda.relations import *

relations = PreferenceStructure([
    P("Fiat 500", "Honda Civic"),
    P("Toyota Corolla", "Opel Astra"),
    P("Fiat 500", "Renault Clio"),
    P("Honda Civic", "Toyota Corolla"),
    I("Opel Astra", "Peugeot 309"),
    I("Renault Clio", "Honda Civic"),
])
relations.plot()
[87]:
../../_images/notebooks_examples_outranking_algorithms_134_0.svg

Train a SRMP model

[88]:
learner = SRMPLearner(
    performance_table,
    relations,
    max_profiles_number=3,
    non_dictator=True,
    gamma=0.01
)
srmp = learner.learn()
srmp.__dict__, learner.fitness
Welcome to the CBC MILP Solver
Version: 2.10.3
Build Date: Dec 15 2019

command line - /home/nduminy/Development/pymcda/.venv/lib/python3.10/site-packages/pulp/apis/../solverdir/cbc/linux/64/cbc /tmp/67cfc01b7a7d48d4a5a541e1fb446043-pulp.mps max timeMode elapsed branch printingOptions all solution /tmp/67cfc01b7a7d48d4a5a541e1fb446043-pulp.sol (default strategy 1)
At line 2 NAME          MODEL
At line 3 ROWS
At line 226 COLUMNS
At line 890 RHS
At line 1112 BOUNDS
At line 1193 ENDATA
Problem MODEL has 221 rows, 80 columns and 577 elements
Coin0008I MODEL read with 0 errors
Option for timeMode changed from cpu to elapsed
Continuous objective value is 6 - 0.00 seconds
Cgl0002I 4 variables fixed
Cgl0003I 0 fixed, 0 tightened bounds, 113 strengthened rows, 6 substitutions
Cgl0003I 0 fixed, 0 tightened bounds, 15 strengthened rows, 0 substitutions
Cgl0003I 0 fixed, 0 tightened bounds, 9 strengthened rows, 0 substitutions
Cgl0003I 0 fixed, 0 tightened bounds, 4 strengthened rows, 0 substitutions
Cgl0004I processed model has 127 rows, 59 columns (25 integer (25 of which binary)) and 470 elements
Cbc0045I 4 integer variables out of 25 objects (25 integer) have cost of -1 - high priority
Cbc0045I branch on satisfied Y create fake objective Y random cost Y
Cbc0038I Initial state - 6 integers unsatisfied sum - 1.58984
Cbc0038I Pass   1: suminf.    0.06000 (5) obj. -5.96 iterations 31
Cbc0038I Pass   2: suminf.    0.12791 (1) obj. -2 iterations 12
Cbc0038I Pass   3: suminf.    0.01000 (1) obj. -2 iterations 6
Cbc0038I Pass   4: suminf.    0.55318 (3) obj. -2 iterations 32
Cbc0038I Pass   5: suminf.    0.00000 (0) obj. -2 iterations 3
Cbc0038I Solution found of -2
Cbc0038I Relaxing continuous gives -2
Cbc0038I Rounding solution of -4 is better than previous of -2

Cbc0038I Before mini branch and bound, 9 integers at bound fixed and 13 continuous
Cbc0038I Full problem 127 rows 59 columns, reduced to 59 rows 30 columns
Cbc0038I Mini branch and bound improved solution from -4 to -5 (0.01 seconds)
Cbc0038I Round again with cutoff of -5.99991
Cbc0038I Reduced cost fixing fixed 4 variables on major pass 2
Cbc0038I Pass   6: suminf.    0.10000 (3) obj. -6 iterations 9
Cbc0038I Pass   7: suminf.    0.30648 (2) obj. -6 iterations 10
Cbc0038I Pass   8: suminf.    0.03000 (2) obj. -6 iterations 7
Cbc0038I Pass   9: suminf.    0.69056 (4) obj. -6 iterations 10
Cbc0038I Pass  10: suminf.    0.53390 (3) obj. -6 iterations 2
Cbc0038I Pass  11: suminf.    0.13857 (1) obj. -6 iterations 8
Cbc0038I Pass  12: suminf.    0.02000 (1) obj. -6 iterations 4
Cbc0038I Pass  13: suminf.    1.06374 (6) obj. -6 iterations 35
Cbc0038I Pass  14: suminf.    0.82457 (5) obj. -6 iterations 4
Cbc0038I Pass  15: suminf.    0.48974 (2) obj. -6 iterations 17
Cbc0038I Pass  16: suminf.    0.02000 (1) obj. -6 iterations 3
Cbc0038I Pass  17: suminf.    0.27632 (1) obj. -6 iterations 2
Cbc0038I Pass  18: suminf.    0.51445 (3) obj. -6 iterations 6
Cbc0038I Pass  19: suminf.    0.27632 (1) obj. -6 iterations 4
Cbc0038I Pass  20: suminf.    0.43298 (2) obj. -6 iterations 8
Cbc0038I Pass  21: suminf.    0.28632 (2) obj. -6 iterations 8
Cbc0038I Pass  22: suminf.    0.01000 (1) obj. -6 iterations 5
Cbc0038I Pass  23: suminf.    0.27632 (1) obj. -6 iterations 2
Cbc0038I Pass  24: suminf.    2.40354 (9) obj. -6 iterations 25
Cbc0038I Pass  25: suminf.    1.60240 (6) obj. -6 iterations 8
Cbc0038I Pass  26: suminf.    0.02000 (1) obj. -6 iterations 18
Cbc0038I Pass  27: suminf.    0.27632 (1) obj. -6 iterations 2
Cbc0038I Pass  28: suminf.    0.64640 (3) obj. -6 iterations 3
Cbc0038I Pass  29: suminf.    0.48974 (2) obj. -6 iterations 2
Cbc0038I Pass  30: suminf.    1.49385 (11) obj. -6 iterations 34
Cbc0038I Pass  31: suminf.    1.04675 (8) obj. -6 iterations 11
Cbc0038I Pass  32: suminf.    0.32454 (3) obj. -6 iterations 20
Cbc0038I Pass  33: suminf.    0.02000 (1) obj. -6 iterations 6
Cbc0038I Pass  34: suminf.    0.13857 (1) obj. -6 iterations 1
Cbc0038I Pass  35: suminf.    1.30417 (7) obj. -6 iterations 26
Cbc0038I Pass  36: suminf.    0.38000 (3) obj. -6 iterations 14
Cbc0038I Pass  37: suminf.    0.13857 (1) obj. -6 iterations 7
Cbc0038I Pass  38: suminf.    0.02000 (1) obj. -6 iterations 1
Cbc0038I Pass  39: suminf.    0.06714 (2) obj. -6 iterations 14
Cbc0038I Pass  40: suminf.    0.02000 (1) obj. -6 iterations 4
Cbc0038I Pass  41: suminf.    0.04714 (1) obj. -6 iterations 1
Cbc0038I Pass  42: suminf.    0.06051 (4) obj. -6 iterations 19
Cbc0038I Pass  43: suminf.    0.66190 (3) obj. -6 iterations 17
Cbc0038I Pass  44: suminf.    0.14791 (2) obj. -6 iterations 8
Cbc0038I Pass  45: suminf.    0.15857 (3) obj. -6 iterations 10
Cbc0038I Pass  46: suminf.    0.14791 (2) obj. -6 iterations 13
Cbc0038I Pass  47: suminf.    0.14857 (2) obj. -6 iterations 10
Cbc0038I Pass  48: suminf.    1.60308 (8) obj. -6 iterations 28
Cbc0038I Pass  49: suminf.    0.99479 (6) obj. -6 iterations 3
Cbc0038I Pass  50: suminf.    0.02000 (1) obj. -6 iterations 15
Cbc0038I Pass  51: suminf.    0.13857 (1) obj. -6 iterations 5
Cbc0038I Pass  52: suminf.    0.14437 (2) obj. -6 iterations 4
Cbc0038I Pass  53: suminf.    0.04000 (3) obj. -6 iterations 12
Cbc0038I Pass  54: suminf.    1.10842 (6) obj. -6 iterations 14
Cbc0038I Pass  55: suminf.    0.60547 (5) obj. -6 iterations 6
Cbc0038I Pass  56: suminf.    0.27632 (1) obj. -6 iterations 12
Cbc0038I Pass  57: suminf.    0.01000 (1) obj. -6 iterations 5
Cbc0038I Pass  58: suminf.    0.72419 (6) obj. -6 iterations 14
Cbc0038I Pass  59: suminf.    0.41560 (3) obj. -6 iterations 14
Cbc0038I Pass  60: suminf.    0.34847 (5) obj. -6 iterations 12
Cbc0038I Pass  61: suminf.    0.19180 (4) obj. -6 iterations 4
Cbc0038I Pass  62: suminf.    0.13857 (1) obj. -6 iterations 9
Cbc0038I Pass  63: suminf.    0.02000 (1) obj. -6 iterations 5
Cbc0038I Pass  64: suminf.    1.40651 (7) obj. -6 iterations 11
Cbc0038I Pass  65: suminf.    0.69667 (3) obj. -6 iterations 5
Cbc0038I Pass  66: suminf.    0.13857 (1) obj. -6 iterations 10
Cbc0038I Pass  67: suminf.    0.02000 (1) obj. -6 iterations 4
Cbc0038I Pass  68: suminf.    1.04037 (6) obj. -6 iterations 13
Cbc0038I Pass  69: suminf.    0.40000 (3) obj. -6 iterations 6
Cbc0038I Pass  70: suminf.    0.13857 (1) obj. -6 iterations 6
Cbc0038I Pass  71: suminf.    0.02000 (1) obj. -6 iterations 4
Cbc0038I Pass  72: suminf.    0.90187 (5) obj. -6 iterations 9
Cbc0038I Pass  73: suminf.    0.69667 (3) obj. -6 iterations 6
Cbc0038I Pass  74: suminf.    0.13857 (1) obj. -6 iterations 9
Cbc0038I Pass  75: suminf.    0.02000 (1) obj. -6 iterations 3
Cbc0038I Pass  76: suminf.    0.70391 (6) obj. -6 iterations 18
Cbc0038I Pass  77: suminf.    1.20866 (7) obj. -6 iterations 7
Cbc0038I Pass  78: suminf.    0.64790 (2) obj. -6 iterations 16
Cbc0038I Pass  79: suminf.    0.02000 (1) obj. -6 iterations 4
Cbc0038I Pass  80: suminf.    0.13857 (1) obj. -6 iterations 3
Cbc0038I Pass  81: suminf.    0.91417 (4) obj. -6 iterations 11
Cbc0038I Pass  82: suminf.    0.02000 (2) obj. -6 iterations 6
Cbc0038I Pass  83: suminf.    0.44880 (5) obj. -6 iterations 13
Cbc0038I Pass  84: suminf.    0.04000 (4) obj. -6 iterations 5
Cbc0038I Pass  85: suminf.    0.30648 (2) obj. -6 iterations 13
Cbc0038I Pass  86: suminf.    0.03000 (2) obj. -6 iterations 7
Cbc0038I Pass  87: suminf.    0.82524 (5) obj. -6 iterations 7
Cbc0038I Pass  88: suminf.    0.03000 (2) obj. -6 iterations 6
Cbc0038I Pass  89: suminf.    0.30648 (2) obj. -6 iterations 6
Cbc0038I Pass  90: suminf.    0.70208 (5) obj. -6 iterations 11
Cbc0038I Pass  91: suminf.    0.37212 (4) obj. -6 iterations 4
Cbc0038I Pass  92: suminf.    0.37212 (4) obj. -6 iterations 6
Cbc0038I Pass  93: suminf.    0.03000 (2) obj. -6 iterations 5
Cbc0038I Pass  94: suminf.    0.30648 (2) obj. -6 iterations 3
Cbc0038I Pass  95: suminf.    1.16023 (6) obj. -6 iterations 10
Cbc0038I Pass  96: suminf.    0.83038 (5) obj. -6 iterations 4
Cbc0038I Pass  97: suminf.    0.02000 (1) obj. -6 iterations 14
Cbc0038I Pass  98: suminf.    0.13857 (1) obj. -6 iterations 1
Cbc0038I Pass  99: suminf.    0.82315 (4) obj. -6 iterations 10
Cbc0038I Pass 100: suminf.    0.66648 (3) obj. -6 iterations 2
Cbc0038I Pass 101: suminf.    1.12816 (5) obj. -6 iterations 24
Cbc0038I Pass 102: suminf.    0.78830 (3) obj. -6 iterations 3
Cbc0038I Pass 103: suminf.    0.03000 (3) obj. -6 iterations 11
Cbc0038I Pass 104: suminf.    0.27632 (1) obj. -6 iterations 7
Cbc0038I Pass 105: suminf.    0.48236 (3) obj. -6 iterations 8
Cbc0038I No solution found this major pass
Cbc0038I Before mini branch and bound, 4 integers at bound fixed and 0 continuous
Cbc0038I Full problem 127 rows 59 columns, reduced to 127 rows 55 columns - 8 fixed gives 108, 47 - ok now
Cbc0038I Full problem 127 rows 59 columns, reduced to 88 rows 39 columns
Cbc0038I Mini branch and bound did not improve solution (0.02 seconds)
Cbc0038I After 0.02 seconds - Feasibility pump exiting with objective of -5 - took 0.02 seconds
Cbc0012I Integer solution of -5 found by feasibility pump after 0 iterations and 0 nodes (0.02 seconds)
Cbc0031I 34 added rows had average density of 23.088235
Cbc0013I At root node, 34 cuts changed objective from -6 to -6 in 100 passes
Cbc0014I Cut generator 0 (Probing) - 1349 row cuts average 2.6 elements, 0 column cuts (0 active)  in 0.014 seconds - new frequency is -100
Cbc0014I Cut generator 1 (Gomory) - 519 row cuts average 50.5 elements, 0 column cuts (0 active)  in 0.008 seconds - new frequency is -100
Cbc0014I Cut generator 2 (Knapsack) - 65 row cuts average 2.6 elements, 0 column cuts (0 active)  in 0.007 seconds - new frequency is -100
Cbc0014I Cut generator 3 (Clique) - 0 row cuts average 0.0 elements, 0 column cuts (0 active)  in 0.000 seconds - new frequency is -100
Cbc0014I Cut generator 4 (MixedIntegerRounding2) - 195 row cuts average 5.4 elements, 0 column cuts (0 active)  in 0.009 seconds - new frequency is -100
Cbc0014I Cut generator 5 (FlowCover) - 8 row cuts average 2.9 elements, 0 column cuts (0 active)  in 0.009 seconds - new frequency is -100
Cbc0014I Cut generator 6 (TwoMirCuts) - 165 row cuts average 6.4 elements, 0 column cuts (0 active)  in 0.003 seconds - new frequency is -100
Cbc0010I After 0 nodes, 1 on tree, -5 best solution, best possible -6 (0.12 seconds)
Cbc0001I Search completed - best objective -5, took 2389 iterations and 10 nodes (0.13 seconds)
Cbc0032I Strong branching done 72 times (761 iterations), fathomed 6 nodes and fixed 0 variables
Cbc0035I Maximum depth 4, 4 variables fixed on reduced cost
Cuts at root node changed objective from -6 to -6
Probing was tried 100 times and created 1349 cuts of which 0 were active after adding rounds of cuts (0.014 seconds)
Gomory was tried 100 times and created 519 cuts of which 0 were active after adding rounds of cuts (0.008 seconds)
Knapsack was tried 100 times and created 65 cuts of which 0 were active after adding rounds of cuts (0.007 seconds)
Clique was tried 100 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)
MixedIntegerRounding2 was tried 100 times and created 195 cuts of which 0 were active after adding rounds of cuts (0.009 seconds)
FlowCover was tried 100 times and created 8 cuts of which 0 were active after adding rounds of cuts (0.009 seconds)
TwoMirCuts was tried 100 times and created 165 cuts of which 0 were active after adding rounds of cuts (0.003 seconds)
ZeroHalf was tried 1 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)
ImplicationCuts was tried 15 times and created 127 cuts of which 0 were active after adding rounds of cuts (0.001 seconds)

Result - Optimal solution found

Objective value:                5.00000000
Enumerated nodes:               10
Total iterations:               2389
Time (CPU seconds):             0.13
Time (Wallclock seconds):       0.13

Option for printingOptions changed from normal to all
Total time (CPU seconds):       0.13   (Wallclock seconds):       0.13

Welcome to the CBC MILP Solver
Version: 2.10.3
Build Date: Dec 15 2019

command line - /home/nduminy/Development/pymcda/.venv/lib/python3.10/site-packages/pulp/apis/../solverdir/cbc/linux/64/cbc /tmp/77f9349c412e461aa3b0584b02dc9e4d-pulp.mps max timeMode elapsed branch printingOptions all solution /tmp/77f9349c412e461aa3b0584b02dc9e4d-pulp.sol (default strategy 1)
At line 2 NAME          MODEL
At line 3 ROWS
At line 427 COLUMNS
At line 1717 RHS
At line 2140 BOUNDS
At line 2290 ENDATA
Problem MODEL has 422 rows, 149 columns and 1135 elements
Coin0008I MODEL read with 0 errors
Option for timeMode changed from cpu to elapsed
Continuous objective value is 6 - 0.00 seconds
Cgl0002I 4 variables fixed
Cgl0003I 0 fixed, 0 tightened bounds, 234 strengthened rows, 12 substitutions
Cgl0003I 0 fixed, 0 tightened bounds, 49 strengthened rows, 0 substitutions
Cgl0003I 0 fixed, 0 tightened bounds, 24 strengthened rows, 0 substitutions
Cgl0003I 0 fixed, 0 tightened bounds, 4 strengthened rows, 0 substitutions
Cgl0003I 0 fixed, 0 tightened bounds, 1 strengthened rows, 0 substitutions
Cgl0004I processed model has 265 rows, 113 columns (50 integer (50 of which binary)) and 1018 elements
Cbc0045I 4 integer variables out of 50 objects (50 integer) have cost of -1 - high priority
Cbc0045I branch on satisfied Y create fake objective Y random cost Y
Cbc0038I Initial state - 10 integers unsatisfied sum - 3.01304
Cbc0038I Pass   1: suminf.    0.13980 (7) obj. -5.99 iterations 51
Cbc0038I Pass   2: suminf.    0.22603 (4) obj. -5 iterations 58
Cbc0038I Pass   3: suminf.    0.15000 (4) obj. -5 iterations 4
Cbc0038I Pass   4: suminf.    0.02990 (2) obj. -5 iterations 23
Cbc0038I Pass   5: suminf.    0.12000 (2) obj. -5 iterations 5
Cbc0038I Pass   6: suminf.    0.33500 (5) obj. -5.99 iterations 54
Cbc0038I Pass   7: suminf.    0.27500 (4) obj. -5.99 iterations 3
Cbc0038I Pass   8: suminf.    0.46620 (4) obj. -5 iterations 25
Cbc0038I Pass   9: suminf.    0.03000 (2) obj. -5 iterations 29
Cbc0038I Pass  10: suminf.    0.33442 (3) obj. -5 iterations 16
Cbc0038I Pass  11: suminf.    0.03000 (2) obj. -5 iterations 8
Cbc0038I Pass  12: suminf.    0.21575 (2) obj. -5 iterations 10
Cbc0038I Pass  13: suminf.    2.62712 (11) obj. -3 iterations 32
Cbc0038I Pass  14: suminf.    1.28788 (8) obj. -3 iterations 10
Cbc0038I Pass  15: suminf.    0.14360 (5) obj. -3 iterations 32
Cbc0038I Pass  16: suminf.    0.20605 (2) obj. -3 iterations 18
Cbc0038I Pass  17: suminf.    0.03970 (2) obj. -3 iterations 5
Cbc0038I Pass  18: suminf.    1.90808 (10) obj. -3 iterations 61
Cbc0038I Pass  19: suminf.    0.72101 (5) obj. -3 iterations 9
Cbc0038I Pass  20: suminf.    0.02000 (2) obj. -3 iterations 14
Cbc0038I Pass  21: suminf.    0.26407 (2) obj. -3 iterations 12
Cbc0038I Pass  22: suminf.    2.40338 (15) obj. -4 iterations 63
Cbc0038I Pass  23: suminf.    2.21306 (12) obj. -4 iterations 6
Cbc0038I Pass  24: suminf.    0.49258 (6) obj. -4 iterations 44
Cbc0038I Pass  25: suminf.    0.04990 (4) obj. -4 iterations 22
Cbc0038I Pass  26: suminf.    0.02000 (2) obj. -4 iterations 25
Cbc0038I Pass  27: suminf.    0.03980 (3) obj. -4 iterations 16
Cbc0038I Pass  28: suminf.    0.03000 (3) obj. -4 iterations 15
Cbc0038I Pass  29: suminf.    1.44298 (7) obj. -3 iterations 33
Cbc0038I Pass  30: suminf.    1.22298 (6) obj. -3 iterations 2
Cbc0038I Pass  31: suminf.    0.00000 (0) obj. -3 iterations 8
Cbc0038I Solution found of -3
Cbc0038I Relaxing continuous gives -3
Cbc0038I Rounding solution of -4 is better than previous of -3

Cbc0038I Before mini branch and bound, 6 integers at bound fixed and 9 continuous
Cbc0038I Full problem 265 rows 113 columns, reduced to 227 rows 96 columns - 4 fixed gives 219, 92 - still too large
Cbc0038I Mini branch and bound did not improve solution (0.02 seconds)
Cbc0038I Round again with cutoff of -5.09991
Cbc0038I Reduced cost fixing fixed 4 variables on major pass 2
Cbc0038I Pass  32: suminf.    0.13970 (7) obj. -6 iterations 1
Cbc0038I Pass  33: suminf.    0.22603 (4) obj. -6 iterations 60
Cbc0038I Pass  34: suminf.    0.15000 (4) obj. -6 iterations 7
Cbc0038I Pass  35: suminf.    0.02990 (2) obj. -6 iterations 16
Cbc0038I Pass  36: suminf.    0.12000 (2) obj. -6 iterations 6
Cbc0038I Pass  37: suminf.    2.70673 (12) obj. -6 iterations 59
Cbc0038I Pass  38: suminf.    1.41648 (9) obj. -6 iterations 7
Cbc0038I Pass  39: suminf.    1.41648 (9) obj. -6 iterations 0
Cbc0038I Pass  40: suminf.    0.21990 (2) obj. -6 iterations 34
Cbc0038I Pass  41: suminf.    0.17000 (1) obj. -6 iterations 5
Cbc0038I Pass  42: suminf.    0.17822 (1) obj. -6 iterations 1
Cbc0038I Pass  43: suminf.    0.77421 (7) obj. -6 iterations 33
Cbc0038I Pass  44: suminf.    0.53421 (6) obj. -6 iterations 1
Cbc0038I Pass  45: suminf.    0.23090 (3) obj. -6 iterations 21
Cbc0038I Pass  46: suminf.    0.01000 (1) obj. -6 iterations 18
Cbc0038I Pass  47: suminf.    0.00990 (1) obj. -6 iterations 1
Cbc0038I Pass  48: suminf.    2.26391 (12) obj. -6 iterations 40
Cbc0038I Pass  49: suminf.    1.97591 (11) obj. -6 iterations 1
Cbc0038I Pass  50: suminf.    0.19180 (3) obj. -6 iterations 40
Cbc0038I Pass  51: suminf.    0.01980 (1) obj. -6 iterations 7
Cbc0038I Pass  52: suminf.    0.01000 (1) obj. -6 iterations 1
Cbc0038I Pass  53: suminf.    1.30298 (6) obj. -6 iterations 34
Cbc0038I Pass  54: suminf.    0.77810 (4) obj. -6 iterations 3
Cbc0038I Pass  55: suminf.    0.02970 (1) obj. -6 iterations 14
Cbc0038I Pass  56: suminf.    0.02000 (1) obj. -6 iterations 1
Cbc0038I Pass  57: suminf.    1.02213 (5) obj. -6 iterations 22
Cbc0038I Pass  58: suminf.    0.01000 (1) obj. -6 iterations 11
Cbc0038I Pass  59: suminf.    0.01980 (1) obj. -6 iterations 1
Cbc0038I Pass  60: suminf.    1.24630 (8) obj. -6 iterations 30
Cbc0038I Pass  61: suminf.    0.84259 (8) obj. -6 iterations 9
Cbc0038I Pass  62: suminf.    0.29187 (7) obj. -6 iterations 2
Cbc0038I Pass  63: suminf.    0.01000 (1) obj. -6 iterations 24
Cbc0038I Pass  64: suminf.    0.01980 (1) obj. -6 iterations 1
Cbc0038I Pass  65: suminf.    1.67114 (9) obj. -6 iterations 53
Cbc0038I Pass  66: suminf.    1.08898 (6) obj. -6 iterations 9
Cbc0038I Pass  67: suminf.    0.36500 (2) obj. -6 iterations 15
Cbc0038I Pass  68: suminf.    0.26485 (1) obj. -6 iterations 4
Cbc0038I Pass  69: suminf.    0.25750 (1) obj. -6 iterations 1
Cbc0038I Pass  70: suminf.    1.85378 (10) obj. -6 iterations 28
Cbc0038I Pass  71: suminf.    1.15801 (7) obj. -6 iterations 6
Cbc0038I Pass  72: suminf.    0.11286 (2) obj. -6 iterations 19
Cbc0038I Pass  73: suminf.    0.00990 (1) obj. -6 iterations 3
Cbc0038I Pass  74: suminf.    0.01000 (1) obj. -6 iterations 1
Cbc0038I Pass  75: suminf.    0.92711 (6) obj. -6 iterations 39
Cbc0038I Pass  76: suminf.    0.45913 (6) obj. -6 iterations 11
Cbc0038I Pass  77: suminf.    0.18990 (3) obj. -6 iterations 20
Cbc0038I Pass  78: suminf.    0.01000 (1) obj. -6 iterations 10
Cbc0038I Pass  79: suminf.    0.00990 (1) obj. -6 iterations 2
Cbc0038I Pass  80: suminf.    1.69920 (6) obj. -6 iterations 35
Cbc0038I Pass  81: suminf.    1.00022 (4) obj. -6 iterations 2
Cbc0038I Pass  82: suminf.    0.01990 (2) obj. -6 iterations 19
Cbc0038I Pass  83: suminf.    0.01000 (1) obj. -6 iterations 4
Cbc0038I Pass  84: suminf.    0.00990 (1) obj. -6 iterations 1
Cbc0038I Pass  85: suminf.    0.80418 (8) obj. -6 iterations 47
Cbc0038I Pass  86: suminf.    0.75306 (8) obj. -6 iterations 14
Cbc0038I Pass  87: suminf.    1.10240 (8) obj. -6 iterations 41
Cbc0038I Pass  88: suminf.    0.37657 (4) obj. -6 iterations 23
Cbc0038I Pass  89: suminf.    0.01000 (1) obj. -6 iterations 12
Cbc0038I Pass  90: suminf.    0.00990 (1) obj. -6 iterations 2
Cbc0038I Pass  91: suminf.    0.31648 (3) obj. -6 iterations 33
Cbc0038I Pass  92: suminf.    0.00990 (1) obj. -6 iterations 11
Cbc0038I Pass  93: suminf.    0.01000 (1) obj. -6 iterations 4
Cbc0038I Pass  94: suminf.    1.38541 (9) obj. -6 iterations 25
Cbc0038I Pass  95: suminf.    1.38541 (9) obj. -6 iterations 0
Cbc0038I Pass  96: suminf.    1.06464 (5) obj. -6 iterations 32
Cbc0038I Pass  97: suminf.    0.34214 (3) obj. -6 iterations 5
Cbc0038I Pass  98: suminf.    0.00990 (1) obj. -6 iterations 7
Cbc0038I Pass  99: suminf.    0.01000 (1) obj. -6 iterations 1
Cbc0038I Pass 100: suminf.    2.10334 (10) obj. -6 iterations 43
Cbc0038I Pass 101: suminf.    1.92334 (9) obj. -6 iterations 1
Cbc0038I Pass 102: suminf.    0.73865 (6) obj. -6 iterations 38
Cbc0038I Pass 103: suminf.    0.36158 (3) obj. -6 iterations 35
Cbc0038I Pass 104: suminf.    0.14000 (2) obj. -6 iterations 14
Cbc0038I Pass 105: suminf.    0.05960 (4) obj. -6 iterations 12
Cbc0038I Pass 106: suminf.    0.15000 (4) obj. -6 iterations 8
Cbc0038I Pass 107: suminf.    1.16574 (8) obj. -6 iterations 34
Cbc0038I Pass 108: suminf.    0.16000 (4) obj. -6 iterations 26
Cbc0038I Pass 109: suminf.    0.04970 (2) obj. -6 iterations 8
Cbc0038I Pass 110: suminf.    0.14000 (2) obj. -6 iterations 7
Cbc0038I Pass 111: suminf.    2.90779 (21) obj. -6 iterations 105
Cbc0038I Pass 112: suminf.    2.29405 (12) obj. -6 iterations 19
Cbc0038I Pass 113: suminf.    0.78243 (8) obj. -6 iterations 45
Cbc0038I Pass 114: suminf.    0.63621 (6) obj. -6 iterations 24
Cbc0038I Pass 115: suminf.    0.07941 (5) obj. -6 iterations 16
Cbc0038I Pass 116: suminf.    0.34461 (5) obj. -6 iterations 16
Cbc0038I Pass 117: suminf.    1.66714 (11) obj. -6 iterations 47
Cbc0038I Pass 118: suminf.    0.66868 (6) obj. -6 iterations 7
Cbc0038I Pass 119: suminf.    0.54694 (5) obj. -6 iterations 31
Cbc0038I Pass 120: suminf.    0.35333 (5) obj. -6 iterations 19
Cbc0038I Pass 121: suminf.    0.38691 (3) obj. -6 iterations 17
Cbc0038I Pass 122: suminf.    0.27470 (3) obj. -6 iterations 14
Cbc0038I Pass 123: suminf.    0.24391 (5) obj. -6 iterations 15
Cbc0038I Pass 124: suminf.    0.57854 (7) obj. -6 iterations 22
Cbc0038I Pass 125: suminf.    0.62246 (9) obj. -6 iterations 29
Cbc0038I Pass 126: suminf.    0.69971 (6) obj. -6 iterations 33
Cbc0038I Pass 127: suminf.    0.04000 (4) obj. -6 iterations 20
Cbc0038I Pass 128: suminf.    0.15260 (4) obj. -6 iterations 12
Cbc0038I Pass 129: suminf.    0.04990 (4) obj. -6 iterations 17
Cbc0038I Pass 130: suminf.    0.24614 (2) obj. -6 iterations 22
Cbc0038I Pass 131: suminf.    0.99880 (7) obj. -6 iterations 41
Cbc0038I Rounding solution of -5 is better than previous of -4

Cbc0038I Before mini branch and bound, 4 integers at bound fixed and 5 continuous
Cbc0038I Full problem 265 rows 113 columns, reduced to 255 rows 104 columns - 6 fixed gives 238, 97 - still too large
Cbc0038I Mini branch and bound did not improve solution (0.04 seconds)
Cbc0038I Round again with cutoff of -5.99992
Cbc0038I Reduced cost fixing fixed 4 variables on major pass 3
Cbc0038I Pass 131: suminf.    0.13970 (7) obj. -6 iterations 0
Cbc0038I Pass 132: suminf.    0.22603 (4) obj. -6 iterations 63
Cbc0038I Pass 133: suminf.    0.15000 (4) obj. -6 iterations 6
Cbc0038I Pass 134: suminf.    0.02990 (2) obj. -6 iterations 19
Cbc0038I Pass 135: suminf.    0.12000 (2) obj. -6 iterations 6
Cbc0038I Pass 136: suminf.    2.04742 (14) obj. -6 iterations 56
Cbc0038I Pass 137: suminf.    1.10993 (8) obj. -6 iterations 20
Cbc0038I Pass 138: suminf.    0.05970 (5) obj. -6 iterations 29
Cbc0038I Pass 139: suminf.    0.47826 (6) obj. -6 iterations 25
Cbc0038I Pass 140: suminf.    0.06990 (3) obj. -6 iterations 20
Cbc0038I Pass 141: suminf.    0.12000 (2) obj. -6 iterations 18
Cbc0038I Pass 142: suminf.    0.04990 (2) obj. -6 iterations 8
Cbc0038I Pass 143: suminf.    0.27660 (5) obj. -6 iterations 11
Cbc0038I Pass 144: suminf.    0.20304 (3) obj. -6 iterations 3
Cbc0038I Pass 145: suminf.    0.20314 (3) obj. -6 iterations 5
Cbc0038I Pass 146: suminf.    1.47606 (14) obj. -6 iterations 46
Cbc0038I Pass 147: suminf.    0.90453 (7) obj. -6 iterations 23
Cbc0038I Pass 148: suminf.    0.20314 (3) obj. -6 iterations 24
Cbc0038I Pass 149: suminf.    0.20304 (3) obj. -6 iterations 5
Cbc0038I Pass 150: suminf.    3.83220 (18) obj. -6 iterations 53
Cbc0038I Pass 151: suminf.    1.24278 (11) obj. -6 iterations 44
Cbc0038I Pass 152: suminf.    0.58221 (8) obj. -6 iterations 39
Cbc0038I Pass 153: suminf.    0.29970 (4) obj. -6 iterations 27
Cbc0038I Pass 154: suminf.    0.04980 (3) obj. -6 iterations 12
Cbc0038I Pass 155: suminf.    0.04970 (3) obj. -6 iterations 8
Cbc0038I Pass 156: suminf.    2.57768 (11) obj. -6 iterations 31
Cbc0038I Pass 157: suminf.    1.61025 (9) obj. -6 iterations 6
Cbc0038I Pass 158: suminf.    0.05000 (2) obj. -6 iterations 30
Cbc0038I Pass 159: suminf.    0.11990 (2) obj. -6 iterations 3
Cbc0038I Pass 160: suminf.    1.16640 (8) obj. -6 iterations 30
Cbc0038I Pass 161: suminf.    0.32638 (4) obj. -6 iterations 22
Cbc0038I Pass 162: suminf.    0.04667 (4) obj. -6 iterations 15
Cbc0038I Pass 163: suminf.    0.13970 (2) obj. -6 iterations 18
Cbc0038I Pass 164: suminf.    0.04000 (2) obj. -6 iterations 7
Cbc0038I Pass 165: suminf.    2.15711 (12) obj. -6 iterations 49
Cbc0038I Pass 166: suminf.    0.48834 (7) obj. -6 iterations 23
Cbc0038I Pass 167: suminf.    0.51864 (3) obj. -6 iterations 20
Cbc0038I Pass 168: suminf.    0.26000 (3) obj. -6 iterations 13
Cbc0038I Pass 169: suminf.    1.57443 (13) obj. -6 iterations 54
Cbc0038I Pass 170: suminf.    1.10770 (9) obj. -6 iterations 10
Cbc0038I Pass 171: suminf.    0.02000 (2) obj. -6 iterations 30
Cbc0038I Pass 172: suminf.    0.00990 (1) obj. -6 iterations 5
Cbc0038I Pass 173: suminf.    0.01000 (1) obj. -6 iterations 3
Cbc0038I Pass 174: suminf.    1.15607 (10) obj. -6 iterations 41
Cbc0038I Pass 175: suminf.    0.83274 (9) obj. -6 iterations 10
Cbc0038I Pass 176: suminf.    0.80093 (7) obj. -6 iterations 27
Cbc0038I Pass 177: suminf.    0.17445 (5) obj. -6 iterations 8
Cbc0038I Pass 178: suminf.    0.02513 (3) obj. -6 iterations 19
Cbc0038I Pass 179: suminf.    0.37822 (4) obj. -6 iterations 22
Cbc0038I Pass 180: suminf.    0.28000 (2) obj. -6 iterations 16
Cbc0038I Pass 181: suminf.    0.19822 (2) obj. -6 iterations 11
Cbc0038I Pass 182: suminf.    3.13051 (16) obj. -6 iterations 48
Cbc0038I Pass 183: suminf.    2.19117 (13) obj. -6 iterations 5
Cbc0038I Pass 184: suminf.    0.58922 (7) obj. -6 iterations 43
Cbc0038I Pass 185: suminf.    0.13276 (4) obj. -6 iterations 18
Cbc0038I Pass 186: suminf.    0.01000 (1) obj. -6 iterations 12
Cbc0038I Pass 187: suminf.    0.01980 (1) obj. -6 iterations 1
Cbc0038I Pass 188: suminf.    2.36747 (13) obj. -6 iterations 44
Cbc0038I Pass 189: suminf.    1.80045 (9) obj. -6 iterations 6
Cbc0038I Pass 190: suminf.    0.39311 (7) obj. -6 iterations 29
Cbc0038I Pass 191: suminf.    0.38998 (7) obj. -6 iterations 7
Cbc0038I Pass 192: suminf.    0.38342 (6) obj. -6 iterations 6
Cbc0038I Pass 193: suminf.    0.54495 (5) obj. -6 iterations 21
Cbc0038I Pass 194: suminf.    0.36158 (3) obj. -6 iterations 10
Cbc0038I Pass 195: suminf.    0.36149 (3) obj. -6 iterations 4
Cbc0038I Pass 196: suminf.    2.09348 (16) obj. -6 iterations 70
Cbc0038I Pass 197: suminf.    1.38278 (11) obj. -6 iterations 15
Cbc0038I Pass 198: suminf.    0.56040 (6) obj. -6 iterations 46
Cbc0038I Pass 199: suminf.    0.04493 (4) obj. -6 iterations 14
Cbc0038I Pass 200: suminf.    0.37000 (4) obj. -6 iterations 24
Cbc0038I Pass 201: suminf.    0.28822 (2) obj. -6 iterations 16
Cbc0038I Pass 202: suminf.    0.19000 (2) obj. -6 iterations 11
Cbc0038I Pass 203: suminf.    1.29512 (10) obj. -6 iterations 84
Cbc0038I Pass 204: suminf.    0.47907 (6) obj. -6 iterations 10
Cbc0038I Pass 205: suminf.    0.00990 (1) obj. -6 iterations 14
Cbc0038I Pass 206: suminf.    0.01000 (1) obj. -6 iterations 1
Cbc0038I Pass 207: suminf.    1.59842 (12) obj. -6 iterations 49
Cbc0038I Pass 208: suminf.    0.93603 (9) obj. -6 iterations 6
Cbc0038I Pass 209: suminf.    0.09333 (1) obj. -6 iterations 36
Cbc0038I Pass 210: suminf.    0.01000 (1) obj. -6 iterations 8
Cbc0038I Pass 211: suminf.    0.00990 (1) obj. -6 iterations 1
Cbc0038I Pass 212: suminf.    1.20839 (6) obj. -6 iterations 24
Cbc0038I Pass 213: suminf.    0.25750 (1) obj. -6 iterations 21
Cbc0038I Pass 214: suminf.    0.26485 (1) obj. -6 iterations 1
Cbc0038I Pass 215: suminf.    1.29667 (5) obj. -6 iterations 20
Cbc0038I Pass 216: suminf.    1.03000 (3) obj. -6 iterations 2
Cbc0038I Pass 217: suminf.    0.00990 (1) obj. -6 iterations 8
Cbc0038I Pass 218: suminf.    0.01000 (1) obj. -6 iterations 1
Cbc0038I Pass 219: suminf.    0.62495 (12) obj. -6 iterations 41
Cbc0038I Pass 220: suminf.    0.20317 (9) obj. -6 iterations 8
Cbc0038I Pass 221: suminf.    0.55470 (6) obj. -6 iterations 29
Cbc0038I Pass 222: suminf.    0.02980 (3) obj. -6 iterations 11
Cbc0038I Pass 223: suminf.    0.02990 (3) obj. -6 iterations 5
Cbc0038I Pass 224: suminf.    2.09610 (13) obj. -6 iterations 69
Cbc0038I Pass 225: suminf.    1.35597 (10) obj. -6 iterations 11
Cbc0038I Pass 226: suminf.    0.54000 (7) obj. -6 iterations 46
Cbc0038I Pass 227: suminf.    0.55137 (5) obj. -6 iterations 20
Cbc0038I Pass 228: suminf.    0.12000 (2) obj. -6 iterations 13
Cbc0038I Pass 229: suminf.    0.02990 (2) obj. -6 iterations 10
Cbc0038I Pass 230: suminf.    1.46293 (11) obj. -6 iterations 44
Cbc0038I No solution found this major pass
Cbc0038I Before mini branch and bound, 4 integers at bound fixed and 2 continuous
Cbc0038I Full problem 265 rows 113 columns, reduced to 261 rows 107 columns - 3 fixed gives 253, 104 - still too large
Cbc0038I Mini branch and bound did not improve solution (0.08 seconds)
Cbc0038I After 0.08 seconds - Feasibility pump exiting with objective of -5 - took 0.07 seconds
Cbc0012I Integer solution of -5 found by feasibility pump after 0 iterations and 0 nodes (0.08 seconds)
Cbc0038I Full problem 265 rows 113 columns, reduced to 145 rows 54 columns - 10 fixed gives 97, 40 - ok now
Cbc0038I Full problem 265 rows 113 columns, reduced to 56 rows 24 columns
Cbc0031I 52 added rows had average density of 17.288462
Cbc0013I At root node, 52 cuts changed objective from -6 to -6 in 100 passes
Cbc0014I Cut generator 0 (Probing) - 1276 row cuts average 2.6 elements, 0 column cuts (1 active)  in 0.028 seconds - new frequency is -100
Cbc0014I Cut generator 1 (Gomory) - 1252 row cuts average 93.3 elements, 0 column cuts (0 active)  in 0.018 seconds - new frequency is -100
Cbc0014I Cut generator 2 (Knapsack) - 69 row cuts average 3.6 elements, 0 column cuts (0 active)  in 0.010 seconds - new frequency is -100
Cbc0014I Cut generator 3 (Clique) - 0 row cuts average 0.0 elements, 0 column cuts (0 active)  in 0.001 seconds - new frequency is -100
Cbc0014I Cut generator 4 (MixedIntegerRounding2) - 293 row cuts average 6.4 elements, 0 column cuts (0 active)  in 0.018 seconds - new frequency is -100
Cbc0014I Cut generator 5 (FlowCover) - 2 row cuts average 3.0 elements, 0 column cuts (0 active)  in 0.010 seconds - new frequency is -100
Cbc0014I Cut generator 6 (TwoMirCuts) - 208 row cuts average 16.7 elements, 0 column cuts (0 active)  in 0.006 seconds - new frequency is -100
Cbc0010I After 0 nodes, 1 on tree, -5 best solution, best possible -6 (0.28 seconds)
Cbc0038I Full problem 265 rows 113 columns, reduced to 95 rows 42 columns
Cbc0038I Full problem 265 rows 113 columns, reduced to 98 rows 42 columns
Cbc0038I Full problem 265 rows 113 columns, reduced to 58 rows 27 columns
Cbc0012I Integer solution of -6 found by DiveCoefficient after 17598 iterations and 400 nodes (0.78 seconds)
Cbc0001I Search completed - best objective -6, took 17598 iterations and 400 nodes (0.78 seconds)
Cbc0032I Strong branching done 2976 times (36232 iterations), fathomed 148 nodes and fixed 75 variables
Cbc0035I Maximum depth 14, 4 variables fixed on reduced cost
Cuts at root node changed objective from -6 to -6
Probing was tried 100 times and created 1276 cuts of which 1 were active after adding rounds of cuts (0.028 seconds)
Gomory was tried 100 times and created 1252 cuts of which 0 were active after adding rounds of cuts (0.018 seconds)
Knapsack was tried 100 times and created 69 cuts of which 0 were active after adding rounds of cuts (0.010 seconds)
Clique was tried 100 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.001 seconds)
MixedIntegerRounding2 was tried 100 times and created 293 cuts of which 0 were active after adding rounds of cuts (0.018 seconds)
FlowCover was tried 100 times and created 2 cuts of which 0 were active after adding rounds of cuts (0.010 seconds)
TwoMirCuts was tried 100 times and created 208 cuts of which 0 were active after adding rounds of cuts (0.006 seconds)
ZeroHalf was tried 1 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)
ImplicationCuts was tried 33 times and created 503 cuts of which 0 were active after adding rounds of cuts (0.003 seconds)

Result - Optimal solution found

Objective value:                6.00000000
Enumerated nodes:               400
Total iterations:               17598
Time (CPU seconds):             0.78
Time (Wallclock seconds):       0.79

Option for printingOptions changed from normal to all
Total time (CPU seconds):       0.78   (Wallclock seconds):       0.79

[88]:
({'performance_table': <mcda.PerformanceTable at 0x7ea5ec473d60>,
  'criteria_weights': {'cost': 0.485,
   'fuel consumption': 0.02,
   'comfort': 0.01,
   'color': 0.02,
   'range': 0.465},
  'profiles': <mcda.PerformanceTable at 0x7ea5a03d3ca0>,
  'lexicographic_order': [0, 1]},
 1.0)
[89]:
srmp.profiles.data
[89]:
cost fuel consumption comfort color range
0 15460.00006 5.18 *** blue 856.0
1 6000.00000 4.10 **** red 1000.0
[90]:
rank = srmp.rank()
rank.data
[90]:
Fiat 500          1
Peugeot 309       4
Renault Clio      2
Opel Astra        4
Honda Civic       2
Toyota Corolla    3
dtype: int64
[91]:
PreferenceStructure.from_ranking(rank).plot()
[91]:
../../_images/notebooks_examples_outranking_algorithms_139_0.svg

You can also directly create and train a SRMP object:

[92]:
srmp = SRMP.learn(
    performance_table,
    relations,
    max_profiles_number=3,
    non_dictator=True,
    gamma=0.01,
)
rank = srmp.rank()
PreferenceStructure.from_ranking(rank).plot()
Welcome to the CBC MILP Solver
Version: 2.10.3
Build Date: Dec 15 2019

command line - /home/nduminy/Development/pymcda/.venv/lib/python3.10/site-packages/pulp/apis/../solverdir/cbc/linux/64/cbc /tmp/177cc7dc99824acbaf01c73c725c8ca3-pulp.mps max timeMode elapsed branch printingOptions all solution /tmp/177cc7dc99824acbaf01c73c725c8ca3-pulp.sol (default strategy 1)
At line 2 NAME          MODEL
At line 3 ROWS
At line 226 COLUMNS
At line 890 RHS
At line 1112 BOUNDS
At line 1193 ENDATA
Problem MODEL has 221 rows, 80 columns and 577 elements
Coin0008I MODEL read with 0 errors
Option for timeMode changed from cpu to elapsed
Continuous objective value is 6 - 0.00 seconds
Cgl0002I 4 variables fixed
Cgl0003I 0 fixed, 0 tightened bounds, 113 strengthened rows, 6 substitutions
Cgl0003I 0 fixed, 0 tightened bounds, 15 strengthened rows, 0 substitutions
Cgl0003I 0 fixed, 0 tightened bounds, 9 strengthened rows, 0 substitutions
Cgl0003I 0 fixed, 0 tightened bounds, 4 strengthened rows, 0 substitutions
Cgl0004I processed model has 127 rows, 59 columns (25 integer (25 of which binary)) and 470 elements
Cbc0045I 4 integer variables out of 25 objects (25 integer) have cost of -1 - high priority
Cbc0045I branch on satisfied Y create fake objective Y random cost Y
Cbc0038I Initial state - 6 integers unsatisfied sum - 1.58984
Cbc0038I Pass   1: suminf.    0.06000 (5) obj. -5.96 iterations 31
Cbc0038I Pass   2: suminf.    0.12791 (1) obj. -2 iterations 12
Cbc0038I Pass   3: suminf.    0.01000 (1) obj. -2 iterations 6
Cbc0038I Pass   4: suminf.    0.55318 (3) obj. -2 iterations 32
Cbc0038I Pass   5: suminf.    0.00000 (0) obj. -2 iterations 3
Cbc0038I Solution found of -2
Cbc0038I Relaxing continuous gives -2
Cbc0038I Rounding solution of -4 is better than previous of -2

Cbc0038I Before mini branch and bound, 9 integers at bound fixed and 13 continuous
Cbc0038I Full problem 127 rows 59 columns, reduced to 59 rows 30 columns
Cbc0038I Mini branch and bound improved solution from -4 to -5 (0.01 seconds)
Cbc0038I Round again with cutoff of -5.99991
Cbc0038I Reduced cost fixing fixed 4 variables on major pass 2
Cbc0038I Pass   6: suminf.    0.10000 (3) obj. -6 iterations 9
Cbc0038I Pass   7: suminf.    0.30648 (2) obj. -6 iterations 10
Cbc0038I Pass   8: suminf.    0.03000 (2) obj. -6 iterations 7
Cbc0038I Pass   9: suminf.    0.69056 (4) obj. -6 iterations 10
Cbc0038I Pass  10: suminf.    0.53390 (3) obj. -6 iterations 2
Cbc0038I Pass  11: suminf.    0.13857 (1) obj. -6 iterations 8
Cbc0038I Pass  12: suminf.    0.02000 (1) obj. -6 iterations 4
Cbc0038I Pass  13: suminf.    1.06374 (6) obj. -6 iterations 35
Cbc0038I Pass  14: suminf.    0.82457 (5) obj. -6 iterations 4
Cbc0038I Pass  15: suminf.    0.48974 (2) obj. -6 iterations 17
Cbc0038I Pass  16: suminf.    0.02000 (1) obj. -6 iterations 3
Cbc0038I Pass  17: suminf.    0.27632 (1) obj. -6 iterations 2
Cbc0038I Pass  18: suminf.    0.51445 (3) obj. -6 iterations 6
Cbc0038I Pass  19: suminf.    0.27632 (1) obj. -6 iterations 4
Cbc0038I Pass  20: suminf.    0.43298 (2) obj. -6 iterations 8
Cbc0038I Pass  21: suminf.    0.28632 (2) obj. -6 iterations 8
Cbc0038I Pass  22: suminf.    0.01000 (1) obj. -6 iterations 5
Cbc0038I Pass  23: suminf.    0.27632 (1) obj. -6 iterations 2
Cbc0038I Pass  24: suminf.    2.40354 (9) obj. -6 iterations 25
Cbc0038I Pass  25: suminf.    1.60240 (6) obj. -6 iterations 8
Cbc0038I Pass  26: suminf.    0.02000 (1) obj. -6 iterations 18
Cbc0038I Pass  27: suminf.    0.27632 (1) obj. -6 iterations 2
Cbc0038I Pass  28: suminf.    0.64640 (3) obj. -6 iterations 3
Cbc0038I Pass  29: suminf.    0.48974 (2) obj. -6 iterations 2
Cbc0038I Pass  30: suminf.    1.49385 (11) obj. -6 iterations 34
Cbc0038I Pass  31: suminf.    1.04675 (8) obj. -6 iterations 11
Cbc0038I Pass  32: suminf.    0.32454 (3) obj. -6 iterations 20
Cbc0038I Pass  33: suminf.    0.02000 (1) obj. -6 iterations 6
Cbc0038I Pass  34: suminf.    0.13857 (1) obj. -6 iterations 1
Cbc0038I Pass  35: suminf.    1.30417 (7) obj. -6 iterations 26
Cbc0038I Pass  36: suminf.    0.38000 (3) obj. -6 iterations 14
Cbc0038I Pass  37: suminf.    0.13857 (1) obj. -6 iterations 7
Cbc0038I Pass  38: suminf.    0.02000 (1) obj. -6 iterations 1
Cbc0038I Pass  39: suminf.    0.06714 (2) obj. -6 iterations 14
Cbc0038I Pass  40: suminf.    0.02000 (1) obj. -6 iterations 4
Cbc0038I Pass  41: suminf.    0.04714 (1) obj. -6 iterations 1
Cbc0038I Pass  42: suminf.    0.06051 (4) obj. -6 iterations 19
Cbc0038I Pass  43: suminf.    0.66190 (3) obj. -6 iterations 17
Cbc0038I Pass  44: suminf.    0.14791 (2) obj. -6 iterations 8
Cbc0038I Pass  45: suminf.    0.15857 (3) obj. -6 iterations 10
Cbc0038I Pass  46: suminf.    0.14791 (2) obj. -6 iterations 13
Cbc0038I Pass  47: suminf.    0.14857 (2) obj. -6 iterations 10
Cbc0038I Pass  48: suminf.    1.60308 (8) obj. -6 iterations 28
Cbc0038I Pass  49: suminf.    0.99479 (6) obj. -6 iterations 3
Cbc0038I Pass  50: suminf.    0.02000 (1) obj. -6 iterations 15
Cbc0038I Pass  51: suminf.    0.13857 (1) obj. -6 iterations 5
Cbc0038I Pass  52: suminf.    0.14437 (2) obj. -6 iterations 4
Cbc0038I Pass  53: suminf.    0.04000 (3) obj. -6 iterations 12
Cbc0038I Pass  54: suminf.    1.10842 (6) obj. -6 iterations 14
Cbc0038I Pass  55: suminf.    0.60547 (5) obj. -6 iterations 6
Cbc0038I Pass  56: suminf.    0.27632 (1) obj. -6 iterations 12
Cbc0038I Pass  57: suminf.    0.01000 (1) obj. -6 iterations 5
Cbc0038I Pass  58: suminf.    0.72419 (6) obj. -6 iterations 14
Cbc0038I Pass  59: suminf.    0.41560 (3) obj. -6 iterations 14
Cbc0038I Pass  60: suminf.    0.34847 (5) obj. -6 iterations 12
Cbc0038I Pass  61: suminf.    0.19180 (4) obj. -6 iterations 4
Cbc0038I Pass  62: suminf.    0.13857 (1) obj. -6 iterations 9
Cbc0038I Pass  63: suminf.    0.02000 (1) obj. -6 iterations 5
Cbc0038I Pass  64: suminf.    1.40651 (7) obj. -6 iterations 11
Cbc0038I Pass  65: suminf.    0.69667 (3) obj. -6 iterations 5
Cbc0038I Pass  66: suminf.    0.13857 (1) obj. -6 iterations 10
Cbc0038I Pass  67: suminf.    0.02000 (1) obj. -6 iterations 4
Cbc0038I Pass  68: suminf.    1.04037 (6) obj. -6 iterations 13
Cbc0038I Pass  69: suminf.    0.40000 (3) obj. -6 iterations 6
Cbc0038I Pass  70: suminf.    0.13857 (1) obj. -6 iterations 6
Cbc0038I Pass  71: suminf.    0.02000 (1) obj. -6 iterations 4
Cbc0038I Pass  72: suminf.    0.90187 (5) obj. -6 iterations 9
Cbc0038I Pass  73: suminf.    0.69667 (3) obj. -6 iterations 6
Cbc0038I Pass  74: suminf.    0.13857 (1) obj. -6 iterations 9
Cbc0038I Pass  75: suminf.    0.02000 (1) obj. -6 iterations 3
Cbc0038I Pass  76: suminf.    0.70391 (6) obj. -6 iterations 18
Cbc0038I Pass  77: suminf.    1.20866 (7) obj. -6 iterations 7
Cbc0038I Pass  78: suminf.    0.64790 (2) obj. -6 iterations 16
Cbc0038I Pass  79: suminf.    0.02000 (1) obj. -6 iterations 4
Cbc0038I Pass  80: suminf.    0.13857 (1) obj. -6 iterations 3
Cbc0038I Pass  81: suminf.    0.91417 (4) obj. -6 iterations 11
Cbc0038I Pass  82: suminf.    0.02000 (2) obj. -6 iterations 6
Cbc0038I Pass  83: suminf.    0.44880 (5) obj. -6 iterations 13
Cbc0038I Pass  84: suminf.    0.04000 (4) obj. -6 iterations 5
Cbc0038I Pass  85: suminf.    0.30648 (2) obj. -6 iterations 13
Cbc0038I Pass  86: suminf.    0.03000 (2) obj. -6 iterations 7
Cbc0038I Pass  87: suminf.    0.82524 (5) obj. -6 iterations 7
Cbc0038I Pass  88: suminf.    0.03000 (2) obj. -6 iterations 6
Cbc0038I Pass  89: suminf.    0.30648 (2) obj. -6 iterations 6
Cbc0038I Pass  90: suminf.    0.70208 (5) obj. -6 iterations 11
Cbc0038I Pass  91: suminf.    0.37212 (4) obj. -6 iterations 4
Cbc0038I Pass  92: suminf.    0.37212 (4) obj. -6 iterations 6
Cbc0038I Pass  93: suminf.    0.03000 (2) obj. -6 iterations 5
Cbc0038I Pass  94: suminf.    0.30648 (2) obj. -6 iterations 3
Cbc0038I Pass  95: suminf.    1.16023 (6) obj. -6 iterations 10
Cbc0038I Pass  96: suminf.    0.83038 (5) obj. -6 iterations 4
Cbc0038I Pass  97: suminf.    0.02000 (1) obj. -6 iterations 14
Cbc0038I Pass  98: suminf.    0.13857 (1) obj. -6 iterations 1
Cbc0038I Pass  99: suminf.    0.82315 (4) obj. -6 iterations 10
Cbc0038I Pass 100: suminf.    0.66648 (3) obj. -6 iterations 2
Cbc0038I Pass 101: suminf.    1.12816 (5) obj. -6 iterations 24
Cbc0038I Pass 102: suminf.    0.78830 (3) obj. -6 iterations 3
Cbc0038I Pass 103: suminf.    0.03000 (3) obj. -6 iterations 11
Cbc0038I Pass 104: suminf.    0.27632 (1) obj. -6 iterations 7
Cbc0038I Pass 105: suminf.    0.48236 (3) obj. -6 iterations 8
Cbc0038I No solution found this major pass
Cbc0038I Before mini branch and bound, 4 integers at bound fixed and 0 continuous
Cbc0038I Full problem 127 rows 59 columns, reduced to 127 rows 55 columns - 8 fixed gives 108, 47 - ok now
Cbc0038I Full problem 127 rows 59 columns, reduced to 88 rows 39 columns
Cbc0038I Mini branch and bound did not improve solution (0.02 seconds)
Cbc0038I After 0.02 seconds - Feasibility pump exiting with objective of -5 - took 0.02 seconds
Cbc0012I Integer solution of -5 found by feasibility pump after 0 iterations and 0 nodes (0.02 seconds)
Cbc0031I 34 added rows had average density of 23.088235
Cbc0013I At root node, 34 cuts changed objective from -6 to -6 in 100 passes
Cbc0014I Cut generator 0 (Probing) - 1349 row cuts average 2.6 elements, 0 column cuts (0 active)  in 0.014 seconds - new frequency is -100
Cbc0014I Cut generator 1 (Gomory) - 519 row cuts average 50.5 elements, 0 column cuts (0 active)  in 0.008 seconds - new frequency is -100
Cbc0014I Cut generator 2 (Knapsack) - 65 row cuts average 2.6 elements, 0 column cuts (0 active)  in 0.007 seconds - new frequency is -100
Cbc0014I Cut generator 3 (Clique) - 0 row cuts average 0.0 elements, 0 column cuts (0 active)  in 0.000 seconds - new frequency is -100
Cbc0014I Cut generator 4 (MixedIntegerRounding2) - 195 row cuts average 5.4 elements, 0 column cuts (0 active)  in 0.009 seconds - new frequency is -100
Cbc0014I Cut generator 5 (FlowCover) - 8 row cuts average 2.9 elements, 0 column cuts (0 active)  in 0.009 seconds - new frequency is -100
Cbc0014I Cut generator 6 (TwoMirCuts) - 165 row cuts average 6.4 elements, 0 column cuts (0 active)  in 0.003 seconds - new frequency is -100
Cbc0010I After 0 nodes, 1 on tree, -5 best solution, best possible -6 (0.12 seconds)
Cbc0001I Search completed - best objective -5, took 2389 iterations and 10 nodes (0.13 seconds)
Cbc0032I Strong branching done 72 times (761 iterations), fathomed 6 nodes and fixed 0 variables
Cbc0035I Maximum depth 4, 4 variables fixed on reduced cost
Cuts at root node changed objective from -6 to -6
Probing was tried 100 times and created 1349 cuts of which 0 were active after adding rounds of cuts (0.014 seconds)
Gomory was tried 100 times and created 519 cuts of which 0 were active after adding rounds of cuts (0.008 seconds)
Knapsack was tried 100 times and created 65 cuts of which 0 were active after adding rounds of cuts (0.007 seconds)
Clique was tried 100 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)
MixedIntegerRounding2 was tried 100 times and created 195 cuts of which 0 were active after adding rounds of cuts (0.009 seconds)
FlowCover was tried 100 times and created 8 cuts of which 0 were active after adding rounds of cuts (0.009 seconds)
TwoMirCuts was tried 100 times and created 165 cuts of which 0 were active after adding rounds of cuts (0.003 seconds)
ZeroHalf was tried 1 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)
ImplicationCuts was tried 15 times and created 127 cuts of which 0 were active after adding rounds of cuts (0.001 seconds)

Result - Optimal solution found

Objective value:                5.00000000
Enumerated nodes:               10
Total iterations:               2389
Time (CPU seconds):             0.13
Time (Wallclock seconds):       0.13

Option for printingOptions changed from normal to all
Total time (CPU seconds):       0.13   (Wallclock seconds):       0.13

Welcome to the CBC MILP Solver
Version: 2.10.3
Build Date: Dec 15 2019

command line - /home/nduminy/Development/pymcda/.venv/lib/python3.10/site-packages/pulp/apis/../solverdir/cbc/linux/64/cbc /tmp/1ed6c4ffc4f1431abc0560f2b8a62a1d-pulp.mps max timeMode elapsed branch printingOptions all solution /tmp/1ed6c4ffc4f1431abc0560f2b8a62a1d-pulp.sol (default strategy 1)
At line 2 NAME          MODEL
At line 3 ROWS
At line 427 COLUMNS
At line 1717 RHS
At line 2140 BOUNDS
At line 2290 ENDATA
Problem MODEL has 422 rows, 149 columns and 1135 elements
Coin0008I MODEL read with 0 errors
Option for timeMode changed from cpu to elapsed
Continuous objective value is 6 - 0.00 seconds
Cgl0002I 4 variables fixed
Cgl0003I 0 fixed, 0 tightened bounds, 234 strengthened rows, 12 substitutions
Cgl0003I 0 fixed, 0 tightened bounds, 49 strengthened rows, 0 substitutions
Cgl0003I 0 fixed, 0 tightened bounds, 24 strengthened rows, 0 substitutions
Cgl0003I 0 fixed, 0 tightened bounds, 4 strengthened rows, 0 substitutions
Cgl0003I 0 fixed, 0 tightened bounds, 1 strengthened rows, 0 substitutions
Cgl0004I processed model has 265 rows, 113 columns (50 integer (50 of which binary)) and 1018 elements
Cbc0045I 4 integer variables out of 50 objects (50 integer) have cost of -1 - high priority
Cbc0045I branch on satisfied Y create fake objective Y random cost Y
Cbc0038I Initial state - 10 integers unsatisfied sum - 3.01304
Cbc0038I Pass   1: suminf.    0.13980 (7) obj. -5.99 iterations 51
Cbc0038I Pass   2: suminf.    0.22603 (4) obj. -5 iterations 58
Cbc0038I Pass   3: suminf.    0.15000 (4) obj. -5 iterations 4
Cbc0038I Pass   4: suminf.    0.02990 (2) obj. -5 iterations 23
Cbc0038I Pass   5: suminf.    0.12000 (2) obj. -5 iterations 5
Cbc0038I Pass   6: suminf.    0.33500 (5) obj. -5.99 iterations 54
Cbc0038I Pass   7: suminf.    0.27500 (4) obj. -5.99 iterations 3
Cbc0038I Pass   8: suminf.    0.46620 (4) obj. -5 iterations 25
Cbc0038I Pass   9: suminf.    0.03000 (2) obj. -5 iterations 29
Cbc0038I Pass  10: suminf.    0.33442 (3) obj. -5 iterations 16
Cbc0038I Pass  11: suminf.    0.03000 (2) obj. -5 iterations 8
Cbc0038I Pass  12: suminf.    0.21575 (2) obj. -5 iterations 10
Cbc0038I Pass  13: suminf.    2.62712 (11) obj. -3 iterations 32
Cbc0038I Pass  14: suminf.    1.28788 (8) obj. -3 iterations 10
Cbc0038I Pass  15: suminf.    0.14360 (5) obj. -3 iterations 32
Cbc0038I Pass  16: suminf.    0.20605 (2) obj. -3 iterations 18
Cbc0038I Pass  17: suminf.    0.03970 (2) obj. -3 iterations 5
Cbc0038I Pass  18: suminf.    1.90808 (10) obj. -3 iterations 61
Cbc0038I Pass  19: suminf.    0.72101 (5) obj. -3 iterations 9
Cbc0038I Pass  20: suminf.    0.02000 (2) obj. -3 iterations 14
Cbc0038I Pass  21: suminf.    0.26407 (2) obj. -3 iterations 12
Cbc0038I Pass  22: suminf.    2.40338 (15) obj. -4 iterations 63
Cbc0038I Pass  23: suminf.    2.21306 (12) obj. -4 iterations 6
Cbc0038I Pass  24: suminf.    0.49258 (6) obj. -4 iterations 44
Cbc0038I Pass  25: suminf.    0.04990 (4) obj. -4 iterations 22
Cbc0038I Pass  26: suminf.    0.02000 (2) obj. -4 iterations 25
Cbc0038I Pass  27: suminf.    0.03980 (3) obj. -4 iterations 16
Cbc0038I Pass  28: suminf.    0.03000 (3) obj. -4 iterations 15
Cbc0038I Pass  29: suminf.    1.44298 (7) obj. -3 iterations 33
Cbc0038I Pass  30: suminf.    1.22298 (6) obj. -3 iterations 2
Cbc0038I Pass  31: suminf.    0.00000 (0) obj. -3 iterations 8
Cbc0038I Solution found of -3
Cbc0038I Relaxing continuous gives -3
Cbc0038I Rounding solution of -4 is better than previous of -3

Cbc0038I Before mini branch and bound, 6 integers at bound fixed and 9 continuous
Cbc0038I Full problem 265 rows 113 columns, reduced to 227 rows 96 columns - 4 fixed gives 219, 92 - still too large
Cbc0038I Mini branch and bound did not improve solution (0.02 seconds)
Cbc0038I Round again with cutoff of -5.09991
Cbc0038I Reduced cost fixing fixed 4 variables on major pass 2
Cbc0038I Pass  32: suminf.    0.13970 (7) obj. -6 iterations 1
Cbc0038I Pass  33: suminf.    0.22603 (4) obj. -6 iterations 60
Cbc0038I Pass  34: suminf.    0.15000 (4) obj. -6 iterations 7
Cbc0038I Pass  35: suminf.    0.02990 (2) obj. -6 iterations 16
Cbc0038I Pass  36: suminf.    0.12000 (2) obj. -6 iterations 6
Cbc0038I Pass  37: suminf.    2.70673 (12) obj. -6 iterations 59
Cbc0038I Pass  38: suminf.    1.41648 (9) obj. -6 iterations 7
Cbc0038I Pass  39: suminf.    1.41648 (9) obj. -6 iterations 0
Cbc0038I Pass  40: suminf.    0.21990 (2) obj. -6 iterations 34
Cbc0038I Pass  41: suminf.    0.17000 (1) obj. -6 iterations 5
Cbc0038I Pass  42: suminf.    0.17822 (1) obj. -6 iterations 1
Cbc0038I Pass  43: suminf.    0.77421 (7) obj. -6 iterations 33
Cbc0038I Pass  44: suminf.    0.53421 (6) obj. -6 iterations 1
Cbc0038I Pass  45: suminf.    0.23090 (3) obj. -6 iterations 21
Cbc0038I Pass  46: suminf.    0.01000 (1) obj. -6 iterations 18
Cbc0038I Pass  47: suminf.    0.00990 (1) obj. -6 iterations 1
Cbc0038I Pass  48: suminf.    2.26391 (12) obj. -6 iterations 40
Cbc0038I Pass  49: suminf.    1.97591 (11) obj. -6 iterations 1
Cbc0038I Pass  50: suminf.    0.19180 (3) obj. -6 iterations 40
Cbc0038I Pass  51: suminf.    0.01980 (1) obj. -6 iterations 7
Cbc0038I Pass  52: suminf.    0.01000 (1) obj. -6 iterations 1
Cbc0038I Pass  53: suminf.    1.30298 (6) obj. -6 iterations 34
Cbc0038I Pass  54: suminf.    0.77810 (4) obj. -6 iterations 3
Cbc0038I Pass  55: suminf.    0.02970 (1) obj. -6 iterations 14
Cbc0038I Pass  56: suminf.    0.02000 (1) obj. -6 iterations 1
Cbc0038I Pass  57: suminf.    1.02213 (5) obj. -6 iterations 22
Cbc0038I Pass  58: suminf.    0.01000 (1) obj. -6 iterations 11
Cbc0038I Pass  59: suminf.    0.01980 (1) obj. -6 iterations 1
Cbc0038I Pass  60: suminf.    1.24630 (8) obj. -6 iterations 30
Cbc0038I Pass  61: suminf.    0.84259 (8) obj. -6 iterations 9
Cbc0038I Pass  62: suminf.    0.29187 (7) obj. -6 iterations 2
Cbc0038I Pass  63: suminf.    0.01000 (1) obj. -6 iterations 24
Cbc0038I Pass  64: suminf.    0.01980 (1) obj. -6 iterations 1
Cbc0038I Pass  65: suminf.    1.67114 (9) obj. -6 iterations 53
Cbc0038I Pass  66: suminf.    1.08898 (6) obj. -6 iterations 9
Cbc0038I Pass  67: suminf.    0.36500 (2) obj. -6 iterations 15
Cbc0038I Pass  68: suminf.    0.26485 (1) obj. -6 iterations 4
Cbc0038I Pass  69: suminf.    0.25750 (1) obj. -6 iterations 1
Cbc0038I Pass  70: suminf.    1.85378 (10) obj. -6 iterations 28
Cbc0038I Pass  71: suminf.    1.15801 (7) obj. -6 iterations 6
Cbc0038I Pass  72: suminf.    0.11286 (2) obj. -6 iterations 19
Cbc0038I Pass  73: suminf.    0.00990 (1) obj. -6 iterations 3
Cbc0038I Pass  74: suminf.    0.01000 (1) obj. -6 iterations 1
Cbc0038I Pass  75: suminf.    0.92711 (6) obj. -6 iterations 39
Cbc0038I Pass  76: suminf.    0.45913 (6) obj. -6 iterations 11
Cbc0038I Pass  77: suminf.    0.18990 (3) obj. -6 iterations 20
Cbc0038I Pass  78: suminf.    0.01000 (1) obj. -6 iterations 10
Cbc0038I Pass  79: suminf.    0.00990 (1) obj. -6 iterations 2
Cbc0038I Pass  80: suminf.    1.69920 (6) obj. -6 iterations 35
Cbc0038I Pass  81: suminf.    1.00022 (4) obj. -6 iterations 2
Cbc0038I Pass  82: suminf.    0.01990 (2) obj. -6 iterations 19
Cbc0038I Pass  83: suminf.    0.01000 (1) obj. -6 iterations 4
Cbc0038I Pass  84: suminf.    0.00990 (1) obj. -6 iterations 1
Cbc0038I Pass  85: suminf.    0.80418 (8) obj. -6 iterations 47
Cbc0038I Pass  86: suminf.    0.75306 (8) obj. -6 iterations 14
Cbc0038I Pass  87: suminf.    1.10240 (8) obj. -6 iterations 41
Cbc0038I Pass  88: suminf.    0.37657 (4) obj. -6 iterations 23
Cbc0038I Pass  89: suminf.    0.01000 (1) obj. -6 iterations 12
Cbc0038I Pass  90: suminf.    0.00990 (1) obj. -6 iterations 2
Cbc0038I Pass  91: suminf.    0.31648 (3) obj. -6 iterations 33
Cbc0038I Pass  92: suminf.    0.00990 (1) obj. -6 iterations 11
Cbc0038I Pass  93: suminf.    0.01000 (1) obj. -6 iterations 4
Cbc0038I Pass  94: suminf.    1.38541 (9) obj. -6 iterations 25
Cbc0038I Pass  95: suminf.    1.38541 (9) obj. -6 iterations 0
Cbc0038I Pass  96: suminf.    1.06464 (5) obj. -6 iterations 32
Cbc0038I Pass  97: suminf.    0.34214 (3) obj. -6 iterations 5
Cbc0038I Pass  98: suminf.    0.00990 (1) obj. -6 iterations 7
Cbc0038I Pass  99: suminf.    0.01000 (1) obj. -6 iterations 1
Cbc0038I Pass 100: suminf.    2.10334 (10) obj. -6 iterations 43
Cbc0038I Pass 101: suminf.    1.92334 (9) obj. -6 iterations 1
Cbc0038I Pass 102: suminf.    0.73865 (6) obj. -6 iterations 38
Cbc0038I Pass 103: suminf.    0.36158 (3) obj. -6 iterations 35
Cbc0038I Pass 104: suminf.    0.14000 (2) obj. -6 iterations 14
Cbc0038I Pass 105: suminf.    0.05960 (4) obj. -6 iterations 12
Cbc0038I Pass 106: suminf.    0.15000 (4) obj. -6 iterations 8
Cbc0038I Pass 107: suminf.    1.16574 (8) obj. -6 iterations 34
Cbc0038I Pass 108: suminf.    0.16000 (4) obj. -6 iterations 26
Cbc0038I Pass 109: suminf.    0.04970 (2) obj. -6 iterations 8
Cbc0038I Pass 110: suminf.    0.14000 (2) obj. -6 iterations 7
Cbc0038I Pass 111: suminf.    2.90779 (21) obj. -6 iterations 105
Cbc0038I Pass 112: suminf.    2.29405 (12) obj. -6 iterations 19
Cbc0038I Pass 113: suminf.    0.78243 (8) obj. -6 iterations 45
Cbc0038I Pass 114: suminf.    0.63621 (6) obj. -6 iterations 24
Cbc0038I Pass 115: suminf.    0.07941 (5) obj. -6 iterations 16
Cbc0038I Pass 116: suminf.    0.34461 (5) obj. -6 iterations 16
Cbc0038I Pass 117: suminf.    1.66714 (11) obj. -6 iterations 47
Cbc0038I Pass 118: suminf.    0.66868 (6) obj. -6 iterations 7
Cbc0038I Pass 119: suminf.    0.54694 (5) obj. -6 iterations 31
Cbc0038I Pass 120: suminf.    0.35333 (5) obj. -6 iterations 19
Cbc0038I Pass 121: suminf.    0.38691 (3) obj. -6 iterations 17
Cbc0038I Pass 122: suminf.    0.27470 (3) obj. -6 iterations 14
Cbc0038I Pass 123: suminf.    0.24391 (5) obj. -6 iterations 15
Cbc0038I Pass 124: suminf.    0.57854 (7) obj. -6 iterations 22
Cbc0038I Pass 125: suminf.    0.62246 (9) obj. -6 iterations 29
Cbc0038I Pass 126: suminf.    0.69971 (6) obj. -6 iterations 33
Cbc0038I Pass 127: suminf.    0.04000 (4) obj. -6 iterations 20
Cbc0038I Pass 128: suminf.    0.15260 (4) obj. -6 iterations 12
Cbc0038I Pass 129: suminf.    0.04990 (4) obj. -6 iterations 17
Cbc0038I Pass 130: suminf.    0.24614 (2) obj. -6 iterations 22
Cbc0038I Pass 131: suminf.    0.99880 (7) obj. -6 iterations 41
Cbc0038I Rounding solution of -5 is better than previous of -4

Cbc0038I Before mini branch and bound, 4 integers at bound fixed and 5 continuous
Cbc0038I Full problem 265 rows 113 columns, reduced to 255 rows 104 columns - 6 fixed gives 238, 97 - still too large
Cbc0038I Mini branch and bound did not improve solution (0.04 seconds)
Cbc0038I Round again with cutoff of -5.99992
Cbc0038I Reduced cost fixing fixed 4 variables on major pass 3
Cbc0038I Pass 131: suminf.    0.13970 (7) obj. -6 iterations 0
Cbc0038I Pass 132: suminf.    0.22603 (4) obj. -6 iterations 63
Cbc0038I Pass 133: suminf.    0.15000 (4) obj. -6 iterations 6
Cbc0038I Pass 134: suminf.    0.02990 (2) obj. -6 iterations 19
Cbc0038I Pass 135: suminf.    0.12000 (2) obj. -6 iterations 6
Cbc0038I Pass 136: suminf.    2.04742 (14) obj. -6 iterations 56
Cbc0038I Pass 137: suminf.    1.10993 (8) obj. -6 iterations 20
Cbc0038I Pass 138: suminf.    0.05970 (5) obj. -6 iterations 29
Cbc0038I Pass 139: suminf.    0.47826 (6) obj. -6 iterations 25
Cbc0038I Pass 140: suminf.    0.06990 (3) obj. -6 iterations 20
Cbc0038I Pass 141: suminf.    0.12000 (2) obj. -6 iterations 18
Cbc0038I Pass 142: suminf.    0.04990 (2) obj. -6 iterations 8
Cbc0038I Pass 143: suminf.    0.27660 (5) obj. -6 iterations 11
Cbc0038I Pass 144: suminf.    0.20304 (3) obj. -6 iterations 3
Cbc0038I Pass 145: suminf.    0.20314 (3) obj. -6 iterations 5
Cbc0038I Pass 146: suminf.    1.47606 (14) obj. -6 iterations 46
Cbc0038I Pass 147: suminf.    0.90453 (7) obj. -6 iterations 23
Cbc0038I Pass 148: suminf.    0.20314 (3) obj. -6 iterations 24
Cbc0038I Pass 149: suminf.    0.20304 (3) obj. -6 iterations 5
Cbc0038I Pass 150: suminf.    3.83220 (18) obj. -6 iterations 53
Cbc0038I Pass 151: suminf.    1.24278 (11) obj. -6 iterations 44
Cbc0038I Pass 152: suminf.    0.58221 (8) obj. -6 iterations 39
Cbc0038I Pass 153: suminf.    0.29970 (4) obj. -6 iterations 27
Cbc0038I Pass 154: suminf.    0.04980 (3) obj. -6 iterations 12
Cbc0038I Pass 155: suminf.    0.04970 (3) obj. -6 iterations 8
Cbc0038I Pass 156: suminf.    2.57768 (11) obj. -6 iterations 31
Cbc0038I Pass 157: suminf.    1.61025 (9) obj. -6 iterations 6
Cbc0038I Pass 158: suminf.    0.05000 (2) obj. -6 iterations 30
Cbc0038I Pass 159: suminf.    0.11990 (2) obj. -6 iterations 3
Cbc0038I Pass 160: suminf.    1.16640 (8) obj. -6 iterations 30
Cbc0038I Pass 161: suminf.    0.32638 (4) obj. -6 iterations 22
Cbc0038I Pass 162: suminf.    0.04667 (4) obj. -6 iterations 15
Cbc0038I Pass 163: suminf.    0.13970 (2) obj. -6 iterations 18
Cbc0038I Pass 164: suminf.    0.04000 (2) obj. -6 iterations 7
Cbc0038I Pass 165: suminf.    2.15711 (12) obj. -6 iterations 49
Cbc0038I Pass 166: suminf.    0.48834 (7) obj. -6 iterations 23
Cbc0038I Pass 167: suminf.    0.51864 (3) obj. -6 iterations 20
Cbc0038I Pass 168: suminf.    0.26000 (3) obj. -6 iterations 13
Cbc0038I Pass 169: suminf.    1.57443 (13) obj. -6 iterations 54
Cbc0038I Pass 170: suminf.    1.10770 (9) obj. -6 iterations 10
Cbc0038I Pass 171: suminf.    0.02000 (2) obj. -6 iterations 30
Cbc0038I Pass 172: suminf.    0.00990 (1) obj. -6 iterations 5
Cbc0038I Pass 173: suminf.    0.01000 (1) obj. -6 iterations 3
Cbc0038I Pass 174: suminf.    1.15607 (10) obj. -6 iterations 41
Cbc0038I Pass 175: suminf.    0.83274 (9) obj. -6 iterations 10
Cbc0038I Pass 176: suminf.    0.80093 (7) obj. -6 iterations 27
Cbc0038I Pass 177: suminf.    0.17445 (5) obj. -6 iterations 8
Cbc0038I Pass 178: suminf.    0.02513 (3) obj. -6 iterations 19
Cbc0038I Pass 179: suminf.    0.37822 (4) obj. -6 iterations 22
Cbc0038I Pass 180: suminf.    0.28000 (2) obj. -6 iterations 16
Cbc0038I Pass 181: suminf.    0.19822 (2) obj. -6 iterations 11
Cbc0038I Pass 182: suminf.    3.13051 (16) obj. -6 iterations 48
Cbc0038I Pass 183: suminf.    2.19117 (13) obj. -6 iterations 5
Cbc0038I Pass 184: suminf.    0.58922 (7) obj. -6 iterations 43
Cbc0038I Pass 185: suminf.    0.13276 (4) obj. -6 iterations 18
Cbc0038I Pass 186: suminf.    0.01000 (1) obj. -6 iterations 12
Cbc0038I Pass 187: suminf.    0.01980 (1) obj. -6 iterations 1
Cbc0038I Pass 188: suminf.    2.36747 (13) obj. -6 iterations 44
Cbc0038I Pass 189: suminf.    1.80045 (9) obj. -6 iterations 6
Cbc0038I Pass 190: suminf.    0.39311 (7) obj. -6 iterations 29
Cbc0038I Pass 191: suminf.    0.38998 (7) obj. -6 iterations 7
Cbc0038I Pass 192: suminf.    0.38342 (6) obj. -6 iterations 6
Cbc0038I Pass 193: suminf.    0.54495 (5) obj. -6 iterations 21
Cbc0038I Pass 194: suminf.    0.36158 (3) obj. -6 iterations 10
Cbc0038I Pass 195: suminf.    0.36149 (3) obj. -6 iterations 4
Cbc0038I Pass 196: suminf.    2.09348 (16) obj. -6 iterations 70
Cbc0038I Pass 197: suminf.    1.38278 (11) obj. -6 iterations 15
Cbc0038I Pass 198: suminf.    0.56040 (6) obj. -6 iterations 46
Cbc0038I Pass 199: suminf.    0.04493 (4) obj. -6 iterations 14
Cbc0038I Pass 200: suminf.    0.37000 (4) obj. -6 iterations 24
Cbc0038I Pass 201: suminf.    0.28822 (2) obj. -6 iterations 16
Cbc0038I Pass 202: suminf.    0.19000 (2) obj. -6 iterations 11
Cbc0038I Pass 203: suminf.    1.29512 (10) obj. -6 iterations 84
Cbc0038I Pass 204: suminf.    0.47907 (6) obj. -6 iterations 10
Cbc0038I Pass 205: suminf.    0.00990 (1) obj. -6 iterations 14
Cbc0038I Pass 206: suminf.    0.01000 (1) obj. -6 iterations 1
Cbc0038I Pass 207: suminf.    1.59842 (12) obj. -6 iterations 49
Cbc0038I Pass 208: suminf.    0.93603 (9) obj. -6 iterations 6
Cbc0038I Pass 209: suminf.    0.09333 (1) obj. -6 iterations 36
Cbc0038I Pass 210: suminf.    0.01000 (1) obj. -6 iterations 8
Cbc0038I Pass 211: suminf.    0.00990 (1) obj. -6 iterations 1
Cbc0038I Pass 212: suminf.    1.20839 (6) obj. -6 iterations 24
Cbc0038I Pass 213: suminf.    0.25750 (1) obj. -6 iterations 21
Cbc0038I Pass 214: suminf.    0.26485 (1) obj. -6 iterations 1
Cbc0038I Pass 215: suminf.    1.29667 (5) obj. -6 iterations 20
Cbc0038I Pass 216: suminf.    1.03000 (3) obj. -6 iterations 2
Cbc0038I Pass 217: suminf.    0.00990 (1) obj. -6 iterations 8
Cbc0038I Pass 218: suminf.    0.01000 (1) obj. -6 iterations 1
Cbc0038I Pass 219: suminf.    0.62495 (12) obj. -6 iterations 41
Cbc0038I Pass 220: suminf.    0.20317 (9) obj. -6 iterations 8
Cbc0038I Pass 221: suminf.    0.55470 (6) obj. -6 iterations 29
Cbc0038I Pass 222: suminf.    0.02980 (3) obj. -6 iterations 11
Cbc0038I Pass 223: suminf.    0.02990 (3) obj. -6 iterations 5
Cbc0038I Pass 224: suminf.    2.09610 (13) obj. -6 iterations 69
Cbc0038I Pass 225: suminf.    1.35597 (10) obj. -6 iterations 11
Cbc0038I Pass 226: suminf.    0.54000 (7) obj. -6 iterations 46
Cbc0038I Pass 227: suminf.    0.55137 (5) obj. -6 iterations 20
Cbc0038I Pass 228: suminf.    0.12000 (2) obj. -6 iterations 13
Cbc0038I Pass 229: suminf.    0.02990 (2) obj. -6 iterations 10
Cbc0038I Pass 230: suminf.    1.46293 (11) obj. -6 iterations 44
Cbc0038I No solution found this major pass
Cbc0038I Before mini branch and bound, 4 integers at bound fixed and 2 continuous
Cbc0038I Full problem 265 rows 113 columns, reduced to 261 rows 107 columns - 3 fixed gives 253, 104 - still too large
Cbc0038I Mini branch and bound did not improve solution (0.08 seconds)
Cbc0038I After 0.08 seconds - Feasibility pump exiting with objective of -5 - took 0.08 seconds
Cbc0012I Integer solution of -5 found by feasibility pump after 0 iterations and 0 nodes (0.08 seconds)
Cbc0038I Full problem 265 rows 113 columns, reduced to 145 rows 54 columns - 10 fixed gives 97, 40 - ok now
Cbc0038I Full problem 265 rows 113 columns, reduced to 56 rows 24 columns
Cbc0031I 52 added rows had average density of 17.288462
Cbc0013I At root node, 52 cuts changed objective from -6 to -6 in 100 passes
Cbc0014I Cut generator 0 (Probing) - 1276 row cuts average 2.6 elements, 0 column cuts (1 active)  in 0.028 seconds - new frequency is -100
Cbc0014I Cut generator 1 (Gomory) - 1252 row cuts average 93.3 elements, 0 column cuts (0 active)  in 0.018 seconds - new frequency is -100
Cbc0014I Cut generator 2 (Knapsack) - 69 row cuts average 3.6 elements, 0 column cuts (0 active)  in 0.010 seconds - new frequency is -100
Cbc0014I Cut generator 3 (Clique) - 0 row cuts average 0.0 elements, 0 column cuts (0 active)  in 0.001 seconds - new frequency is -100
Cbc0014I Cut generator 4 (MixedIntegerRounding2) - 293 row cuts average 6.4 elements, 0 column cuts (0 active)  in 0.018 seconds - new frequency is -100
Cbc0014I Cut generator 5 (FlowCover) - 2 row cuts average 3.0 elements, 0 column cuts (0 active)  in 0.010 seconds - new frequency is -100
Cbc0014I Cut generator 6 (TwoMirCuts) - 208 row cuts average 16.7 elements, 0 column cuts (0 active)  in 0.007 seconds - new frequency is -100
Cbc0010I After 0 nodes, 1 on tree, -5 best solution, best possible -6 (0.28 seconds)
Cbc0038I Full problem 265 rows 113 columns, reduced to 95 rows 42 columns
Cbc0038I Full problem 265 rows 113 columns, reduced to 98 rows 42 columns
Cbc0038I Full problem 265 rows 113 columns, reduced to 58 rows 27 columns
Cbc0012I Integer solution of -6 found by DiveCoefficient after 17598 iterations and 400 nodes (0.79 seconds)
Cbc0001I Search completed - best objective -6, took 17598 iterations and 400 nodes (0.79 seconds)
Cbc0032I Strong branching done 2976 times (36232 iterations), fathomed 148 nodes and fixed 75 variables
Cbc0035I Maximum depth 14, 4 variables fixed on reduced cost
Cuts at root node changed objective from -6 to -6
Probing was tried 100 times and created 1276 cuts of which 1 were active after adding rounds of cuts (0.028 seconds)
Gomory was tried 100 times and created 1252 cuts of which 0 were active after adding rounds of cuts (0.018 seconds)
Knapsack was tried 100 times and created 69 cuts of which 0 were active after adding rounds of cuts (0.010 seconds)
Clique was tried 100 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.001 seconds)
MixedIntegerRounding2 was tried 100 times and created 293 cuts of which 0 were active after adding rounds of cuts (0.018 seconds)
FlowCover was tried 100 times and created 2 cuts of which 0 were active after adding rounds of cuts (0.010 seconds)
TwoMirCuts was tried 100 times and created 208 cuts of which 0 were active after adding rounds of cuts (0.007 seconds)
ZeroHalf was tried 1 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)
ImplicationCuts was tried 33 times and created 503 cuts of which 0 were active after adding rounds of cuts (0.003 seconds)

Result - Optimal solution found

Objective value:                6.00000000
Enumerated nodes:               400
Total iterations:               17598
Time (CPU seconds):             0.78
Time (Wallclock seconds):       0.79

Option for printingOptions changed from normal to all
Total time (CPU seconds):       0.78   (Wallclock seconds):       0.79

[92]:
../../_images/notebooks_examples_outranking_algorithms_141_1.svg
[ ]: