User Tools

Site Tools


Intercepting a Solver Call

The GAMS solve statement usually represents a monolithic call which can not be intercepted.

There is an exception to this: the GAMS/Cplex interactive option which allows to interrupt the B&C process, to reset some options and to abort or continue the algorithms. However you can not look at the solution. Please also note that the 'interactive' option can not be used within the IDE since to input stream is attached to the process window. If you want this, you need to run it from the command line.

There is another exception namely the BCH Facility ( This intercepts the B&C algorithm at certain points and allows to feed cuts and feasible solutions found by an outside process to the B&C algorithm. This BCH Facility can also be used to save all integer solutions found during the solution process in GDX files. These files can be looked at (using the GAMS IDE) while the algorithm is still running and later be read into GAMS for further processing.

Below is an example that demonstrates the use of BCH for this purpose. You will need a recent GAMS system (22.4 or newer) to run this model.

$Title Three-dimensional Noughts and Crosses  (CUBE,SEQ=42)


White and black balls are to be arranged in a cube one to a
cell in such a way as to minimize the number of lines with balls
of equal color. For this example the length of the cube is three.
a total of 49 lines exist in a cube of 3x3x3. 27 lines by changing
only one coordinate, 18 diagonals within a plane, and 4 diagonals
going across planes.

Williams, H P, Experiments in the formulation of Integer Programming
Problems. Mathematical Programming Study 2 (1974).


Sets  s       domain for line identification   / a, b, c, incr, decr /
      x(s)    coordinate labels                / a, b, c /
      d(s)    directions                       / incr, decr /
      b       bounds                           / low, high /

Alias (x,y,z), (d,dp), (s,sp,spp)

Set ld(s,sp,spp)  line definition ;

   ld("incr",y,z) = yes;  ld(x,"incr",z) = yes; ld(x,y,"incr") = yes;
   ld("incr",d,z) = yes;  ld(x,"incr",d) = yes; ld(d,y,"incr") = yes;
   ld("incr",d,dp) = yes; display ld;

Parameters  ls(b)    sign for line definitions      / low  +1, high -1 /
            lr(b)    rhs for line definitions       / low   2, high -1 /
            df(x,s)  line definition function;

   df(x,y) = ord(y) - ord(x); df(x,"decr") = 1 + card(x) - 2*ord(x); display df;

Variables  core(x,y,z)    placement of balls (white 0  black 1)
           line(s,sp,spp) line identification
           num            number of lines of equal color

Binary Variables core;
Positive Variable line;

Equations  nbb              total number of balls definition
           ldef(s,sp,spp,b) line definitions
           ndef             number of lines definition ;

nbb..  sum((x,y,z), core(x,y,z)) =e= floor(card(x)**3/2);

ldef(s,sp,spp,b)$ld(s,sp,spp).. ls(b)*sum(x, core(x+df(x,s),x+df(x,sp),x+df(x,spp))) =l= line(s,sp,spp) + lr(b) ;

ndef.. num =e= sum((s,sp,spp)$ld(s,sp,spp), line(s,sp,spp)) ;

Model cube / all /

* this is a very difficult problem that takes a long time with
* the default settings. we use an optca value that will
* cause termination after finding the best solution, but before
* proving that it is the best. the best solution is 4.

* Cplex Option file to enable the cut generation call at every new integer point
$onecho     > cplex.opt
usercutcall   savesol.gms
usercutfreq   0
usercutfirst  0
usercutnewint 1

* A global counter for the solutions found during the process
$echo $setglobal solnum 0 > solnum.gms

* The "cut generator" program which just renames the GDX file with the newly found solution
$onechoV > savesol.gms
* Read current solution number and save solnum+1
$include solnum
$eval solnum %solnum%+1
$echo $setglobal solnum %solnum% > solnum.gms
$if exist bchout_i.gdx $call mv -f bchout_i.gdx sol%solnum%.gdx
scalar numcuts 'we do not find cuts' /0/, solcnt /%solnum%/;

Option optca = 3.9, iterlim=50000, mip=cplex; cube.optfile=1;

* Remove old solution files
execute 'rm -f sol*.gdx';

Solve cube minimizing num using mip;

* Loop through all solutions
file fx; scalar cnt, solcnt; execute_load 'bchin', solcnt;
for(cnt=1 to solcnt,
  put_utilities fx 'gdxin' / 'sol' cnt:0:0;
  execute_load num;
  display num.l);
E x e c u t i o n
----     94 VARIABLE num.L                 =       12.000  number of lines of equal color

----     94 VARIABLE num.L                 =       10.000  number of lines of equal color

----     94 VARIABLE num.L                 =        5.000  number of lines of equal color

----     94 VARIABLE num.L                 =        4.000  number of lines of equal color
solver/intercepting_a_solver_call.txt · Last modified: 2017/09/02 16:07 by support