source: coopr.pyomo/trunk/coopr/pyomo/io/ampl.py @ 1992

Last change on this file since 1992 was 1992, checked in by wehart, 10 years ago

A rework of component management in Pyomo. This was initially
started as an effort to add the component activate()/deactivate()
methods. However, this naturally led to a rework of
component management that I've been planning for a while.

Component types are now managed with the natural class types (e.g.
Var for variables, rather than _VarBase). Further, the components
should now be accessed with model methods: components() or active_components().
For example,

model.components(Var)

returns a dictionary of the Var components.

NOTE:

  1. I suspect that this commit will break PySP to the extent that it

uses the model._component data structure.

  1. This adds support for component-level deactivation, but not

component index deactivation.

  1. I haven't added unit tests to validate this type of deactivation,

but all of the standard unit tests work.

File size: 12.3 KB
Line 
1#  _________________________________________________________________________
2#
3#  Coopr: A COmmon Optimization Python Repository
4#  Copyright (c) 2008 Sandia Corporation.
5#  This software is distributed under the BSD License.
6#  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
7#  the U.S. Government retains certain rights in this software.
8#  For more information, see the Coopr README.txt file.
9#  _________________________________________________________________________
10
11#
12# AMPL Problem Writer Plugin
13#
14
15from coopr.opt import ProblemFormat, WriterFactory
16from coopr.pyomo.base.numtypes import minimize, maximize
17from coopr.pyomo.base import *
18from coopr.opt.base import *
19from coopr.pyomo.base.param import _ParamValue
20from coopr.pyomo.base.var import _VarBase
21
22class ProblemWriter_nl(AbstractProblemWriter):
23
24    def __init__(self):
25        AbstractProblemWriter.__init__(self,ProblemFormat.nl)
26
27    def __call__(self, model, filename):
28        if filename is None:
29           filename = model.name + ".nl"
30        OUTPUT=open(filename,"w")
31        symbol_map = self._print_model_NL(model,OUTPUT)
32        OUTPUT.close()
33        return filename, symbol_map
34
35    def _get_bound(self, exp):
36        if isinstance(exp,expr._IdentityExpression):
37           return self._get_bound(exp._args[0])
38        elif isinstance(exp,NumericConstant):
39           return exp.value
40        elif isinstance(exp,_ParamValue):
41           return exp.value
42        else:
43           raise ValueError, "ERROR: nonconstant bound: " + str(exp)
44           return None
45
46    def _print_model_NL(self,model, OUTPUT, verbose=False):
47
48        # maps NL variables to the "real" variable names in the problem.
49        # it's really NL variable ordering, as there are no variable names
50        # in the NL format. however, we by convention make them go from
51        # x0 upward.
52        symbol_map = {}
53
54        #
55        # Collect statistics
56        #
57        nc = no = neqn = nrange = 0
58        Obj = model.active_components(Objective)
59        Con = model.active_components(Constraint)
60        Vars = model.active_components(Var)
61        Onontriv = model.Onontriv
62        for obj in Onontriv:
63                O = Obj[obj]
64                no += len(O._Onz)
65        Cnontriv = model.Cnontriv
66        for con in Cnontriv:
67                C = Con[con]
68                nc += len(C._Cnz)
69                for i in C._Cnz:
70                  if C[i].lower is not None:
71                           L = self._get_bound(C[i].lower)
72                           if C[i].upper is not None:
73                                    U = self._get_bound(C[i].upper)
74                                    if (L == U):
75                                             neqn += 1
76                                    elif L > U:
77                                             raise ValueError, "Constraint " + str(con) +\
78                                             "[" + str(i) + "]: lower bound = " + str(L) +\
79                                             " > upper bound = " + str(U)
80                                    else:
81                                             nrange += 1
82
83        icv = 0
84        Ilist = []
85        Blist = []
86        Vlist = []
87        for var in Vars.values():
88                Vv = var._varval
89                if isinstance(var.domain, IntegerSet):
90                  # print "Domain of", var._name, "= Integers"
91                  for ndx in Vv:
92                           if Vv[ndx].id >= 0:
93                                    Ilist.append((var,ndx))
94                elif isinstance(var.domain, BooleanSet):
95                  # print "Domain of", var._name, "= Boolean"
96                  for ndx in Vv:
97                           if Vv[ndx].id >= 0:
98                              L = Vv[ndx].lb()
99                              U = Vv[ndx].ub()
100                              if L is not None and value(L) == 0 \
101                                 and U is not None and value(U) == 1:
102                                        Blist.append((var,ndx))
103                              else:
104                                        Ilist.append((var,ndx))
105                else:
106                  # print "Domain of", var_.name, "is not discrete."
107                  for ndx in Vv:
108                           Vi = Vv[ndx]
109                           if Vi.id >= 0:
110                                    Vi.id = icv
111                                    icv += 1
112                                    Vlist.append((var,ndx))
113        for x in Blist:
114                x[0][x[1]].id = icv
115                icv += 1
116                Vlist.append((x[0],x[1]))
117        for x in Ilist:
118                x[0]._varval[x[1]].id = icv
119                icv += 1
120                Vlist.append((x[0],x[1]))
121        #
122        # Print Header
123        #
124        # LINE 1
125        #
126        print >>OUTPUT,"g3 1 1 0\t# problem",model.name
127        #
128        # LINE 2
129        #
130        print >>OUTPUT, " " + str(model.vnum), nc, no, nrange, str(neqn) +\
131                "\t# vars, constraints, objectives, ranges, eqns"
132        #
133        # LINE 3
134        #
135        print >>OUTPUT, " 0 0\t# nonlinear constraints, objectives"
136        #
137        # LINE 4
138        #
139        print >>OUTPUT, " 0 0\t# network constraints: nonlinear, linear"
140        #
141        # LINE 5
142        #
143        print >>OUTPUT, " 0 0 0\t# nonlinear vars in constraints, objectives, both"
144        #
145        # LINE 6
146        #
147        print >>OUTPUT, " 0 0 0 1\t# linear network variables; functions; arith, flags"
148        #
149        # LINE 7
150        #
151        niv = nbv = 0
152        for var in Vars.values():
153                Vv = var._varval
154                if isinstance(var.domain, IntegerSet):
155                  for i in Vv.keys():
156                           if Vv[i].id >= 0:
157                                    niv += 1
158                elif isinstance(var.domain, BooleanSet):
159                  for i in Vv.keys():
160                           if Vv[i].id >= 0:
161                                    nbv += 1
162        print >>OUTPUT, " " + str(nbv), niv, 0, 0,\
163                "0\t# discrete variables: binary, integer, nonlinear (b,c,o)"
164        #
165        # LINE 8
166        #
167        nsno = model.vnum
168        ngc = ngo = 0
169        for key in Obj:
170                for obj in Obj[key]._linterm:
171                    ngo += len(Obj[key]._linterm[obj])
172        cu = {}
173        for i in xrange(nsno):
174                cu[i] = 0
175        #Con = model.components(Constraint)
176        for key in Cnontriv:
177                C = Con[key]
178                for cndx in C._Cnz:
179                  LT = C._linterm[cndx]
180                  #print "HERE",LT.keys()
181                  for i in LT:
182                           #print "HERE",i,type(LT[i]),LT[i],type(LT[i][1]),LT[i][1]
183                           if i != '0':
184                              ngc += 1
185                              cu[LT[i][1].id] += 1
186        print >>OUTPUT, " " + str(ngc), str(ngo) + "\t# nonzeros in Jacobian, gradients"
187        #
188        # LINE 9
189        #
190        print >>OUTPUT, " 0 0\t# max name lengths: constraints, variables"
191        #
192        # LINE 10
193        #
194        print >>OUTPUT, " 0 0 0 0 0\t# common exprs: b,c,o,c1,o1"
195        #
196        # "C" lines
197        #
198        nc = 0
199        for key in Cnontriv:
200                for cndx in Con[key]._Cnz:
201                  print >>OUTPUT, "C" + str(nc) + "\t#" + str(key) + "[" + str(cndx) + "]"
202                  nc += 1
203                  #if '0' in Con[key]._linterm[cndx]:
204                  #  print >>OUTPUT, "n"+str(Con[key]._linterm[cndx]['0'][0])
205                  #else:
206                  #  print >>OUTPUT, "n0"
207                  print >>OUTPUT, "n0"
208        #
209        # "O" lines
210        #
211        no = 0
212        for key in Obj.keys():
213                k = 0
214                if Obj[key].sense == maximize:
215                        k = 1
216                for cndx in Obj[key]._Onz:
217                  print >>OUTPUT, "O" + str(no) + " "+str(k)+"\t#" + str(key) + "[" + str(cndx) + "]"
218                  no += 1
219                  LT = Obj[key]._linterm[cndx]
220                  if "0" in LT:
221                        print >>OUTPUT, "n" + str(LT["0"][0])
222                  else:
223                        print >>OUTPUT, "n0"
224        #
225        # "r" lines
226        #
227        print >>OUTPUT, "r"
228        nc=0
229        for key in Cnontriv:
230                C = Con[key]
231                for cndx in C._Cnz:
232                  if '0' in Con[key]._linterm[cndx]:
233                        offset=Con[key]._linterm[cndx]['0'][0]
234                  else:
235                        offset=0
236                  if C[cndx]._equality:
237                           print >>OUTPUT, "4", self._get_bound(C[cndx].lower)-offset,
238                  else:
239                           if C[cndx].lower is None:
240                                    if C[cndx].upper is None:
241                                             print >>OUTPUT,"3",
242                                    else:
243                                             print >>OUTPUT,"1", self._get_bound(C[cndx].upper)-offset,
244                           else:
245                                    if C[cndx].upper is None:
246                                             print >>OUTPUT,"2", self._get_bound(C[cndx].lower)-offset,
247                                    else:
248                                             print >>OUTPUT,"0",\
249                                                      self._get_bound(C[cndx].lower)-offset,\
250                                                      self._get_bound(C[cndx].upper)-offset,
251                  print >>OUTPUT, " # c"+ str(nc)+"  "+str(key) + "[" + str(cndx) + "]"
252                  symbol_map["c" + str(nc)] = str(key) + "[" + str(cndx) + "]"
253                  nc += 1
254        #
255        # "b" lines
256        #
257        print >>OUTPUT, "b"
258        nv=0
259        for i in xrange(len(Vlist)):
260                vi = Vlist[i]
261                var = vi[0]
262                ndx = vi[1]
263                if isinstance(var.domain, BooleanSet):
264                        print >>OUTPUT, "0 0 1",
265                        print >>OUTPUT, " # v"+str(nv)+"  "+str(var)+"["+str(ndx)+"]"
266                        nv += 1
267                        continue
268                vv = var._varval[ndx]
269                L = vv.lb()
270                U = vv.ub()
271                if L is not None:
272                  Lv = str(value(L))
273                  if U is not None:
274                           Uv = str(value(U))
275                           if Lv == Uv:
276                                    print >>OUTPUT, "4" , Lv,
277                           else:
278                                    print >>OUTPUT, "0", Lv, Uv,
279                  else:
280                           print >>OUTPUT, "2", Lv,
281                elif U is not None:
282                  print >>OUTPUT, "1", str(value(U)),
283                else:
284                  print >>OUTPUT, "3",
285                if ndx is not None:
286                   print >>OUTPUT, " # v"+str(nv)+"  "+str(var)+"["+str(ndx)+"]"
287                   symbol_map["v"+str(nv)] = (str(var)+"["+str(ndx)+"]")                   
288                else:
289                   print >>OUTPUT, " # v"+str(nv)+"  "+str(var)
290                   symbol_map["v"+str(nv)] = str(var)
291
292                nv += 1
293        #
294        # "k" lines
295        #
296        n1 = model.vnum - 1
297        print >>OUTPUT, "k" + str(n1)
298        ktot = 0
299        for i in xrange(n1):
300                ktot += cu[i]
301                print >>OUTPUT, ktot
302        #
303        # "J" lines
304        #
305        nc = 0
306        for key in Cnontriv:
307                C = Con[key]
308                for cndx in C._Cnz:
309                  LT = C._linterm[cndx]
310                  LT_len = len(LT) - ('0' in LT)
311                  print >>OUTPUT, "J" + str(nc), LT_len
312                  nc += 1
313                  for x in LT:
314                           if x != '0':
315                              p = LT[x]
316                              print >>OUTPUT, p[1].id, p[0]
317        #
318        # "G" lines
319        #
320        no = 0
321        for key in Obj:
322                OLT = Obj[key]._linterm
323                Ng = 0
324                for j in OLT:
325                        Ng += len(OLT[j])
326                print >>OUTPUT, "G" + str(no), Ng
327                no += 1
328                for j in OLT:
329                        LT = OLT[j]
330                        for x in LT:
331                                if x != '0':
332                                   p = LT[x]
333                                   print >>OUTPUT, p[1].id, p[0]
334
335        return symbol_map
336
337problem.WriterRegistration(str(ProblemFormat.nl), ProblemWriter_nl)
338
Note: See TracBrowser for help on using the repository browser.