ampl / mp

An open-source library for mathematical programming
https://mp.ampl.com
Other
229 stars 42 forks source link

Accepting > or < conditions in if-then(-else) expressions #168

Closed 4er4er4er closed 2 years ago

4er4er4er commented 2 years ago

I modified the book example multmip1.mod (see attached files) to a version called x-multmip1.mod that uses an if-then expression in the objective instead of defining binary variables:

set ORIG;   # origins
set DEST;   # destinations
set PROD;   # products

param supply {ORIG,PROD} >= 0;  # amounts available at origins
param demand {DEST,PROD} >= 0;  # amounts required at destinations

   check {p in PROD}:
      sum {i in ORIG} supply[i,p] = sum {j in DEST} demand[j,p];

param limit {ORIG,DEST} >= 0;   # maximum shipments on routes

param vcost {ORIG,DEST,PROD} >= 0; # variable shipment cost on routes
var Trans {ORIG,DEST,PROD} >= 0;   # units to be shipped

param fcost {ORIG,DEST} >= 0;      # fixed cost for using a route
var Ship {i in ORIG, j in DEST} = sum {p in PROD} Trans[i,j,p];

minimize Total_Cost:
   sum {i in ORIG, j in DEST, p in PROD} vcost[i,j,p] * Trans[i,j,p]
 + sum {i in ORIG, j in DEST} (if Ship[i,j] > 0 then fcost[i,j]);

subject to Supply {i in ORIG, p in PROD}:
   sum {j in DEST} Trans[i,j,p] = supply[i,p];

subject to Demand {j in DEST, p in PROD}:
   sum {i in ORIG} Trans[i,j,p] = demand[j,p];

This is rejected with Error: unsupported: >. An AMPL if-then expression assumes else 0, so the objective here is equivalent to

minimize Total_Cost:
   sum {i in ORIG, j in DEST, p in PROD} vcost[i,j,p] * Trans[i,j,p]
 + sum {i in ORIG, j in DEST} (if Ship[i,j] > 0 then fcost[i,j] else 0);

which is similarly rejected. However, the equivalent formulation

minimize Total_Cost:
   sum {i in ORIG, j in DEST, p in PROD} vcost[i,j,p] * Trans[i,j,p]
 + sum {i in ORIG, j in DEST} (if Ship[i,j] = 0 then 0 else fcost[i,j]);

is accepted and solves correctly:

x-Gurobi 9.5.0: optimal solution; objective 218125
298 simplex iterations
21 branching nodes

This suggests that we should be able to accept an if-then or if-then-else expression with a > or < as the if condition. And in this example, the > formulation is more natural to write.

(There is always going to be the issue of setting tolerances for if conditions. In this example, it should be correct to set the tolerance to 0, in which case the formulation ought to reduce to that in multmip1.mod.)

glebbelov commented 2 years ago

Added (long overdue.) Right, cvt:mip:eps=0 gives same result, although longer