1 /* $Id$
2  *
3  * Name:    writeAMPL.cpp
4  * Author:  Pietro Belotti
5  * Purpose: save a problem in AMPL format
6  *
7  * (C) Carnegie-Mellon University, 2006.
8  * This file is licensed under the Eclipse Public License (EPL)
9  */
10 
11 #include <fstream>
12 #include <iomanip> // to use the setprecision manipulator
13 
14 #include "CouenneProblem.hpp"
15 #include "CouenneProblemElem.hpp"
16 #include "CouenneExprVar.hpp"
17 
18 using namespace Couenne;
19 
20 // store problem in a .mod file (AMPL)
21 
writeAMPL(const std::string & fname,bool aux)22 void CouenneProblem::writeAMPL (const std::string &fname,  /// name of the mod file
23 				bool aux) {                /// with or without auxiliaries?
24 
25   std::ofstream f (fname.c_str ());
26 
27   f << std::setprecision (10);
28 
29   // original variables, integer and non //////////////////////////////////////////////
30 
31   f << "# Problem name: " << fname << std::endl << std::endl
32     << "# original variables" << std::endl << std::endl;
33 
34   for (int i=0; i < nVars (); i++) {
35 
36     f << "var ";
37     variables_ [i] -> print (f);
38     if (Lb (i) > - COUENNE_INFINITY/2) f << " >= " << Lb (i);
39     if (Ub (i) < + COUENNE_INFINITY/2) f << " <= " << Ub (i);
40     if (variables_ [i] -> isInteger ())   f << " integer";
41     if (fabs (X (i)) < COUENNE_INFINITY)
42       f << " default " << X (i);
43     f << ';' << std::endl;
44   }
45 
46 
47   // defined (aux) variables, declaration ///////////////////////////////////////////
48   /*
49   if (aux) {
50 
51     initAuxs (x_, lb_, ub_);
52 
53     f << std::endl << "# auxiliary variables" << std::endl << std::endl;
54 
55     for (std::vector <exprVar *>::iterator i = variables_.begin ();
56 	 i != variables_.end ();
57 	 i++)
58 
59       if ((*i) -> Type () == AUX) {
60 
61 	exprAux *aux = dynamic_cast <exprAux *> (*i);
62 
63 	if (aux -> Multiplicity () > 0) {
64 
65 	  f << "var "; (*i) -> print (f, false, this);
66 	  //    f << " = ";  (*i) -> Image () -> print (f);
67 	  CouNumber bound;
68 
69 	  if ((bound = (*((*i) -> Lb ())) ()) > - COUENNE_INFINITY) f << " >= " << bound;
70 	  if ((bound = (*((*i) -> Ub ())) ()) <   COUENNE_INFINITY) f << " <= " << bound;
71 	  if ((*i) -> isInteger ()) f << " integer";
72 
73 	  f << " default " << (*((*i) -> Image ())) () << ';' << std::endl;
74 	}
75       }
76   }
77   */
78 
79   // objective function /////////////////////////////////////////////////////////////
80 
81   f << std::endl << "# objective" << std::endl << std::endl;
82 
83   //if (objectives_ [0] -> Sense () == MINIMIZE)
84   f << "minimize";
85   //else                                         f << "maximize";
86 
87   f << " obj: ";
88   objectives_ [0] -> Body () -> print (f, !aux);
89   f << ';' << std::endl;
90 
91 
92   // defined (aux) variables, with formula ///////////////////////////////////////////
93 
94   if (aux) {
95 
96     f << std::endl << "# aux. variables defined" << std::endl << std::endl;
97 
98     for (int i=0; i < nVars (); i++)
99 
100       if ((variables_ [i] -> Type () == AUX) &&
101 	  (variables_ [i] -> Multiplicity () > 0)) {
102 
103 	f << "aux" << i << ": "; variables_ [i] -> print (f, false);
104 	f << " = ";
105 
106 	variables_ [i] -> Image () -> print (f, false);
107 	f << ';' << std::endl;
108       }
109   }
110 
111 
112   // write constraints //////////////////////////////////////////////////////////////
113 
114   f << std::endl << "# constraints" << std::endl << std::endl;
115 
116   if (!aux) // print h_i(x,y) <= ub, >= lb
117     for (std::vector <exprVar *>::iterator i = variables_.begin ();
118 	 i != variables_.end ();
119 	 ++i)
120 
121       if (((*i) -> Type () == AUX) &&
122 	  ((*i) -> Multiplicity () > 0)) {
123 
124 	CouNumber bound;
125 
126 	if ((bound = (*i) -> lb ()) > - COUENNE_INFINITY) {
127 	  f << "conAuxLb" << (*i) -> Index () << ": ";
128 	  (*i) -> print (f, true);
129 	  f << ">= " << bound << ';' << std::endl;
130 	}
131 
132 	if ((bound = (*i) -> ub ()) <   COUENNE_INFINITY) {
133 	  f << "conAuxUb" << (*i) -> Index () << ": ";
134 	  (*i) -> print (f, true);
135 	  f << "<= " << bound << ';' << std::endl;
136 	}
137       }
138 
139 
140   for (int i=0; i < nCons (); i++) {
141 
142     // get numerical value of lower, upper bound
143     CouNumber lb = (constraints_ [i] -> Lb () -> Value ()),
144               ub = (constraints_ [i] -> Ub () -> Value ());
145 
146     f << "con" << i << ": ";
147     constraints_ [i] -> Body () -> print (f, !aux);
148 
149     if (lb > - COUENNE_INFINITY + 1) {
150       f << ' ';
151       if (fabs (ub-lb) > COUENNE_EPS)
152 	f << '>';
153       f << "= " << lb << ';' << std::endl;
154     }
155     else  f << " <= " << ub << ';' << std::endl;
156 
157     // if range constraint, print it once again
158 
159     if ((   lb > - COUENNE_INFINITY + 1)
160 	&& (ub <   COUENNE_INFINITY - 1)
161 	&& (fabs (ub-lb) > COUENNE_EPS)) {
162 
163       f << "con" << i << "_rng: ";
164       constraints_ [i] -> Body () -> print (f, !aux);
165       f << " <= " << ub << ';' << std::endl;
166     }
167   }
168 
169   f.close ();
170 }
171