Node:MIP, Next:Implementation Architecture, Previous:Syntactic Sugar, Up:CLPQR
The predicates bb_inf/3, bb_inf/5 implement a simple
Branch and Bound search algorithm for Mixed Integer Linear (MIP) Optimization
examples. Serious MIP is not trivial. The implementation
library('clpqr/bb.pl') is to be understood as a starting point
for more ambitious users who need control over branching, or who
want to add cutting planes, for example.
Anyway, here is a small
problem from miplib, a collection of MIP models, housed at
Rice University:
NAME: flugpl
ROWS: 18
COLUMNS: 18
INTEGER: 11
NONZERO: 46
BEST SOLN: 1201500 (opt)
LP SOLN: 1167185.73
SOURCE: Harvey M. Wagner
John W. Gregory (Cray Research)
E. Andrew Boyd (Rice University)
APPLICATION: airline model
COMMENTS: no integer variables are binary
%
% from file: library('clpqr/examples/mip')
%
example(flugpl, Obj, Vs, Ints, []) :-
Vs = [ Anm1,Anm2,Anm3,Anm4,Anm5,Anm6,
Stm1,Stm2,Stm3,Stm4,Stm5,Stm6,
UE1,UE2,UE3,UE4,UE5,UE6],
Ints = [Stm6, Stm5, Stm4, Stm3, Stm2,
Anm6, Anm5, Anm4, Anm3, Anm2, Anm1],
Obj = 2700*Stm1 + 1500*Anm1 + 30*UE1
+ 2700*Stm2 + 1500*Anm2 + 30*UE2
+ 2700*Stm3 + 1500*Anm3 + 30*UE3
+ 2700*Stm4 + 1500*Anm4 + 30*UE4
+ 2700*Stm5 + 1500*Anm5 + 30*UE5
+ 2700*Stm6 + 1500*Anm6 + 30*UE6,
allpos(Vs),
{ Stm1 = 60, 0.9*Stm1 +1*Anm1 -1*Stm2 = 0,
0.9*Stm2 +1*Anm2 -1*Stm3 = 0, 0.9*Stm3 +1*Anm3 -1*Stm4 = 0,
0.9*Stm4 +1*Anm4 -1*Stm5 = 0, 0.9*Stm5 +1*Anm5 -1*Stm6 = 0,
150*Stm1 -100*Anm1 +1*UE1 >= 8000,
150*Stm2 -100*Anm2 +1*UE2 >= 9000,
150*Stm3 -100*Anm3 +1*UE3 >= 8000,
150*Stm4 -100*Anm4 +1*UE4 >= 10000,
150*Stm5 -100*Anm5 +1*UE5 >= 9000,
150*Stm6 -100*Anm6 +1*UE6 >= 12000,
-20*Stm1 +1*UE1 =< 0, -20*Stm2 +1*UE2 =< 0, -20*Stm3 +1*UE3 =< 0,
-20*Stm4 +1*UE4 =< 0, -20*Stm5 +1*UE5 =< 0, -20*Stm6 +1*UE6 =< 0,
Anm1 =< 18, 57 =< Stm2, Stm2 =< 75, Anm2 =< 18,
57 =< Stm3, Stm3 =< 75, Anm3 =< 18, 57 =< Stm4,
Stm4 =< 75, Anm4 =< 18, 57 =< Stm5, Stm5 =< 75,
Anm5 =< 18, 57 =< Stm6, Stm6 =< 75, Anm6 =< 18
}.
allpos([]).
allpos([X|Xs]) :- {X >= 0}, allpos(Xs).
We can first check whether the relaxed problem has indeed the quoted
infimum:
clp(r) ?- example(flugpl, Obj, _, _, _), inf(Obj, Inf). Inf = 1167185.7255923203
Computing the infimum under the additional constraints that Stm6,
Stm5, Stm4, Stm3, Stm2, Anm6,
Anm5, Anm4, Anm3, Anm2, Anm1 assume
integer values at the infimum is computationally harder, but the query
does not change much:
clp(r) ?- example(flugpl, Obj, _, Ints, _),
bb_inf(Ints, Obj, Inf, Vertex, 0.001).
Inf = 1201500.0000000005,
Vertex = [75.0,70.0,70.0,60.0,60.0,0.0,12.0,7.0,16.0,6.0,6.0]