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