Description
J. Brimberg, P. Hansen, K.-W. Lih, N. Mladenovic, M. Breton 2003. An Oil Pipeline Design Problem. Operations Research, Vol 51, No. 2 228-239 Keywords: mixed integer linear programming, pipeline designment, network optimization
Large Model of Type : MIP
Category : GAMS Model library
Main file : ccoil.gms
$title Oil Pipeline Design Problem using concurrent MIP solves (CCOIL,SEQ=370)
$onText
J. Brimberg, P. Hansen, K.-W. Lih, N. Mladenovic, M. Breton 2003.
An Oil Pipeline Design Problem. Operations Research, Vol 51, No. 2 228-239
Keywords: mixed integer linear programming, pipeline designment, network optimization
$offText
Set
n 'nodes in the oil pipeline network'
nw(n) 'subset of nodes'
k 'type of oil pipe'
kk(k) 'reduced set of pipe line types'
regnode(n) 'non-port nodes'
port(n) 'port'
arc(n,n) 'arcs in the network';
Parameter
cap(k) 'capacity of type k oil pipe'
pipecost(k) 'monetary units for type k capacity'
p(n) 'production at each node'
edgedist(n,n) 'one way distance'
dist(n,n) 'the distance of the arcs';
Scalar
cap1 'capacity of type 1 oil pipe'
pipecost1 'monetary units for pipe of type 1';
Alias (n,m);
Variable
bk(n,n,k) 'build variable for type k pipe on the arc'
b(n,n) 'build variable for some pipe on the arc'
f(n,n) 'flow variable on the arc'
cost 'the cost for installing pipes in the network';
Binary Variable bk, b;
Positive Variable f;
Equation
obj 'oil pipeline network construction cost'
oneout(n) 'at most one out-flow each node'
oneoutp(n) 'one out-flow for each production node'
bal(n) 'flow conservation constraints'
bigM(n,n) 'the flow capacity constraints'
defb(n,n) 'additional pipe constraint';
obj.. sum(arc(nw,n), dist(arc)*(pipecost1*b(arc)
+ sum(kk, pipecost(kk)*bk(arc,kk))))
=e= cost;
oneout(m)$(not p(m)).. sum((arc(m,n)), b(m,n)) =l= 1;
oneoutp(m)$p(m).. sum((arc(m,n)), b(m,n)) =e= 1;
bal(regnode(nw)).. p(nw) =e= sum(arc(nw,m), f(nw,m)) - sum(arc(m,nw), f(m,nw));
bigM(arc(nw,n)).. cap1*b(arc) + sum(kk, cap(kk)*bk(arc,kk)) =g= f(arc);
defb(arc(nw,n)).. sum(kk, bk(arc,kk)) =l= b(arc);
Model ccoil / all /;
Set
k 'type of oil pipe' / 1*6 /
n 'nodes in the oil pipeline network'
/ 1 'H87', 2 'ECHIRA', 3 'SIMBA-CONOCO-C'
4 'AGIP-TASSI', 5 'SIMBA-CONOCO-B', 6 'J87'
7 'CONN07', 8 'MBASSI-CONOCO', 9 'WELL09'
10 'NAMBA-TENNECO', 11 'ELF-B', 12 'NDOGO-C-ELF'
13 'PANGA-AGIP', 14 'BIGORNEAU', 15 'CONN15'
16 'AGIP-PANGA-B', 17 'CONN17', 18 'MASSANGA-TENNECO-A'
19 'WELL19', 20 'MASSANGA-TENNECO-B', 21 'TCHIBALA-ELF'
22 'HOURICULA', 23 'LUCINA-SHELL', 24 'CONN24'
25 'CONN25', 26 'TCHIBOBO-TRITON-A', 27 'CONN27'
28 'MWENGUI-ELF', 29 'MBYA-ELF', 30 'CONN30'
31 'TCHIBOBO-TRITON-B', 32 'K8', 33 'GAMBA ' /;
Parameter
cap(k) 'capacity of type k oil pipe'
/ 2 5, 3 10, 4 25, 5 50, 6 100 /
pipecost(k) 'monetary units for type k capacity'
/ 2 10, 3 15, 4 25, 5 40, 6 65 /
p(n) 'production at each node'
/ 1 5, 2 7, 3 5, 4 6, 5 5, 6 4, 8 7, 9 3, 10 5
11 4, 12 3, 13 6, 14 9, 16 5, 18 6, 19 5, 20 4, 21 6
22 3, 23 8, 26 5, 28 5, 29 10, 31 6, 32 6 /
edgedist(n,n) 'generalized distance of each edge'
/ 1 .2 3.50, 1 .3 1.90, 1 .4 5.40, 2 .3 3.70, 2 .7 1.15
3 .4 4.90, 3 .5 2.50, 3 .7 2.60, 3 .33 4.80, 4 .5 5.30
4 .6 4.00, 5 .6 4.30, 5 .8 2.70, 5 .9 2.10, 5 .33 3.75
6 .8 2.60, 7 .33 1.60, 8 .9 2.20, 8 .10 2.20, 9 .12 2.30
9 .33 1.60, 10.11 2.00, 10.13 2.80, 10.33 5.30, 11.12 1.10
11.13 1.80, 12.13 2.50, 12.14 1.20, 12.33 3.00, 13.14 2.10
13.16 3.20, 14.15 1.20, 14.16 5.30, 15.16 6.30, 15.17 2.10
15.33 1.65, 16.17 4.80, 17.19 7.30, 17.24 2.70, 18.19 1.50
19.20 1.80, 19.21 0.90, 19.23 3.00, 20.21 1.30, 20.26 2.20
20.29 4.80, 21.22 2.50, 21.23 2.80, 21.26 2.90, 22.23 0.80
23.24 2.40, 23.25 3.00, 23.26 5.00, 23.29 3.70, 24.25 0.90
24.29 4.50, 25.29 3.30, 25.30 0.90, 26.27 1.20, 26.28 2.80
26.31 2.50, 27.28 2.10, 27.31 1.50, 28.29 1.30, 28.31 3.00
29.30 2.60, 29.31 4.00, 30.32 0.90 /;
Set
regnode(n) 'non-port nodes'
port(n) 'port'
arc(n,n) 'arcs in the network'
kk(k) 'reduced set of pipe line types';
Parameter dist(n,n) 'the distance of the arcs';
dist(m,n) = edgedist(m,n) + edgedist(n,m);
arc(m,n)$dist(m,n) = yes;
* Last node is the port
port(n)$(card(n) = ord(n)) = yes;
regnode(n) = yes;
regnode(port) = no;
arc(port,n) = no;
kk(k) = yes;
kk('1') = no;
kk('2') = no;
pipecost1 = pipecost('2');
cap1 = cap('2');
* Adjust data for removed pipe line type
pipecost(kk) = pipecost(kk) - pipecost1;
cap(kk) = cap(kk) - cap1;
nw(n) = yes;
Set
s 'solvers' / cbc, scip, gurobi, cplex, xpress /
mtype 'model type' / mip /
ss(s) 'solvers available';
ss(s) = SolverCapabilities(s,'mip');
Parameter h(s) 'handle';
ccoil.solveLink = %solveLink.asyncGrid%;
ccoil.resLim = 60;
option limRow = 0, limCol = 0, solPrint = silent, optCr = 0, optCa = 0;
loop(ss,
if(sameas('cbc', ss), option mip = cbc;);
if(sameas('cplex', ss), option mip = cplex;);
if(sameas('gurobi', ss), option mip = gurobi;);
if(sameas('scip', ss), option mip = scip;);
if(sameas('xpress', ss), option mip = xpress;);
solve ccoil minimizing cost using mip;
h(ss) = ccoil.handle;
);
Parameter rep, haveSolution / 0 /;
$eolCom //
* Now collect
repeat
loop(ss$handlecollect(h(ss)),
rep(ss,'solveStat') = ccoil.solveStat;
rep(ss,'modelStat') = ccoil.modelStat;
rep(ss,'resUsd' ) = ccoil.resUsd;
rep(ss,'objVal') = ccoil.objVal;
display$handledelete(h(ss)) 'trouble deleting handles';
h(ss) = 0;
haveSolution$(ccoil.modelStat = %modelStat.optimal% or ccoil.modelStat = %modelStat.integerSolution%) = 1;
);
if(haveSolution = 0, display$sleep(0.25) 'was sleeping for 1/4 second';);
until haveSolution = 1 or card(h) = 0 or timeelapsed > 70;
display rep;
* We might have some solver processes still running. If the grid
* directory is the scratch directory, we better wait for the jobs to
* terminate otherwise we will have trouble removing the scratch
* directory which happens automatically when GAMS terminates.
$ifThen "%gams.scrdir%"=="%gams.griddir%"
repeat
loop(ss$handlecollect(h(ss)),
rep(ss,'solveStat') = ccoil.solveStat;
rep(ss,'modelStat') = ccoil.modelStat;
rep(ss,'resUsd' ) = ccoil.resUsd;
rep(ss,'objVal') = ccoil.objVal;
display$handledelete(h(ss)) 'trouble deleting handles';
h(ss) = 0;
);
display$sleep(card(h)*0.25) 'was sleeping some time';
until card(h) = 0 or timeelapsed > 70;
display rep;
$endIf
abort$(haveSolution = 0) 'We did not find an integer solution';