New features of the AMPL CP interfaces ====================================== Victor Zverovich AMPL Optimization

2013 INFORMS Annual Meeting, Oct 6-9, 2013, Minneapolis, MN
About AMPL ---------- * [AMPL]( is a popular modeling system - used in businesses, government agencies, and academic institutions (over 100 courses in 2012) - large community:
> 1,400 members in [AMPL Google Group]( alone - the most popular input format on the [NEOS cloud server]( for optimization:
> 900,000 or 85% submissions in Jan-Sep 2013 * AMPL is high-level, solver-independent and efficient.
Law of the Instrument ---------------------

And to a man with a MIP solver...
Using the Right Tool -------------------- * AMPL facilitates the use of suitable optimization tools and technologies by supporting a wide variety of solvers and problem types: - linear, mixed integer and constraint programming - quadratic, second-order cone, general nonlinear programming, complementarity problems and more ... * Switching between solvers is easy. * Connecting new solvers is easy using the open-source [AMPL Solver Library]( * Solver-specific features are supported such as the whole set of solver options, variable- and constraint-specific information via suffixes.
History of CP Support in AMPL ----------------------------- * 1996: first experiments with adding logic programming features to AMPL. * Fourer (1998). *Extending a General-Purpose Algebraic Modeling Language to Combinatorial Optimization: A Logic Programming Approach* [[1](] * Fourer and Gay (2001). *Hooking a Constraint Programming Solver to an Algebraic Modeling Language* * Fourer and Gay (2002). *Extending an Algebraic Modeling Language to Support Constraint Programming* [[2](] * Initially [IBM/ILOG CP Optimizer]( was connected. * [Gecode]( was connected in 2012, [JaCoP]( - in early 2013.
AMPL Solver Library ------------------- AMPL Solver Library (ASL) is an open-source library for connecting solvers to AMPL. * C interface: - described in [Hooking Your Solver to AMPL]( - used by most non-CP solvers * [C++ interface]( - makes connecting new solvers super easy - type-safe: no casts needed when working with expression trees - efficient: no overhead compared to the C interface - used by the gecode, ilogcp and jacop (via JNI) drivers
AMPL CP Solver Architecture ------------------------
* CP function library (cp.dll) provides functions mapped to global constraints (element, in_relation, ...). * Driver library is optional but facilitates testing. * The test suite is solver independent and can be reused when connecting a new solver.
New features ------------ * Counting solutions and getting multiple solutions * Better accuracy of time statistics using high-resolution timers * Fine-grained control over the search process using variable and constraint suffixes. * Restart-based search in the Gecode driver * Element constraint * In_relation (table) constraint
Multiple solutions ------------------
* Options supported by all CP solvers connected to AMPL: - `solutionlimit`: limit on the number of feasible solutions found before terminating a search - `countsolutions`: whether to return the number of solutions in the `nsol` suffix of the current problem - `solutionstub`: basename for returned solutions * Duplicate solutions are filtered out automatically (ilogcp)
Counting Solutions ------------------

  model nqueens.ampl;
  let n := 8;
  option solver gecode;
  option gecode_options 'countsolutions=1';
  print 'The number of solutions is', Current.nsol;

running the script:

  $ ampl nqueens-count.ampl
  gecode 4.2.0: countsolutions=1
  feasible solution
  787 nodes, 302 fails
  suffix nsol OUT;
  The number of solutions is 92

Getting Multiple Solutions --------------------------

  model nqueens.ampl;
  let n := 8;
  option solver ilogcp;
  option ilogcp_options 'solutionlimit=10 solutionstub=nqueens';
  for {i in 1..Current.nsol} {
    solution ('nqueens' & i & '.sol');
    display Row;

  $ ampl nqueens-multi.ampl
  ilogcp 12.4.0: feasible solution
  Row [*] :=
  1  5
  2  7
  ilogcp 12.4.0: feasible solution
  Row [*] :=
  1  3
  2  1

Photo Problem -------------
  • A group of people wants to take a group photo.
  • Each person can give preferences next to whom he or she wants to be placed on the photo.
  • The objective is to find a placement that satisfies as many preferences as possible.
Choosing Propagators in Gecode ------------------------------

  include gecode.ampl;

  param nPeople integer > 0;
  set PREFS within {i in 1..nPeople, j in 1..nPeople: i != j};

  var Sat{PREFS} binary;
  var Pos{1..nPeople} integer >= 1, <= nPeople;

  maximize NumSat: sum{(i,j) in PREFS} Sat[i,j];

  # Choose the bound consistent variant of alldiff/distinct.
  s.t. OnePersonPerPosition:
    alldiff{i in 1..nPeople} Pos[i] suffix icl icl_bnd;

  s.t. SatDefn {(i,j) in PREFS}:
    Sat[i,j] = 1 ==> abs(Pos[i] - Pos[j]) = 1;

  s.t. SymmetryBreaking: Pos[1] < Pos[2];

Truck "Fleet" Problem ---------------------
  • Deliver orders to clients with a single truck.
  • Each order consists of a given quantity of a product of a certain type.
  • The truck must be configured in order to handle one or several types of products.
  • The truck (re)configuration cost depends both on original and new configuration.
  • Multiobjective: both the cost (for configuring and loading the truck) and the number of travels needed to deliver all the orders must be minimized, the cost being the most important criterion.
  • . . .
From IBM/ILOG CP examples
Element Constraint ------------------ Example:

  param NumTruckConfigs integer > 0;
  set TruckConfigs = 0..NumTruckConfigs - 1;

  param NumTrips integer > 0;
  set Trips = 0..NumTrips - 1;

  var truckConfigs{Trips} integer >= 0 <= NumTruckConfigs - 1;

  # Truck load cannot exceed max. load for truck's configuration.
  s.t. satisfyMaxLoad{t in Trips}:
    load[t] <= element({c in TruckConfigs} MaxTruckConfigLoad[c],

Future syntax:

  s.t. satisfyMaxLoad{t in Trips}:
    load[t] <= MaxTruckConfigLoad[truckConfigs[t]];

In_relation Constraint ---------------------- Also known as the table constraint, IloAllowedAssignments in ilogcp, extensional in Gecode. Example:

  param NumOrders integer > 0;
  set Orders = 0..NumOrders - 1;
  var configOfContainer{Orders} integer >= 0 <= NumTruckConfigs - 1;
  param NumProductTypes integer > 0;
  set AllowedContainerConfigs{0..NumProductTypes - 1};

  s.t. restrictConfigOfContainer{o in Orders}:
      {c in AllowedContainerConfigs[ProductTypes[o]]} c);

Future syntax:

  s.t. restrictConfigOfContainer{o in Orders}:
    configOfContainer[o] in

Multiobjective optimization --------------------------- Example:

  minimize totalCost:
    sum{t in Trips}
      (if load[t] > 0 then
        element({c in TruckConfigs} TruckCost[c],
                truckConfigs[t])) +
    sum{t in 0..NumTrips - 2} reconfigCost[t];

  minimize tripCount: count{t in 0..NumTrips - 1} (load[t] > 0);

Mapped to IloStaticLex with i-th objective treated as more important than (i+1)-th.
Future Work ----------- * Better syntax for some constructs: - (x1, ..., xn) in S for the in_relation constraint - e[x] for the element constraint * Support for more types of global constraints * Connecting other CP solvers (maybe using libmzn?)
Summary ------- * AMPL provides a uniform and intuitive interface to multiple constraint programming solvers. * Connecting new solvers is easy. * New features include element and in_relation constraints, multiobjective optimization, variable and constraint suffixes to choose propagators and better control search process. * This enables formulation of new and more efficient CP models using AMPL. * AMPL CP functionality is extensible: new global constraints and suffixes can be added without any changes to AMPL itself.
Links ----- * AMPL Logic and Constraint Programming Extensions: []( * Trial version of AMPL with IBM/ILOG CP: []( * Downloads for open-source AMPL solvers and libraries including Gecode: []( * AMPL models by Hakan Kjellerstrand including 100 CP models: []( * Source code for ilogcp, gecode and jacop interfaces on GitHub: [](