1% BEGIN LICENSE BLOCK 2% Version: CMPL 1.1 3% 4% The contents of this file are subject to the Cisco-style Mozilla Public 5% License Version 1.1 (the "License"); you may not use this file except 6% in compliance with the License. You may obtain a copy of the License 7% at www.eclipse-clp.org/license. 8% 9% Software distributed under the License is distributed on an "AS IS" 10% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 11% the License for the specific language governing rights and limitations 12% under the License. 13% 14% The Original Code is The ECLiPSe Constraint Logic Programming System. 15% The Initial Developer of the Original Code is Cisco Systems, Inc. 16% Portions created by the Initial Developer are 17% Copyright (C) 2006 Cisco Systems, Inc. All Rights Reserved. 18% 19% Contributor(s): 20% 21% END LICENSE BLOCK 22 23\chapter{The Eplex Library} 24\label{chapeplex} 25%HEVEA\cutdef[1]{section} 26 27\section{Introduction} 28 29The eplex library allows an external Mathematical Programming solver to be 30used by {\eclipse}. It is designed to allow the external solver to be seen 31as another solver for {\eclipse}, possibly in co-operation with 32the existing `native' solvers of {\eclipse} such as the {\it ic\/} solver. It is 33not specific to a given external solver, with the differences between 34different solvers (largely) hidden from the user, so that the user can 35write the same code and it will run on the different solvers. 36 37The exact types of problems that can be solved (and methods to solve them) 38are solver dependent, but currently linear programming, mixed integer 39programming and quadratic programming problems can be solved. 40 41The rest of this chapter is organised as follows: the remainder of this 42introduction gives a very brief description of Mathematical Programming, which 43can be skipped if the reader is familiar with the concepts. 44Section~\ref{mpmodelling} demonstrates the modelling of an MP problem, and the 45following section discusses some of the more advanced features of the library 46that are useful for hybrid techniques. 47 48\subsection{What is Mathematical Programming?} 49\label{whatmp} 50 51\index{Mathematical Programming (MP)} 52\index{Linear Programming (LP)} 53\index{Mixed Integer Programming (MIP)} 54\index{optimisation (numerical)} 55\index{objective function} 56 57Mathematical Programming (MP) (also known as numerical optimisation) is the study of optimisation using 58mathematical/numerical techniques. A problem is modelled 59by a set of simultaneous equations: an 60objective function that is to be minimised or maximised, subject to a set of 61constraints on the problem variables, expressed as equalities and 62inequalities. 63 64Many subclasses of MP problems have found important practical 65applications. In particular, Linear Programming (LP) 66problems and Mixed Integer Programming (MIP) problems are perhaps the most 67important. LP problems have both a linear objective function and linear 68constraints. MIP problems are LP problems where some or all of the 69variables are constrained to take on only integer values. 70 71It is beyond the scope of this chapter to cover MP in 72any more detail. However, for most usages of the eplex library, the user 73need not know the details of MP -- it can be treated as a black-box 74solver. 75 76\See{For more information on Mathematical Programming, you can read a 77textbook on the subject such as H.~P.~Williams' {\it Model Building in 78Mathematical Programming} \cite{Williams99}.} 79 80\quickref{Classification of MP problems}{ 81 82\begin{itemize} 83\item Linear Programming (LP) problems: linear constraints and objective 84function, continuous variables. 85\item Mixed Integer Programming (MIP) problems: LP problems with some or 86all variables restricted to taking integral values. 87\end{itemize} 88 89} 90 91\subsection{Why interface to Mathematical Programming solvers?} 92\label{whymp} 93 94Much research effort has been devoted to developing efficient ways of 95solving the various subclasses of MP problems for over 50 years. The 96external solvers are state-of-the-art implementations of some of these 97techniques. The eplex library allows the user to model an MP problem in 98ECLiPSe, and then solve the problem using the best available MP tools. 99 100In addition, the eplex library allows for the user to write programs that 101combines MP's global algorithmic solving techniques with the local 102propagation techniques of Constraint Logic 103Programming. 104 105\subsection{Example formulation of an MP Problem} 106\begin{figure} 107\begin{center} 108\resizebox{0.5\textwidth}{!}{\includegraphics{tpprob.ps}} 109\end{center} 110\caption{An Example MP Problem} 111\label{tpprob} 112\end{figure} 113 114Figure~\ref{tpprob} shows an example of an MP problem. 115It is a transportation problem where 116several plants (1-3) have varying product producing capacities that must 117be transported to various clients (A-D), each requiring various amounts of 118the product. The per-unit cost of transporting the product to 119the clients also varies. The problem is to minimise the transportation 120cost whilst satisfying the demands of the clients. 121 122To formulate the problem, we define the amount of product transported from 123a plant $N$ to a client $p$ as the variable $Np$, e.g.\ $A1$ 124represents the cost of transporting to plant $A$ from client $1$. There are 125two kinds of constraints: 126 127\begin{itemize} 128\item The amount of product delivered from all the plants to a client must be equal to the 129client's demand, e.g.\ for client A, which can recieve products from plants 1301-3: \( A1 + A2 + A3 = 21 \) 131 132 133\item The amount of product sent by a plant must not be more than its 134capacity, e.g. for plant 1, which can send products to plants A-D: 135\(A1 + B1 + C1 + D1 \leq 50 \) 136 137\end{itemize} 138 139The objective is to minimise the transportation cost, thus the objective 140function is to minimise the combined costs of transporting the product to 141all 4 clients from the 3 plants. 142 143 144Putting everything 145together, we have the following formulation of the problem: 146 147Objective function: 148{\small 149\[ 150\min (10A1 + 7A2 + 200A3 + 8B1 + 5B2 + 10B3 + 5C1 + 5C2 + 8C3 + 9D1 + 3D2 + 7D3) 151\] 152} 153 154Constraints: 155 156\begin{eqnarray*} 157A1 + A2 + A3 & = & 21\\ 158B1 + B2 + B3 & = & 40\\ 159C1 + C2 + C3 & = & 34\\ 160D1 + D2 + D3 & = & 10\\ 161A1 + B1 + C1 + D1 & \leq & 50\\ 162A2 + B2 + C2 + D2 & \leq & 30\\ 163A3 + B3 + C3 + D3 & \leq & 40\\ 164\end{eqnarray*} 165 166\section{How to load the library} 167 168To use the library, you must have an MP solver that eplex can use. This 169can be an open-source solver such as the COIN-OR project's CLP/CBC solvers, 170which is distributed with ECLiPSe, or a commercial solver such as 171XPRESS-MP or CPLEX. Your {\eclipse} should be configured to load in a 172`default' solver if there is more than one available. 173 174\See{See the library 175manual's Eplex chapter for details for how to install the solver.} 176 177When configured properly, the library can be loaded with the directive: 178 179\begin{code} 180:- lib(eplex). 181\end{code} 182 183\noindent 184This will load the library with the default external MP solver. 185 186You probably need a valid license in order to use an external commercial solver. 187 188\section{Modelling MP problems in {\eclipse}} 189\label{mpmodelling} 190 191\subsection{Eplex instance} 192 193The simplest way to model an eplex problem is through an {\it eplex 194instance}. Abstractly, it can be viewed as a solver module that is 195dedicated to one MP problem. MP constraints can be posted to the instance 196and the problem solved with respect to an objective function by the 197external solver. 198 199Declaratively, an eplex instance can be 200seen as a compound constraint consisting of all the variables and 201constraints of its eplex problem. Like normal constraints, different eplex 202instances can share variables, although the individual MP constraints in 203an eplex instance do not necessarily have to be consistent with those in 204another. 205 206\quickref{Eplex Instance}{ 207 208An {\bf eplex instance} represents a single MP problem in a 209module. Constraints for the problem are posted to the module. The 210problem is solved with respect to an objective function. 211} 212 213\subsection{Example modelling of an MP problem in {\eclipse}} 214 215\index{modelling, LP problem} 216The following code models (and solves) the transportation problem of 217Figure~\ref{tpprob}, using an eplex instance: 218 219{\small 220\begin{code} 221:- lib(eplex). 222 223:- eplex_instance(prob). % a. declare an eplex instance 224 225main1(Cost, Vars) :- 226 % b. create the problem variables and set their range 227 Vars = [A1,A2,A3,B1,B2,B3,C1,C2,C3,D1,D2,D3], 228 prob: (Vars \$:: 0.0..1.0Inf), 229 230 % c. post the constraints for the problem to the eplex instance 231 prob: (A1 + A2 + A3 \$= 21), 232 prob: (B1 + B2 + B3 \$= 40), 233 prob: (C1 + C2 + C3 \$= 34), 234 prob: (D1 + D2 + D3 \$= 10), 235 236 prob: (A1 + B1 + C1 + D1 \$=< 50), 237 prob: (A2 + B2 + C2 + D2 \$=< 30), 238 prob: (A3 + B3 + C3 + D3 \$=< 40), 239 240 % d. set up the external solver with the objective function 241 prob: eplex_solver_setup(min( 242 10*A1 + 7*A2 + 200*A3 + 243 8*B1 + 5*B2 + 10*B3 + 244 5*C1 + 5*C2 + 8*C3 + 245 9*D1 + 3*D2 + 7*D3)), 246 247 %------------------------------- End of Modelling code 248 249 prob: eplex_solve(Cost). % e. Solve problem using external solver 250 251\end{code} 252} 253 254To use an eplex instance, it must first be declared with \verb'eplex_instance/1'. 255This is usually done with a directive, as in line \verb'a'. 256Once 257declared, an eplex instance can be referred to using its name like a module 258qualifier. 259 260We first create the problem 261variables and set their range to be non-negative, as is conventional in MP. 262Note that the bounds are posted to our eplex instance, using \verb'$::/2'. 263\Note{The default bounds for variables is -1.0Inf..1.0Inf. Bounds posted to 264 an eplex instance are specific to that eplex instance.} 265 266Next, we set up the MP constraints for the 267problem by posting them to the eplex instance. 268The MP constraints accepted by eplex are the arithmetic equalities and 269inequalities: 270\verb'$=/2', \verb'$=</2' and \verb'$>=/2'. 271\Note{The arithmetic constraints can be linear expressions on both 272sides. The restriction to linear 273expressions originates from the external solver.} 274\index{\$=/2!eplex} 275\index{\$>=/2!eplex} 276\index{\$=</2!eplex} 277\index{eplex\_solver\_setup/1} 278\index{eplex\_instance/1} 279\index{eplex\_solve/1} 280 281We need to setup the external solver with the eplex instance, so 282that the problem can be solved by the external solver. This is done by 283\verb'eplex_solver_setup/1', with the objective 284function given as the argument, enclosed by either \verb'min(...)' or \verb'max(...)'. In this case, we are minimising. 285Note that 286generally the setup of the solver and the posting of the MP constraints can be 287done in any order. 288 289Having set up the problem, we can solve it 290by calling \verb'eplex_solve/1' in line \verb'e'. 291 292When an instance gets solved, the external solver takes into account all 293constraints posted to that instance, the current variable bounds for the 294problem variables, and the objective specified during setup. 295 296In this case, there is an optimal solution of 710.0: 297 298\begin{quote}\begin{verbatim} 299?- main1(Cost, Vars). 300 301Cost = 710.0 302Vars = [A1{0.0 .. 1e+20 @ 0.0}, A2{0.0 .. 1e+20 @ 21.0}, ....] 303\end{verbatim}\end{quote} 304Note that the problem variables are not 305instantiated by the solver. However, the `solution' values, i.e.\ the 306values that the variable are given by the solver, are available in the 307eplex attribute. The eplex attribute is shown as \verb'Lo..Hi @ Sol' where 308\verb'Lo' is the lower bound, \verb'Hi' the upper bound, and \verb'Sol' the 309solution value for the variable (e.g., \verb'A2' has the solution value of 31021.0 in the example above). Note also that the external solver may not 311allow very large floats, hence \verb'1e+20', this external solver's 312representation of infinity, is the upper bound of the 313variables, even though we specified \verb'1.0Inf' in our code. 314 315One reason the problem variables are not assigned their solution values is 316so that the eplex problem can be solved again, after it has been modified. 317A problem can be modified by the addition of more constraints, and/or 318changes in the bounds of the problem variables. 319 320\subsection{Getting more solution information from the solver} 321 322The solution values of the problem variables can be obtained by 323\verb'eplex_var_get/3'. The example program in the 324previous section can be modified to return the solution values: 325 326{\small 327\begin{code} 328main2(Cost, Vars) :- 329 .... % same as previous example up to line e 330 prob: eplex_solve(Cost), % e. Solve problem using external solver 331 (foreach(V, Vars) do 332 % f. set the problem variables to their solution values 333 prob: eplex_var_get(V, typed_solution, V) 334 ). 335\end{code}} 336\index{eplex_var_get/3} 337 338In line \verb'f', \verb'eplex_var_get/3' is used to obtain the solution 339value for a problem variable. The second argument, set to \verb'typed_solution', 340 specifies that we want the solution value for the variable to be returned. 341Here, we instantiate the problem variable itself to the solution value 342with the third argument: 343 344\begin{quote}\begin{verbatim} 345?- main2(Cost, Vars). 346 347 348Cost = 710.0 349Vars = [0.0, 21.0, 0.0, 16.0, 9.0, 15.0, 34.0, 0.0, 0.0, 0.0, 0.0, 10.0] 350\end{verbatim}\end{quote} 351 352Note that, in general, an MP problem can have many optimal solutions, i.e.\ 353different solutions which give the optimal value for the objective function. 354As a result, the above 355instantiations for \verb'Vars' might not be what is returned by the solver 356used. 357 358 359\subsection{Adding integrality constraints} 360\index{modelling, MIP} 361 362In general, a problem variable is not restricted to taking integer 363values. However, for some problems, there may be a requirement that some or 364all of the variable values be strictly integral (for example, in the previous 365transportation problem, it may be that only whole units of the 366products can be transported; also variables may often be used to model 367booleans by allowing them to take on the values of 0 or 1 only). 368This can be specified by 369posting an additional \verb'integers/1' constraint on the 370variables. 371 372\index{integers/1!eplex} 373Consider the example problem again, where it so happens that the 374optimal value for the objective function can be satisfied with integral 375values for the variables. To show the differences 376that imposing integer constraints might make, we add the constraint that 377client A must receive an equal amount of products from plants 1 and 2. Now 378the problem (without the integer constraints) can be written as: 379 380{\small 381\begin{code} 382:- lib(eplex). 383 384:- eplex_instance(prob). 385 386main3(Cost, Vars) :- 387 Vars = [A1,A2,A3,B1,B2,B3,C1,C2,C3,D1,D2,D3], 388 prob: (Vars \$:: 0.0..1.0Inf), 389 prob: (A1 + A2 + A3 \$= 21), 390 prob: (B1 + B2 + B3 \$= 40), 391 prob: (C1 + C2 + C3 \$= 34), 392 prob: (D1 + D2 + D3 \$= 10), 393 394 prob: (A1 + B1 + C1 + D1 \$=< 50), 395 prob: (A2 + B2 + C2 + D2 \$=< 30), 396 prob: (A3 + B3 + C3 + D3 \$=< 40), 397 398 prob: eplex_solver_setup(min( 399 10*A1 + 7*A2 + 200*A3 + 400 8*B1 + 5*B2 + 10*B3 + 401 5*C1 + 5*C2 + 8*C3 + 402 9*D1 + 3*D2 + 7*D3)), 403 404 prob: (A1 \$= A2), % g. the new constraint, added after setup 405 406 %------------------------------- End of Modelling code 407 408 prob: eplex_solve(Cost), 409 (foreach(V, Vars) do 410 prob: eplex_var_get(V, typed_solution, V) 411 ). 412\end{code}} 413 414In this example, the new constraint in line \verb'g' is imposed after the 415solver setup. In fact it can be imposed anytime before 416\verb'eplex_solve(Cost)' is called. 417 418This problem also has an optimal \verb'Cost' of 710, the same as the original 419problem. However, the solution values are not integral: 420 421\begin{quote}\begin{verbatim} 422?- main3(Cost, Vars). 423 424Cost = 710.0 425Vars = [10.5, 10.5, 0.0, 5.5, 19.5, 15.0, 34.0, 0.0, 0.0, 0.0, 0.0, 10.0] 426\end{verbatim}\end{quote} 427 428Now, to impose the constraints that only whole units of the products can be 429transported, we modify the program as follows: 430 431{\small 432\begin{code} 433main4(Cost, Vars) :- 434 Vars = [A1,A2,A3,B1,B2,B3,C1,C2,C3,D1,D2,D3], 435 prob: (Vars \$:: 0.0..1.0Inf), 436 prob: integers(Vars), % h. impose the integrality constraint 437 ....% Rest is the same as main3 438\end{code}} 439 440In line \verb'h', we added the \verb'integers/1' constraint. This imposes 441the integrality constraint on \verb'Vars' for the eplex instance 442\verb'prob'. Now, 443the external solver will only assign integer solution values to the 444variables in the list. \Note{In fact, with the integer 445constraints, the problem is solved 446as a MIP problem rather than an LP problem, which involves different 447(and generally computationally more expensive) techniques. This difference 448is hidden from the eplex user.} 449 450Running this program, we get: 451 452\begin{quote}\begin{verbatim} 453 454?- main4(Cost,Vars). 455 456Cost = 898.0 457Vars = [10, 10, 1, 6, 20, 14, 34, 0, 0, 0, 0, 10] 458 459\end{verbatim}\end{quote} 460 461In this case, \verb'A1' and \verb'A2' are now integers. In fact, notice 462that all the values returned are now integers rather than floats. This is 463because the \verb'typed_solution' option of \verb'eplex_var_get/3' 464returns the solution values taking into account if the variables have been 465declared as integers for the eplex instance. 466\Note{Posting an integers/1 constraint to an eplex instance only 467 inform the external solver to treat those variables as integers (in fact 468 the external solver will still represent the variables as floats, but 469 will only assign intergral solution values to them), but does 470 not constrain the variable itself to be of type integer.} 471 472 473 474\quickref{Modelling an MP Problem}{ 475\begin{itemize} 476\item Declare an eplex instance using {\bf eplex_instance(+Instance)}. 477\item Post the constraints ({\bf \$=/2, \$>=/2, \$=</2, integers/1, 478 \$::/2}) for the problem to the eplex instance. 479\item Setup the solver with the objective function using 480\newline{\bf Instance: eplex_solver_setup(+ObjFunc)}. 481\end{itemize} 482 483} 484 485\section{Repeated Solving of an Eplex Problem} 486 487Part of the power of using the eplex library comes from being able to solve 488an eplex problem repeatedly after modification. 489For example, we can solve the original transportation 490problem, add the extra constraint, and resolve the problem. 491Remember that as \verb'eplex_solve/1' instantiates its argument, we 492need to use a new variable for each call: 493 494{\small 495\begin{code} 496 .... % setup the constraints for the original problem as before 497 prob: (A3 + B3 + C3 + D3 =< 40), 498 499 prob: eplex_solver_setup(min(....)), % as before 500 501 prob: eplex_solve(Cost1), % h. solve original problem 502 prob: (A1 \$= A2), 503 prob: eplex_solve(Cost2), % i. solve modified problem 504 ..... 505\end{code}} 506 507Note that posted constraints behave logically: they are added to an eplex 508instance when posted, and removed when they are backtracked over. 509 510In the examples so far, the solver has been invoked explicitly. 511However, the solver can also behave like a normal constraint, i.e.\ it is 512automatically invoked when certain conditions are met. 513 514As an example, we implement the standard branch-and-bound method of 515solving a MIP problem, using the external solver as an LP solver only. 516Firstly we outline how this can be 517implemented with the facilities we have already encountered. We then show 518how this can be improved usin more advanced features of \texttt{lib(eplex)}. 519 520With the branch-and-bound approach, a search-tree is formed, and at each node a 521`relaxed' version of the MIP problem is solved as an LP problem. 522Starting at the root, the problem solved is the original MIP problem, but 523without any of the integrality constraints: 524{\small 525\begin{code} 526:- eplex_instance(mip). 527 528main5(Cost, Vars) :- 529 % set up variables and constraints, but no integers/1 constraints 530 .... 531 % assume minimise for simplicity 532 mip: eplex_solver_setup(min(Obj)), 533 mip: eplex_solve(RelaxedCost), 534 mip: (Cost \$>= RelaxedCost), % RelaxedCost is lower bound 535\end{code}} 536\begin{figure} 537\begin{center} 538\resizebox{0.35\textwidth}{!}{\includegraphics{mipnode.ps}} 539\end{center} 540\caption{Labelling a variable at a MIP tree node} 541\label{mipnode} 542\end{figure} 543In general, this initial LP solution contains non-integer assignments 544to integer variables. The objective value of this LP is a lower bound on 545the actual MIP objective value. 546The task of the search is to find integer assignments 547for the integer variables that optimises the objective function. 548Each node of the 549search-tree solves the problem with extra bound constraints on these 550variables. At each node, a particular variable is `labelled' as shown in 551Figure~\ref{mipnode}. The integer variable in this case has been assigned 552the non-integer value of 4.2. In the subsequent nodes of the tree, we 553consider two alternate problems, which creates two branches in the search. In one 554problem, we impose the bound constraint $X \leq 4$, and in the other, $X 555\geq 5$: these are the two nearest integer values to 4.2. In each branch, 556the problem is solved 557again as an LP problem with its new bound for the variable: 558 559{\small 560\begin{code} 561branching(IntVars) :- 562 .... 563 % for each integer variable X which violates the integer constraint 564 mip: eplex_var_get(X, solution, XVal), 565 ... 566 Split is floor(XVal), 567 % choice: branch on the two ranges for X 568 (mip: (X \$=< Split) ; mip: (X \$>= Split + 1)), 569 mip: eplex_solve(RelaxedCost), 570 ...% repeat until there are no integer violations 571\end{code}} 572 573A choice-point for the two alternative branchings is created in the above 574code, the problem is solved with one of the branchings (\verb'X $=< Split'). 575The program then proceeds to further labelling of the variables. The 576alternative branch is left to be tried on backtracking. 577 578 579Eventually, if the problem has a solution, all the integer 580variables will be `labelled' with integer values, resulting in a solution to the 581MIP problem. However, this will generally not be optimal, and so the program 582needs to backtrack into the tree to search for a better solution by trying 583the other branches for the variables, using the 584existing solution value as a bound. 585This `branch-and-bound' search technique is implemented in {\tt 586lib(branch_and_bound)}. 587 588\quickref{Reminder: use {\eclipse} libraries!}{Remember that {\eclipse} provides 589libraries that make some programming tasks much easier. There is no 590need to write your own code when you can use what is 591provided by an {\eclipse} library.} 592 593\begin{sloppypar} 594In the code, the external solver is invoked explicitly at every node. This 595however may not be necessary as the imposed bound may already be satisfied. 596As stated at the start of this section, the invocation of the solver could be done in a 597data-driven way, more like a normal constraint. 598This is done with \verb'eplex_solver_setup/4': 599\verb'eplex_solver_setup(+Obj,-ObjVal,+Options,+Trigs)', a more 600powerful version of \verb'eplex_solver_setup/1' for setting up a 601solver. The \verb'Trigs' argument specifies a list of `trigger 602modes' for triggering the solver. \See{See the {\eclipse} reference manual for a 603complete description of the predicate.} 604\end{sloppypar} 605 606\index{eplex\_solver\_setup/4} 607For our example, we add a bound constraint at each node to exclude a 608fractional solution value for a variable. The criterion we want to use is 609to invoke the solver only if this old solution value is excluded by the new 610bounds (otherwise the external solver will solve the same problem 611redundantly). This is done by 612specifying \verb'deviating_bounds' in the trigger modes. 613The full code that 614implements a MIP solution for the 615example transportation problem is given below: 616{\small 617\begin{code} 618:- lib(eplex). 619:- lib(branch_and_bound). 620 621:- eplex_instance(mip). 622 623main6(Cost, Vars) :- 624 % b. create the problem variables and set their range 625 Vars = [A1,A2,A3,B1,B2,B3,C1,C2,C3,D1,D2,D3], 626 mip: (Vars :: 0.0..1.0Inf), 627 628 % c. post the constraints for the problem to the eplex instance 629 mip: (A1 + A2 + A3 \$= 21), 630 mip: (B1 + B2 + B3 \$= 40), 631 mip: (C1 + C2 + C3 \$= 34), 632 mip: (D1 + D2 + D3 \$= 10), 633 634 mip: (A1 + B1 + C1 + D1 \$=< 50), 635 mip: (A2 + B2 + C2 + D2 \$=< 30), 636 mip: (A3 + B3 + C3 + D3 \$=< 40), 637 mip: (A1 \$= A2), 638 639 % j. post the objective function as a constraint 640 ObjFunc = 10*A1 + 7*A2 + 200*A3 + 641 8*B1 + 5*B2 + 10*B3 + 642 5*C1 + 5*C2 + 8*C3 + 643 9*D1 + 3*D2 + 7*D3, 644 mip: (ObjFunc \$= Cost), 645 646 % k. this is a more flexible method for setting up a solver. 647 % [deviating_bounds] specifies that the external solver should be 648 % invoked when any solution value is outside the variable bounds 649 mip: eplex_solver_setup(min(ObjFunc), Cost, [], [deviating_bounds]), 650 651 % l. Use the branch_and_bound library to do the branch and bound 652 bb_min(( branching(Vars), 653 mip: eplex_get(cost, Cost) 654 (foreach(V, Vars) do mip: eplex_var_get(V,solution,V)) 655 ), Cost, _). 656 657branching(IntVars) :- 658 % Find a variable X which does not have an integer solution value 659 (integer_violation(IntVars, X, XVal) -> 660 % m. try the closer integer range first 661 Split is round(XVal), 662 (Split > XVal -> 663 (mip: (X \$>= Split) ; mip: (X \$=< Split - 1)) 664 ; 665 (mip: (X \$=< Split) ; mip: (X \$>= Split + 1)) 666 ), 667 branching(IntVars) 668 ; 669 % cannot find any integer violations; found a solution 670 true 671 ). 672 673% returns Var with solution value Val which violates the integer constraint 674integer_violation([X|Xs], Var, Val) :- 675 mip: eplex_var_get(X, solution, RelaxedSol), 676 % m. we are dealing with floats here, so need some `margin' for a 677 % float value to be considered integer (1e-5 on either side) 678 (abs( RelaxedSol - round(RelaxedSol) ) >= 1e-5 -> 679 Var = X, Val = RelaxedSol 680 ; 681 integer_violation(Xs, Var, Val) 682 ). 683 684\end{code}} 685 686The setup of the solver is done in line \verb'k', with the use of the 687\verb'deviating_bounds' trigger mode. There are no explicit calls to trigger the 688solver -- it is triggered automatically. In addition, the first call to 689\verb'eplex_solve/1' for an initial solution 690is also not required, because when trigger modes are specified, then 691by default, \verb'eplex_solver_setup/4' will invoke the solver once the 692problem is setup. 693 694\begin{sloppypar} 695Besides the \verb'deviating_bounds' 696trigger condition, the other argument of interest in our use of 697\verb'eplex_solver_setup/4' is the second argument, 698the objective value of the problem (\verb'Cost' in the example): 699recall that this was returned previously by \verb'eplex_solve/1'. 700Unlike in \verb'eplex_solve/1', the variable is {\it not\/} 701instantiated when the solver returns. Instead, one of the bounds (lower 702bound in the case of minimise) is updated 703to the optimal value, reflecting the range the objective value can take, 704from suboptimal to the `best' value at optimal. The variable is therefore 705made a problem variable by posting of the objective as a constraint in line 706\verb'j'. This informs the external solver needs to be informed 707that the \verb'Cost' variable is the objective value. 708 709\end{sloppypar} 710 711In line \verb'm', the branch choice is created by the posting of the bound 712constraint, which may trigger the external solver. Here, we use a 713simple heuristic to decide which of the two branches to try first: the 714branch with the integer range closer to the relaxed solution value. 715For example, in the situation of Figure~\ref{mipnode}, the branch with 716\verb'X $=< 4' is tried first since the solution value of 4.2 is 717closer to 4 than 5. 718 719By using {\it lib(branch_and_bound)\/}'s \verb'bb_min/3' predicate in \verb'm', 720there is no need to explicitly write our own branch-and-bound routine. However, 721this predicate requires the cost variable to be instantiated, so we call 722\verb'eplex_get(cost, Cost)' to instantiate \verb'Cost' at the end of 723each labelling of the variables. We also get the solution values for the 724variables, so that the branch-and-bound routine will remember it. 725The final value returned in \verb'Cost' (and {\tt Vars} for the solution 726values) 727is the optimal value after the branch-and-bound search, i.e.\ the 728optimal value for the MIP problem. 729 730\quickref{More advanced modelling in eplex}{ 731\begin{itemize} 732\item Use {\bf 733Instance:eplex_solver_setup(+Obj,-ObjVal,+Opts,+Trigs)} to 734set up an external solver state for instance Instance. Trigs specifies a 735list of trigger conditions to automatically trigger the external solver. 736\item {\bf Instance:eplex_var_get(+Var,+What,-Value)} can be used to obtain 737information for the variable {\bf Var} in the eplex instance. 738\item {\bf Instance:eplex_get(+Item, -Value)} can be used to retrieve 739information about the eplex instance's solver state. 740\end{itemize} 741} 742\index{eplex\_get/2} 743 744Of course, in practice, we do not write our own MIP solver, but 745use the MIP solver provided with the external solvers instead. These 746solvers are highly optimised and tightly coupled to their own LP solvers. 747The techniques of solving relaxed subproblems described here are however 748very useful for combining the external solver with other solvers in a 749hybrid fashion. \See{See chapter~\ref{chaphybrid} for more details on hybrid techniques.} 750 751\section{Exercise} 752 753A company produces two types of products T1 and T2, which requires the 754following resources to produce each unit of the product: 755 756\vspace{3mm} 757\begin{center} 758\begin{tabular}{|r||r|r|}\hline 759Resource & T1 & T2\\ \hline 760Labour (hours) & 9 & 6\\ \hline 761Pumps (units) & 1 & 1\\ \hline 762Tubing (m) & 12 & 16\\ \hline 763\end{tabular} 764\end{center} 765\vspace{3mm} 766 767The amount of profit per unit of products are: 768 769\begin{description} 770\item[T1] \pounds350 771\item[T2] \pounds300 772\end{description} 773 774They have the following resources available: 1566 hours of labour, 200 775pumps, and 2880 metres of tubing. 776 777 778 779\begin{enumerate} 780\item Write a program to maximise the profit for the company, using eplex 781as a black box solver. Write a predicate that returns the profit and the 782 values for T1 and T2. 783 784\item What program change is required to answer this question: 785 What profit can be achieved if exactly 150 units of T1 are required? 786 787\item What would the profit be if fractional numbers of refrigerators could 788 be produced? 789 790\item Rewrite the program from (1) without optimize/2, using 791 eplex_solver_setup/1, eplex_solve/1, and eplex_var_get/3. 792 793\item In the program from (4), remove the integrality constraints (so that eplex 794 only sees an LP problem). Solve the integer problem by interleaving 795 solving of the LP problem with a rounding heuristic: 796 797\begin{itemize} 798 \item solve the continuous relaxation 799 \item round the solution for T1 to the nearest integer and instantiate it 800Initially just return the maximum profit value. 801 \item re-solve the new continuous relaxation 802 \item round the solution for T2 to the nearest integer and instantiate it 803 \item re-solve the new continuous relaxation 804\end{itemize} 805 806 What is the result in terms of T1, T2 and Profit? 807 808\item Rewrite the program from (5) using eplex_solver_setup/4 and automatic 809 triggering of the solver instead of explicit calls to eplex_solve/1. 810 The solver should be triggered whenever variables get instantiated. 811\end{enumerate} 812 813%HEVEA\cutend 814 815