asyncincbi.gms : Asynchronous processing of incumbents reported by GAMS/CPLEX

Description

This model demonstrates how to instruct GAMS/CPLEX to dump a newly found incumbent to disk
in a GDX point file format. An asynchronously running GAMS program checks the current incumbent
and instructs GAMS/CPLEX to terminate as soon as an externally measured event (here simple that
the objective value of the incumbent drops below a certain threshold). The MIP used in this
example is the pk1 instance from MIPLIB.

  Run this only when Cplex or no solver is selected


Small Model of Type : MIP


Category : GAMS Model library


Main file : asyncincbi.gms

$title Asynchronous processing of incumbents reported by GAMS/CPLEX (ASYNCINCBI,SEQ=430)

$onText
This model demonstrates how to instruct GAMS/CPLEX to dump a newly found incumbent to disk
in a GDX point file format. An asynchronously running GAMS program checks the current incumbent
and instructs GAMS/CPLEX to terminate as soon as an externally measured event (here simple that
the objective value of the incumbent drops below a certain threshold). The MIP used in this 
example is the pk1 instance from MIPLIB.
$offText

* Run this only when Cplex or no solver is selected
$ifE sameas('','%gams.mip%')or(sameas('cplex','%gams.mip%'))==0 $exit

Variables  x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12,x13,x14,x15,x16,x17,x18,x19
          ,x20,x21,x22,x23,x24,x25,x26,x27,x28,x29,x30,x31,x32,b33,b34,b35,b36
          ,b37,b38,b39,b40,b41,b42,b43,b44,b45,b46,b47,b48,b49,b50,b51,b52,b53
          ,b54,b55,b56,b57,b58,b59,b60,b61,b62,b63,b64,b65,b66,b67,b68,b69,b70
          ,b71,b72,b73,b74,b75,b76,b77,b78,b79,b80,b81,b82,b83,b84,b85,b86,b87;

Positive Variables  x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12,x13,x14,x15,x16,x17
          ,x18,x19,x20,x21,x22,x23,x24,x25,x26,x27,x28,x29,x30,x31,x32;

Binary Variables  b33,b34,b35,b36,b37,b38,b39,b40,b41,b42,b43,b44,b45,b46,b47
          ,b48,b49,b50,b51,b52,b53,b54,b55,b56,b57,b58,b59,b60,b61,b62,b63,b64
          ,b65,b66,b67,b68,b69,b70,b71,b72,b73,b74,b75,b76,b77,b78,b79,b80,b81
          ,b82,b83,b84,b85,b86,b87;

Equations  e1,e2,e3,e4,e5,e6,e7,e8,e9,e10,e11,e12,e13,e14,e15,e16,e17,e18,e19
          ,e20,e21,e22,e23,e24,e25,e26,e27,e28,e29,e30,e31,e32,e33,e34,e35,e36
          ,e37,e38,e39,e40,e41,e42,e43,e44,e45,e46;


e1..    x1 - x2 =E= 0;
e2..    x2 - x3 =G= 0;
e3..    x2 - x4 =G= 0;
e4..    x2 - x5 =G= 0;
e5..    x2 - x6 =G= 0;
e6..    x2 - x7 =G= 0;
e7..    x2 - x8 =G= 0;
e8..    x2 - x9 =G= 0;
e9..    x2 - x10 =G= 0;
e10..    x2 - x11 =G= 0;
e11..    x2 - x12 =G= 0;
e12..    x2 - x13 =G= 0;
e13..    x2 - x14 =G= 0;
e14..    x2 - x15 =G= 0;
e15..    x2 - x16 =G= 0;
e16..    x2 - x17 =G= 0;
e17..    x2 - x18 =G= 0;
e18..    x2 - x19 =G= 0;
e19..    x2 - x20 =G= 0;
e20..    x2 - x21 =G= 0;
e21..    x2 - x22 =G= 0;
e22..    x2 - x23 =G= 0;
e23..    x2 - x24 =G= 0;
e24..    x2 - x25 =G= 0;
e25..    x2 - x26 =G= 0;
e26..    x2 - x27 =G= 0;
e27..    x2 - x28 =G= 0;
e28..    x2 - x29 =G= 0;
e29..    x2 - x30 =G= 0;
e30..    x2 - x31 =G= 0;
e31..    x2 - x32 =G= 0;

e32..    x3 - x4 + 14*b33 + 36*b34 + 11*b35 + 27*b36 + 49*b37 + 26*b38 + 37*b39
       + 45*b40 + 21*b41 + 6*b42 + 48*b43 + 38*b44 + 37*b45 + 10*b46 + 16*b47
       + 35*b48 + 17*b49 + 7*b50 + 46*b51 + 26*b52 + 8*b53 + 40*b54 + 19*b55
       + 33*b56 + 5*b57 + 42*b58 + 22*b59 + 14*b60 + 51*b61 + 49*b62 + 7*b63
       + 10*b64 + 30*b65 + 14*b66 + 32*b67 + 24*b68 + 36*b69 + 14*b70 + 13*b71
       + 52*b72 + 16*b73 + 5*b74 + 35*b75 + 48*b76 + 11*b77 + 47*b78 + 27*b79
       + 24*b80 + 49*b81 + 17*b82 + 46*b83 + 53*b84 + 53*b85 + 10*b86 + 30*b87
       =E= 731;

e33..    x5 - x6 + 53*b33 + 48*b34 + 48*b35 + 12*b36 + 43*b37 + 42*b38 + 14*b39
       + 48*b40 + 16*b41 + 23*b42 + 25*b43 + 36*b44 + 54*b45 + 34*b46 + 45*b47
       + 51*b48 + 45*b49 + 46*b50 + 30*b51 + 38*b52 + 52*b53 + 21*b54 + 9*b55
       + 21*b56 + 15*b57 + 22*b58 + 12*b59 + 12*b60 + 19*b61 + 17*b62 + 38*b63
       + 17*b64 + 9*b65 + 30*b66 + 24*b67 + 48*b68 + 16*b69 + 34*b70 + 41*b71
       + 28*b72 + 52*b73 + 10*b74 + 8*b75 + 51*b76 + 40*b77 + 48*b78 + 46*b79
       + 30*b80 + 38*b81 + 21*b82 + 12*b83 + 35*b84 + 38*b85 + 17*b86 + 52*b87
       =E= 731;

e34..    x7 - x8 + 48*b33 + 34*b34 + 8*b35 + 5*b36 + 49*b37 + 21*b38 + 38*b39
       + 11*b40 + 26*b41 + 12*b42 + 30*b43 + 18*b44 + 23*b45 + 8*b46 + 55*b47
       + 46*b48 + 5*b49 + 10*b50 + 50*b51 + 52*b52 + 45*b53 + 42*b54 + 43*b55
       + 19*b56 + 25*b57 + 8*b58 + 27*b59 + 5*b60 + 41*b61 + 39*b62 + 52*b63
       + 33*b64 + 17*b65 + 5*b66 + 34*b67 + 11*b68 + 21*b69 + 16*b70 + 17*b71
       + 42*b72 + 23*b73 + 43*b74 + 5*b75 + 42*b76 + 47*b77 + 55*b78 + 32*b79
       + 47*b80 + 9*b81 + 26*b82 + 43*b83 + 50*b84 + 13*b85 + 30*b86 + 14*b87
       =E= 731;

e35..    x9 - x10 + 33*b33 + 34*b34 + 36*b35 + 34*b36 + 19*b37 + 19*b38
       + 30*b39 + 48*b40 + 32*b41 + 30*b42 + 26*b43 + 39*b44 + 47*b45 + 37*b46
       + 52*b47 + 33*b48 + 5*b49 + 39*b50 + 34*b51 + 42*b52 + 30*b53 + 33*b54
       + 19*b55 + 21*b56 + 38*b57 + 40*b58 + 9*b59 + 33*b60 + 48*b61 + 35*b62
       + 42*b63 + 26*b64 + 13*b65 + 23*b66 + 55*b67 + 27*b68 + 37*b69 + 30*b70
       + 20*b71 + 14*b72 + 5*b73 + 42*b74 + 49*b75 + 47*b76 + 24*b77 + 45*b78
       + 25*b79 + 24*b80 + 28*b81 + 54*b82 + 11*b83 + 53*b84 + 32*b85 + 25*b86
       + 19*b87 =E= 731;

e36..    x11 - x12 + 15*b33 + 9*b34 + 24*b35 + 43*b36 + 53*b37 + 54*b38
       + 29*b39 + 24*b40 + 11*b41 + 47*b42 + 24*b43 + 34*b44 + 29*b45 + 49*b46
       + 50*b47 + 39*b48 + 50*b49 + 36*b50 + 32*b51 + 42*b52 + 55*b53 + 21*b54
       + 11*b55 + 24*b56 + 45*b57 + 10*b58 + 30*b59 + 42*b60 + 38*b61 + 51*b62
       + 6*b63 + 48*b64 + 5*b65 + 25*b66 + 36*b67 + 53*b68 + 24*b69 + 10*b70
       + 22*b71 + 31*b72 + 53*b73 + 41*b74 + 10*b75 + 26*b76 + 35*b77 + 55*b78
       + 10*b79 + 29*b80 + 36*b81 + 37*b82 + 15*b83 + 36*b84 + 54*b85 + 22*b86
       + 55*b87 =E= 731;

e37..    x13 - x14 + 43*b33 + 28*b34 + 30*b35 + 30*b36 + 10*b37 + 26*b38
       + 32*b39 + 54*b40 + 26*b41 + 52*b42 + 34*b43 + 24*b44 + 21*b45 + 39*b46
       + 41*b47 + 47*b48 + 36*b49 + 27*b50 + 52*b51 + 7*b52 + 6*b53 + 52*b54
       + 13*b55 + 30*b56 + 32*b57 + 46*b58 + 41*b59 + 12*b60 + 44*b61 + 7*b62
       + 12*b63 + 32*b64 + 30*b65 + 38*b66 + 6*b67 + 36*b68 + 8*b69 + 34*b70
       + 34*b71 + 30*b72 + 31*b73 + 13*b74 + 49*b75 + 47*b76 + 48*b77 + 35*b78
       + 39*b79 + 29*b80 + 6*b81 + 35*b82 + 32*b83 + 7*b84 + 32*b85 + 40*b86
       + 33*b87 =E= 731;

e38..    x15 - x16 + 8*b33 + 30*b34 + 18*b35 + 16*b36 + 18*b37 + 21*b38
       + 24*b39 + 46*b40 + 47*b41 + 6*b42 + 48*b43 + 27*b44 + 10*b45 + 26*b46
       + 6*b47 + 36*b48 + 52*b49 + 14*b50 + 29*b51 + 43*b52 + 7*b53 + 8*b54
       + 26*b55 + 31*b56 + 10*b57 + 6*b58 + 7*b59 + 12*b60 + 33*b61 + 42*b62
       + 41*b63 + 37*b64 + 17*b65 + 55*b66 + 48*b67 + 31*b68 + 20*b69 + 17*b70
       + 21*b71 + 11*b72 + 19*b73 + 13*b74 + 34*b75 + 24*b76 + 35*b77 + 35*b78
       + 55*b79 + 31*b80 + 44*b81 + 29*b82 + 19*b83 + 46*b84 + 33*b85 + 41*b86
       + 22*b87 =E= 731;

e39..    x17 - x18 + 38*b33 + 42*b34 + 24*b35 + 46*b36 + 20*b37 + 11*b38
       + 32*b39 + 52*b40 + 24*b41 + 31*b42 + 45*b43 + 50*b44 + 47*b45 + 6*b46
       + 15*b47 + 53*b48 + 20*b49 + 24*b50 + 31*b51 + 40*b52 + 54*b53 + 10*b54
       + 40*b55 + 30*b56 + 50*b57 + 14*b58 + 44*b59 + 41*b60 + 42*b61 + 29*b62
       + 8*b63 + 24*b64 + 16*b65 + 27*b66 + 15*b67 + 31*b68 + 34*b69 + 42*b70
       + 28*b71 + 53*b72 + 17*b73 + 18*b74 + 48*b75 + 8*b76 + 19*b77 + 7*b78
       + 6*b79 + 35*b80 + 27*b81 + 33*b82 + 20*b83 + 25*b84 + 39*b85 + 55*b86
       + 51*b87 =E= 731;

e40..    x19 - x20 + 34*b33 + 13*b34 + 39*b35 + 19*b36 + 51*b37 + 13*b38
       + 22*b39 + 20*b40 + 24*b41 + 45*b42 + 30*b43 + 51*b44 + 24*b45 + 17*b46
       + 23*b47 + 22*b48 + 29*b49 + 36*b50 + 14*b51 + 33*b52 + 51*b53 + 17*b54
       + 35*b55 + 31*b56 + 39*b57 + 12*b58 + 47*b59 + 9*b60 + 46*b61 + 46*b62
       + 55*b63 + 25*b64 + 55*b65 + 38*b66 + 39*b67 + 51*b68 + 46*b69 + 6*b70
       + 15*b71 + 15*b72 + 47*b73 + 40*b74 + 10*b75 + 15*b76 + 52*b77 + 29*b78
       + 32*b79 + 26*b80 + 10*b81 + 42*b82 + 55*b83 + 6*b84 + 54*b85 + 34*b86
       + 32*b87 =E= 731;

e41..    x21 - x22 + 37*b33 + 42*b34 + 23*b35 + 41*b36 + 33*b37 + 14*b38
       + 40*b39 + 53*b40 + 14*b41 + 23*b42 + 37*b43 + 9*b44 + 14*b45 + 38*b46
       + 19*b47 + 24*b48 + 29*b49 + 55*b50 + 29*b51 + 40*b52 + 52*b53 + 54*b54
       + 16*b55 + 23*b56 + 8*b57 + 53*b58 + 23*b59 + 9*b60 + 52*b61 + 52*b62
       + 37*b63 + 33*b64 + 39*b65 + 55*b66 + 18*b67 + 17*b68 + 14*b69 + 54*b70
       + 14*b71 + 24*b72 + 21*b73 + 46*b74 + 28*b75 + 30*b76 + 29*b77 + 43*b78
       + 50*b79 + 53*b80 + 43*b81 + 24*b82 + 38*b83 + 39*b84 + 22*b85 + 49*b86
       + 7*b87 =E= 731;

e42..    x23 - x24 + 25*b33 + 47*b34 + 25*b35 + 29*b36 + 44*b37 + 22*b38
       + 10*b39 + 21*b40 + 5*b41 + 10*b42 + 35*b43 + 17*b44 + 20*b45 + 33*b46
       + 27*b47 + 39*b48 + 50*b49 + 17*b50 + 11*b51 + 25*b52 + 42*b53 + 50*b54
       + 19*b55 + 40*b56 + 37*b57 + 38*b58 + 22*b59 + 20*b60 + 5*b61 + 16*b62
       + 22*b63 + 25*b64 + 8*b65 + 43*b66 + 50*b67 + 47*b68 + 9*b69 + 5*b70
       + 12*b71 + 10*b72 + 10*b73 + 42*b74 + 22*b75 + 25*b76 + 20*b77 + 45*b78
       + 9*b79 + 15*b80 + 7*b81 + 15*b82 + 35*b83 + 44*b84 + 9*b85 + 50*b86
       + 28*b87 =E= 731;

e43..    x25 - x26 + 42*b33 + 33*b34 + 45*b35 + 6*b36 + 33*b37 + 6*b38 + 24*b39
       + 54*b40 + 9*b41 + 12*b42 + 48*b43 + 51*b44 + 16*b45 + 48*b46 + 8*b47
       + 21*b48 + 54*b49 + 46*b50 + 39*b51 + 23*b52 + 11*b53 + 28*b54 + 27*b55
       + 21*b56 + 30*b57 + 38*b58 + 52*b59 + 18*b60 + 43*b61 + 46*b62 + 42*b63
       + 29*b64 + 23*b65 + 32*b66 + 31*b67 + 52*b68 + 33*b69 + 51*b70 + 50*b71
       + 38*b72 + 7*b73 + 42*b74 + 34*b75 + 18*b76 + 35*b77 + 37*b78 + 35*b79
       + 33*b80 + 28*b81 + 18*b82 + 52*b83 + 34*b84 + 42*b85 + 24*b86 + 51*b87
       =E= 731;

e44..    x27 - x28 + 16*b33 + 6*b34 + 47*b35 + 30*b36 + 45*b37 + 37*b38
       + 16*b39 + 19*b40 + 5*b41 + 44*b42 + 45*b43 + 53*b44 + 22*b45 + 40*b46
       + 47*b47 + 55*b48 + 43*b49 + 34*b50 + 33*b51 + 6*b52 + 13*b53 + 15*b54
       + 36*b55 + 41*b56 + 39*b57 + 50*b58 + 38*b59 + 18*b60 + 36*b61 + 6*b62
       + 13*b63 + 47*b64 + 8*b65 + 5*b66 + 22*b67 + 48*b68 + 37*b69 + 34*b70
       + 11*b71 + 38*b72 + 22*b73 + 52*b74 + 35*b75 + 39*b76 + 37*b77 + 27*b78
       + 38*b79 + 24*b80 + 5*b81 + 16*b82 + 25*b83 + 14*b84 + 27*b85 + 6*b86
       + 51*b87 =E= 731;

e45..    x29 - x30 + 10*b33 + 51*b34 + 33*b35 + 23*b36 + 31*b37 + 34*b38
       + 32*b39 + 23*b40 + 38*b41 + 32*b42 + 40*b43 + 30*b44 + 14*b45 + 19*b46
       + 37*b47 + 48*b48 + 36*b49 + 33*b50 + 27*b51 + 20*b52 + 14*b53 + 50*b54
       + 54*b55 + 34*b56 + 50*b57 + 14*b58 + 54*b59 + 9*b60 + 37*b61 + 55*b62
       + 55*b63 + 42*b64 + 51*b65 + 32*b66 + 10*b67 + 26*b68 + 11*b69 + 38*b70
       + 45*b71 + 44*b72 + 14*b73 + 30*b74 + 19*b75 + 24*b76 + 44*b77 + 52*b78
       + 16*b79 + 24*b80 + 29*b81 + 39*b82 + 39*b83 + 39*b84 + 33*b85 + 37*b86
       + 17*b87 =E= 731;

e46..    x31 - x32 + 28*b33 + 47*b34 + 16*b35 + 32*b36 + 28*b37 + 16*b38
       + 32*b39 + 15*b40 + 11*b41 + 8*b42 + 21*b43 + 33*b44 + 15*b45 + 54*b46
       + 22*b47 + 55*b48 + 13*b49 + 47*b50 + 19*b51 + 33*b52 + 35*b53 + 15*b54
       + 44*b55 + 55*b56 + 39*b57 + 28*b58 + 39*b59 + 23*b60 + 6*b61 + 20*b62
       + 36*b63 + 29*b64 + 12*b65 + 48*b66 + 6*b67 + 35*b68 + 8*b69 + 33*b70
       + 46*b71 + 15*b72 + 37*b73 + 11*b74 + 44*b75 + 48*b76 + 9*b77 + 11*b78
       + 47*b79 + 18*b80 + 54*b81 + 10*b82 + 46*b83 + 34*b84 + 20*b85 + 35*b86
       + 33*b87 =E= 731;

Model m / all /;

m.limrow=0; m.limcol=0; m.optcr=0;

*generate a random mutex ID
$eval mtxID round(frac(jnow)*24*60*60*1000)
$funcLibIn mtxlib mtxcclib
Function 
   create      / mtxlib.Create /
   delete      / mtxlib.Delete /;
abort$create(%mtxID%) 'Problems creating mutex';

* Use incumbent reporter that copies solution to a unique file name
$onEcho > savesol.gms
$set fn %ncalls%
$ifE %ncalls%<100 $set fn 0%fn%
$ifE %ncalls%<10  $set fn 0%fn%
put_utility 'exec.checkErrorLevel' / 'cp bchout_i.gdx sol%ncalls%.gdx';
$funcLibIn mtxlib mtxcclib
Function 
   timedLock   / mtxlib.TimedLock /
   unlock      / mtxlib.Unlock /;
abort$timedLock(%mtxID%,1000) 'Locking the lastsol GDX file creation';
put_utility 'exec' / 'mv -f bchout_i.gdx lastsol.gdx';
display$unlock(%mtxID%) 'Unlocking the lastsol GDX file creation';
abort$errorLevel 'Move of bchout_i.gdx to lastsol.gdx did not succeed'
$offEcho

* Instruct Cplex to call GAMS program savesol.gms everytime a new incumbent is found
* Moreover, Cplex will look for a file "process_cplex.op2" and if present process a
* secondary option file cplex.op2. Cplex will check every second for the
* existence of "process_cplex.op2". Finally, it will skip 
$onEcho > cplex.opt
mipemphasis 5
userincbicall savesol.gms
interactive 1
iatriggerfile process_cplex.op2
iafile cplex.op2
iatriggertime 1
solvefinal 0
$offEcho

* Reset Cplex time limit to stop immediately
$onEcho > cplex.op2
tilim 0
$offEcho

* A GAMS program that checks every quarter of a second for the latest
* solution file (lastsol.gdx). If the objective value drops below 10
* we signal to Cplex to process a secondary option file cplex.op2 by
* creating the file "process_cplex.op2". The secondary option file resets
* the time limit 0 which will let Cplex terminate immediately.
$onEcho > monitorsol.gms
Variable x1 /L 10/;
$funcLibIn mtxlib mtxcclib
Function 
   timedLock   / mtxlib.TimedLock /
   unlock      / mtxlib.Unlock /;
repeat
  display$sleep(0.25) 'sleeping for some time'       
  abort$timedLock(%mtxID%,1000) 'Locking the lastsol GDX file for reading';
  execute_load 'lastsol.gdx', x1;
  display$unlock(%mtxID%) 'Unlocking the lastsol GDX file for reading';
  put_utility 'log' / 'Incumbent with objective: ' x1.l:8:4;
  if (x1.l < 15,
    put_utility 'exec' / 'touch process_cplex.op2'
    abort.noError 'Stopping the program'
  );
until timeElapsed > 100  
$offEcho

* Remove all previously written solution files and Cplex trigger file
put_utility 'shell' / 'rm -f sol*.gdx lastsol.gdx process_cplex.op2';

* Create a lastsol with infinite objective value
x1.l = inf; execute_unload 'lastsol.gdx', x1; x1.l=0;

* Spawn the GAMS program asynchronously
put_utility 'shell.asyncNC' / 'gams monitorsol.gms lo=2';

m.optfile=1;
Option solver=cplex; 
solve m using MIP minimizing x1;

display$delete(%mtxID%) 'Problems removing mutex';