# Linear Programming

I wonder if there is not a little display bug inside the SageMath linear program since the display of the result here is given before the display of the program (for some other programs it is given inside).

# Nombre de contraintes et de variables.
nmd, mmd = 10, 6
# Coefficients pour chaque contrainte.
coeffs = [(250, 770, 360, 190, 230, -1),
(0, 0, 0, 0, 0, 1),
(31, 44, 14, 27, 3, 0),
(480, 1770, 800, 580, 160, 0),
(1, 0, 0, 0, 0, 0),
(0, 1, 0, 0, 0, 0),
(0, 0, 1, 0, 0, 0),
(0, 0, 0, 1, 0, 0),
(0, 0, 0, 0, 1, 0),
(0, 0, 0, 0, 0, 1)]
# Matrice des contraintes.
Amd = matrix(nmd, mmd, coeffs)
# Bornes inférieures pour les contraintes.
bmdmin = [0, 600, 30, 0, 0, 0, 0, 0, 0]
# Bornes supérieures pour les  contraintes (oo = infini).
bmdmax = [0, 900, 1000, oo, oo, oo, oo, oo, oo, oo]
# Visualisons.
show(LatexExpr("A="), Amd)
show(LatexExpr("bmin="), bmdmin)
show(LatexExpr("bmax="), bmdmax)
# On crée le programme de maximisation.
md = MixedIntegerLinearProgram(maximization=False, solver="GLPK")
# Nouvelles variables: x_0 ... x_2; 'integer' dit si variables à valeurs entières
x = md.new_variable(integer=False, nonnegative=True, indices=[0 .. mmd - 1])
# Fonction linéaire pour les contraintes.
Bmd = Amd * x
# On fixe l'objectif.
md.set_objective(1.2*x + 4.5*x + 3.7*x + 6.3*x + 3.2*x)
# On construit les contraintes avec leurs bornes.
for i in range(0,4):
md.show()
md.solve()
md.get_values(x)
xmd = md.get_values(x)
# Le résultat.
show(xmd)


Output:

𝐴=(...)
𝑏𝑚𝑖𝑛=[0,600,30,0,0,0,0,0,0]
𝑏𝑚𝑎𝑥=[0,900,1000,+∞,+∞,+∞,+∞,+∞,+∞,+∞]

Minimization:
1.2 x_0 + 4.5 x_1 + 3.7 x_2 + 6.3 x_3 + 3.2 x_4

Constraints:
0.0 <= 250.0 x_0 + 770.0 x_1 + 360.0 x_2 + 190.0 x_3 + 230.0 x_4 - x_5 <= 0.0
600.0 <= x_5 <= 900.0
30.0 <= 31.0 x_0 + 44.0 x_1 + 14.0 x_2 + 27.0 x_3 + 3.0 x_4 <= 1000.0
0.0 <= 480.0 x_0 + 1770.0 x_1 + 800.0 x_2 + 580.0 x_3 + 160.0 x_4 <= inf
Variables:
x_0 is a continuous variable (min=0.0, max=+oo)
x_1 is a continuous variable (min=0.0, max=+oo)
x_2 is a continuous variable (min=0.0, max=+oo)
x_3 is a continuous variable (min=0.0, max=+oo)
x_4 is a continuous variable (min=0.0, max=+oo)
x_5 is a continuous variable (min=0.0, max=+oo)

{0:2.4000000000000004,1:0.0,2:0.0,3:0.0,4:0.0,5:600.0000000000001}


Of course I am aware that without the show() command there is no problem. But, for uniformity of presentation I need this command. As I could call it in an other cell the problem an be circumvented. But for economic reasons I would prefer to have the code and the result in the same cell. Nevertheless, this is just a remark.

Edit to address a comment by slelievre.

Inside a notebook this works perfectly. But inside a "Sage Cell" here is the result:

𝐴=(...)
𝑏𝑚𝑖𝑛=[0,600,30,0,0,0,0,0,0]
𝑏𝑚𝑎𝑥=[0,900,1000,+∞,+∞,+∞,+∞,+∞,+∞,+∞]

{0:2.4000000000000004,1:0.0,2:0.0,3:0.0,4:0.0,5:600.0000000000001}

Minimization:
1.2 x_0 + 4.5 x_1 + 3.7 x_2 + 6.3 x_3 + 3.2 x_4

Constraints:
0.0 <= 250.0 x_0 + 770.0 x_1 + 360.0 x_2 + 190.0 x_3 + 230.0 x_4 - x_5 <= 0.0
600.0 <= x_5 <= 900.0
30.0 <= 31.0 x_0 + 44.0 x_1 + 14.0 x_2 + 27.0 x_3 + 3.0 x_4 <= 1000.0
0.0 <= 480.0 x_0 + 1770.0 x_1 + 800.0 x_2 + 580.0 x_3 + 160.0 x_4 <= inf
Variables:
x_0 is a continuous variable (min=0.0, max=+oo)
x_1 is a continuous variable (min=0.0, max=+oo)
x_2 is a continuous variable (min=0.0, max=+oo)
x_3 is a continuous variable (min=0.0, max=+oo)
x_4 is a continuous variable (min=0.0, max=+oo)
x_5 is a continuous variable (min=0.0, max=+oo)


That is, the result, {0:2.40...,1:0.0,2:0.0,3:0.0,4:0.0,5:600.00...}, is printed before the program's output, and sometimes inside it.

edit retag close merge delete

Minimal, reproducible examples go a long way to attract answers.

Edited question to add the output I am getting.

Is that the output you see too? What would be the alternative desired output?

Thanks the edit adding what output you get and how that differs from what you expect.

That clarifies the question.

Sort by » oldest newest most voted

The command md.show() prints various lines of output.

The way printing is done might explain the out-of-orderness.

In Python, when using print, the string to be printed is put in a queue of things to be printed. Once in a while, that queue is "flushed" and the printing actually occurs.

When other commands send things to the output zone, depending on flushing, they might appear out of order.

Sometimes one can remedy the problem by forcing flushing, which can be done using print('bla', flush=True); but here the print comes from some function, not user code.

The other way to remedy the problem, once we are aware that some operations are a bit slow and might lead to such out-of-order output, is to add some pauses, using sleep.

The command sleep takes as an argument a number of seconds, which can be an integer or a float. If a float, it must be a Python float, not a Sage "real number".

Below we add a short sleep, using the raw float 0.5r as the argument to sleep, where r is for "raw", which tells the Sage preparser to leave this as the Python float 0.5, instead of transforming it to the Sage "real number" RealNumber('0.5').

# Nombre de contraintes et de variables.
nmd, mmd = 10, 6
# Coefficients pour chaque contrainte.
coeffs = [(250, 770, 360, 190, 230, -1),
(0, 0, 0, 0, 0, 1),
(31, 44, 14, 27, 3, 0),
(480, 1770, 800, 580, 160, 0),
(1, 0, 0, 0, 0, 0),
(0, 1, 0, 0, 0, 0),
(0, 0, 1, 0, 0, 0),
(0, 0, 0, 1, 0, 0),
(0, 0, 0, 0, 1, 0),
(0, 0, 0, 0, 0, 1)]
# Matrice des contraintes.
Amd = matrix(nmd, mmd, coeffs)
# Bornes inférieures pour les contraintes.
bmdmin = [0, 600, 30, 0, 0, 0, 0, 0, 0]
# Bornes supérieures pour les  contraintes (oo = infini).
bmdmax = [0, 900, 1000, oo, oo, oo, oo, oo, oo, oo]
# Visualisons.
show(LatexExpr("A="), Amd)
show(LatexExpr("bmin="), bmdmin)
show(LatexExpr("bmax="), bmdmax)
# On crée le programme de maximisation.
md = MixedIntegerLinearProgram(maximization=False, solver="GLPK")
# Nouvelles variables: x_0 ... x_2; 'integer' dit si variables à valeurs entières
x = md.new_variable(integer=False, nonnegative=True, indices=[0 .. mmd - 1])
# Fonction linéaire pour les contraintes.
Bmd = Amd * x
# On fixe l'objectif.
md.set_objective(1.2*x + 4.5*x + 3.7*x + 6.3*x + 3.2*x)
# On construit les contraintes avec leurs bornes.
for i in range(0,4):
md.show()
sleep(0.5r)  # short sleep to prevent out-of-order display          <---  !!
md.solve()
xmd = md.get_values(x)
# Le résultat.
show(xmd)


Before adding the sleep(0.5r) line, the out-of-order display reported in the question can be observed.

Adding the short sleep seems to alleviate the problem:

more

Obviously after that I can't see trully a latency. Is very nice.