Variable Reslim time

Hello,

Let us assume that I would like to solve a specific model (with different inputs) ten times. I have a maximum of 3,000 seconds time limit for all runs. At first, I need to assume that the time limit for each run of the model is 300 seconds. However, for example, if the first run of the model takes only 100 seconds, the remaining 200 seconds should be added to the time limit of the remaining runs. In other words, I need to make the time limit variable so I can increase the time limit of each of them from 300 seconds to 300 + 200/9.

To define the time limit of a model, I use the below option:

Option Reslim = 300

Because this option only takes real values, I cannot assign a scalar to this option. Would you please help me so I can make this option variable?

Best, Amir

Instead of defining option reslim = 300; you can define modelname.reslim = 300;

You can do the same to calculate the time left. For example (not tested syntax but should be almost correct)

parameter timelimit /300/;
loop(iter, 
modelname.reslim = timelimit;
solve modelname using lp minimizing objective;
if (card(iter) ne ord(iter), 
timelimit = timelimit - modelname.resusd/(card(iter) - ord(iter));
)
)
  • Atharv

Thanks for your reply. It worked for me. Now, I have another question. Your attention is very much appreciated.

Let us say that I want to solve three models as follows:

LTC.reslim=300;
Solve LTC using MIP min f1;
Solve LTC using MIP min f2;
Solve LTC using MIP min f3;

I give an initial max CPU time of 300 for each model (I will have 900 seconds in total). It is possible that one of the models does not even find an initial solution within the given 300 seconds (this makes solving the other models useless for me). Therefore, in such cases, I would allow the models to run for more than 300 seconds. But as soon as the model finds an initial feasible solution, I want to terminate the model and start running the other models given the remaining time (900 - resusd).

For more clarification, let me give an example. For the above three models, suppose that I have run the first one. The solver was not able to find even an initial solution within the first 300 seconds. I would like to allow the solver to continue looking for a solution. Fortunately, it finds a solution right in 400 seconds. Then, I terminate and calculate the remaining time for each of the two other models, which could be equal to 500/2 seconds ((900 - 400)/2). Now, I set the reslim for the second model and start solving it…

Would it be possible to help me to see how I can address this problem as well?

Best, Amir

It looks to me like you are more interested in just finding a feasible solution than actually optimizing it. I say this because you want to terminate after the solver finds a feasible solution no matter how good/bad the solution is. Easy work around for this is to change your objective to a constant (say add an equation saying f1 =e= 0 and remove your current equation for the objective function). Keep everything else as is (still minimize f1). Solvers determine quickly that the objective is constant and terminate on finding any feasible solution. You can do this for all your models.

Once you decide to do that everything else follows quite logically. You provide reslim = 900 for your first run (I assume this is your absolute budget that you never want to exceed). Once the model solves it you use modelname.resusd to calculate the remaining time and follow the procedure that I mentioned in the previous response.

\

  • Atharv

Thanks for your attention again. The thing is that I like to find the optimal solution given a limited computational cost. I do not want to terminate the solver as long as it has not used its initial allocated CPU time (300 seconds in the previous example) and not found the optimal solution. If it finds the optimal solution (within the time limit), it would be so great. However, it is possible that it cannot even find an initial solution within this time limit (I have a final model that needs the objective values of all these three models). In this case, I would be forced to increase its allocated CPU time until it finds an initial solution. Then, I need to terminate the solver and run other models because I do not want to use the available time budget of other models.

Therefore, as far as I understood, your suggested solution might not work for what I intend it do. Let me know if you need more clarification. Thanks in advance.

I think that means changing reslim based on some intermediate feedback from solvers (like a callback). This is ‘in general’ not possible but some solvers might allow callbacks.

This is not the best solution, but you can have two solve statements, one with constant objective (to find a feasible point) and one with your actual objective to opitmize. You can have these calls one after the other so that solution from one is passed on to the other as level values (or starting values). i.e. if your first run finds a feasible point, the second run starts from that feasible point. This gives you more control as you can do something like 300-reslim for the second run.

  • Atharv

Hi,

You can also make use of the option mipstopexpr https://www.gams.com/34/docs/S_CPLEX.html#CPLEXmipstopexpr
This option is available with CPLEX, GUROBI, and XPRESS. With this option you can provide specific stopping conditions. For your example, the following should work.

mipstopexpr  objval < 1e75 && resusd > 300

With this, you tell the solver that if the objective value is less than 1e75 (very large value) and time used by the solver is less greater than 300 seconds, it can stop. This way, the run will continue even after 300 seconds if a feasible solution is not found and it will continue till 300 even after a feasible solution is found. Note that objval is the current objective value found by the solver and resusd is the time used by the solver.

This option has to be provided using solver option file. I provide an example below which is a modified version of the example rotdk.gms from GAMS model library.


$title Robust Optimization (ROTDK,SEQ=185)

$onText
Robust Optimization.


Laguna, M, Applying Robust Optimization to Capacity Expansion of
One Location in Telecommunications with Demand Uncertainty.
Management Science 44, 11 (1998), 101-110.

Keywords: mixed integer linear programming, robust optimization, capacity expansion,
          time-dependent knapsack problem
$offText

Set
   s 'scenarios'    / 1*1000    /
   t 'time periods' / t1*t12    /
   j 'components'   / C001*C010 /;

Alias (t,tt);

Parameter
   di(s,t) 'increment'
   D(t,s)  'demand'
   c(j)    'capacity size'
   p(j)    'capacity cost'
   mu      'mean capacity parameter'
   sigma   'std capacity parameter';

mu    = 100;
sigma =  10;

c(j) = round(uniform(1,mu));
p(j) = round(mu + c(j) + uniform(-sigma,sigma));

di(s,t)$(ord(s) <= 0.25*card(s)) = round(normal( 50,10));
di(s,t)$(ord(s) >  0.25*card(s) and ord(s) <= 0.75*card(s)) = round(normal(100,20));
di(s,t)$(ord(s) >  0.75*card(s)) = round(normal(150,40));

d(t,s) = sum(tt$(ord(tt) <= ord(t)), di(s,tt));
* display c, p, di, d;

Parameter
   dis(t) 'discount factor'
   w      'shortage penalty';

dis(t) = power(.86,ord(t) - 1);
w      = 5;

Variable
   x(j,t) 'expansion'
   z(s)   'max capacity shortage'
   cap(t) 'installed capacity'
   obj;

Integer  Variable x;
Positive Variable z;

Equation
   capbal(t)   'capacity balance'
   dembal(t,s) 'demand balance'
   objdef;

objdef..      obj =e= sum((j,t), dis(t)*p(j)*x(j,t)) + w/card(s)*sum(s, z(s));

capbal(t)..   cap(t) =e= cap(t-1) + sum(j, c(j)*x(j,t));

dembal(t,s).. cap(t) + z(s) =g= d(t,s);

Model rotdk / all /;

$onecho > cplex.opt
mipstopexpr  objval < 1e75 && resusd > 300
$offecho
rotdk.optfile =1 ;
option limCol = 0, limRow = 0;

* do not reset optcr if already set to a nondefault value
if{(.1 = %gams.optCr%), option optCr = 0.05;};

solve rotdk min obj using mip;

You can then combine this with my previous answer to allocate time in a loop. Note that you can change/modify the cplex.opt file after each run based on the time available.

  • Atharv

This is fantastic. Thank you!!!

I implemented the below code, but it does not properly terminate the code. I have set the time limit equal to 10 seconds. Although the CPLEX solver finds a feasible solution with a gap of about 4%, it does not terminate after 10 seconds!

Model MOBJ /Obj1, Obj2, Con3, Con4, Con5, Con6, Con8, Con9, Con10, Con11, Con12, Con13, Con14, Con15, Con16/
$onecho > cplex.opt
mipstopexpr  objval < 1e75 && resusd > 10
$offecho

Option limrow=0, limcol=0;
Option optca=0, optcr=0;
Option Iterlim = 100000000;
Option solvelink = 0;
MOBJ.optfile = 1;

Solve MOBJ using MIP max f1;

I am sorry if it is becoming frustrating.

As you can see from the condition imposed, that should not happen. I can confirm from the tests on my end. Which version of GAMS are you using? The option mipstopexpr was added from GAMS 33.1 onwards. Please make sure you are using the latest version to be able to use that option.

  • Atharv

Exactly! My GAMS was not up-to-date. Thanks!