Changeset 1772


Ignore:
Timestamp:
Oct 29, 2009 12:28:47 AM (11 years ago)
Author:
jwatson
Message:

Updates to allow for proper handling of variable maps in cases where formats cannot handle fully qualified,
human-readable variable names. Many ripple effects, as problem writers now must return a variable map (or None,
if not applicable. CBC now properly handles and reads NL and SOL input/output combinations!

Location:
trunk/coopr
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/coopr/opt/base/convert.py

    r1768 r1772  
    3939    if len(args) == 0:
    4040       raise ConverterError, "Empty argument list"
     41
    4142    #
    4243    # Setup list of source problem types
     
    5758    else:
    5859       source_ptype = args[0].valid_problem_types()
     60
    5961    #
    6062    # Setup list of valid problem types
     
    9193                tmp = [s_ptype,ptype] + list(args)
    9294                tmp = tuple(tmp)
    93                 return (converter.apply(*tmp), ptype)
     95                problem_files, variable_map = converter.apply(*tmp)
     96                return problem_files, ptype, variable_map
    9497    raise ConverterError, "No conversion possible.  Source problem type: %s.  Valid target types: %s" % (str(source_ptype[0]),map(str,valid_ptypes))
    9598
  • trunk/coopr/opt/base/solution.py

    r1770 r1772  
    1414from pyutilib.math import as_number
    1515from pyutilib.enum import Enum
     16
    1617import sys
    1718import StringIO
     
    214215        self.solution = SolutionSet()
    215216        self.initialize()
     217        self.variable_map = None
    216218
    217219    def initialize(self):
     
    262264        if not flag:        # pragma:nocover
    263265           print >>ostream, "  No Info"
     266        if self.variable_map is not None:
     267           print >>ostream, "  Variable map is available"
    264268        #
    265269        print >>ostream, "----------------------------------------------------------"
  • trunk/coopr/opt/base/solver.py

    r1768 r1772  
    1818import results
    1919from solution import SolverResults, SolverStatus
     20
    2021from pyutilib.enum import Enum
    2122from pyutilib.plugin.core import *
     
    115116            for key in kwds['options']:
    116117                setattr(self.options,key,kwds['options'][key])
     118        self._variable_map=None
    117119        self._problem_format=None
    118120        self._results_format=None
     
    136138        self._presolve(*args, **kwds)
    137139        self._apply_solver()
    138         return self._postsolve()
     140        result = self._postsolve()
     141        result.variable_map = self._variable_map
     142        return result
    139143
    140144    def _presolve(self, *args, **kwds):
     
    162166             raise ValueError, "Unknown option="+key+" for solver="+self.type
    163167
    164         (self._problem_files,self._problem_format) = self._convert_problem(args, self._problem_format, self._valid_problem_formats)
     168        (self._problem_files,self._problem_format,self._variable_map) = self._convert_problem(args, self._problem_format, self._valid_problem_formats)
    165169        if self._results_format is None:
    166170           self._results_format= self._default_results_format(self._problem_format)
  • trunk/coopr/opt/reader/sol.py

    r1657 r1772  
    2020from coopr.opt.base.formats import *
    2121from coopr.opt.base.solution import SolverResults, Solution
    22 
    2322
    2423class ResultsReader_sol(results.AbstractResultsReader):
     
    9897        for i in range(0,len(x)):
    9998            #soln.variable.add("_svar["+str(i)+"]", x[i])
    100             soln.variable.add("x"+str(i), x[i])
     99            soln.variable.add("V"+str(i), x[i])
    101100        for i in range(0,len(y)):
    102101            #soln.dual.add("_scon["+str(i)+"]", y[i])
  • trunk/coopr/opt/solver/shellcmd.py

    r1768 r1772  
    1313import sys
    1414import os
     15from coopr.opt.base import *
     16from coopr.opt.base.solver import *
     17import tempfile
     18
    1519import pyutilib.common
    1620import pyutilib.services
     
    1822import pyutilib.plugin.core
    1923import pyutilib.misc
    20 from coopr.opt.base import *
    21 from coopr.opt.base.solver import *
    22 import tempfile
    23 
    2424
    2525class SystemCallSolver(OptSolver):
     
    130130
    131131    def _postsolve(self):
     132
    132133        if self.log_file is not None:
    133134           OUTPUT=open(self.log_file,"w")
     
    150151           if not self.keepFiles:
    151152              pyutilib.services.TempfileManager.clear_tempfiles()
     153              # in some cases, the solution filename is not generated via the temp-file mechanism,
     154              # instead being automatically derived from the input lp/nl filename. so, we may
     155              # have to clean it up manually.
     156              if os.path.exists(self.soln_file):
     157                 os.remove(self.soln_file)
    152158
    153159        return results
     
    160166            [rc, log] = pyutilib.subprocess.run(command.cmd, timelimit=self._timelimit, env=command.env, tee=self.tee, shell=True)
    161167        except pyutilib.common.WindowsError, err:
    162             raise pyutilib.Acommon.pplicationError, "Could not execute the command: "+command.cmd+"\tError message: "+str(err)
     168            raise pyutilib.common.ApplicationError, "Could not execute the command: "+command.cmd+"\tError message: "+str(err)
    163169        sys.stdout.flush()
    164170        return [rc,log]
  • trunk/coopr/plugins/converter/glpsol.py

    r1768 r1772  
    1212
    1313from coopr.opt.base import *
     14
    1415from pyutilib.plugin.core import *
    1516from pyutilib.plugin.config import *
     
    1718import pyutilib.subprocess
    1819import pyutilib.common
    19 
    2020
    2121class GlpsolMIPConverter(ManagedSingletonPlugin):
     
    101101        if os.path.exists("glpsol.mod"):
    102102            os.remove("glpsol.mod")
    103         return (ofile,)
    104 
     103        return (ofile,),None # empty variable map
  • trunk/coopr/plugins/converter/pico.py

    r1768 r1772  
    1212
    1313from coopr.opt.base import *
     14
    1415from pyutilib.plugin.core import *
    1516from pyutilib.plugin.config import *
     
    1819import pyutilib.common
    1920import pyutilib.subprocess
    20 
    2121
    2222class PicoMIPConverter(ManagedSingletonPlugin):
     
    8080            raise pyutilib.common.ApplicationError, \
    8181                    "Problem launching 'pico_convert' to create "+output_filename
    82         return (output_filename,)
     82        return (output_filename,),None # no variable map at the momoent
    8383
    8484
  • trunk/coopr/plugins/converter/pyomo.py

    r1768 r1772  
    1313
    1414from coopr.opt.base import *
     15from pico import PicoMIPConverter
     16
    1517from pyutilib.plugin.core import *
    1618from pyutilib.plugin.config import *
    1719from pyutilib.plugin.executables import *
    1820import pyutilib.services
    19 from pico import PicoMIPConverter
    20 
    2121
    2222class PyomoMIPConverter(ManagedSingletonPlugin):
     
    4848        conversions.
    4949        """
     50
    5051        if args[1] is ProblemFormat.cpxlp:
    5152            problem_filename = pyutilib.services.TempfileManager.create_tempfile(suffix = '.pyomo.lp')
    52             args[2].write(filename=problem_filename,format=ProblemFormat.cpxlp)
    53             return (problem_filename,)
     53            (problem_filename, varmap) = args[2].write(filename=problem_filename,format=ProblemFormat.cpxlp)
     54            return (problem_filename,),None # no map file is necessary
    5455        elif args[1] is ProblemFormat.mps:
     56            # TBD: We don't support a variable map file when going from NL to MPS within the PICO converter.
    5557            problem_filename = pyutilib.services.TempfileManager.create_tempfile(suffix = '.pyomo.nl')
    56             args[2].write(filename=problem_filename,format=ProblemFormat.nl)
     58            (problem_filename, varmap) = args[2].write(filename=problem_filename,format=ProblemFormat.nl)
    5759            ans = self.pico_converter.apply(ProblemFormat.nl,ProblemFormat.mps,problem_filename)
    5860            os.remove(problem_filename)
     
    6062        elif args[1] is ProblemFormat.nl:
    6163            problem_filename = pyutilib.services.TempfileManager.create_tempfile(suffix = '.pyomo.nl')
    62             args[2].write(filename=problem_filename,format=ProblemFormat.nl)
    63             return (problem_filename,)
    64 
    65 
    66 
     64            (problem_filename, variable_map) = args[2].write(filename=problem_filename,format=ProblemFormat.nl)
     65            return (problem_filename,),variable_map # map file is necessary
  • trunk/coopr/plugins/mip/CBC.py

    r1768 r1772  
    3737        self._valid_result_formats={}
    3838        self._valid_result_formats[ProblemFormat.mps] = [ResultsFormat.log]
    39         self._valid_result_formats[ProblemFormat.nl] = [ResultsFormat.log]
     39        self._valid_result_formats[ProblemFormat.nl] = [ResultsFormat.sol]
    4040        self._valid_result_formats[ProblemFormat.cpxlp] = [ResultsFormat.log]
     41
     42    def _presolve(self, *args, **kwds):
     43
     44       # establish real "default" problem and results formats. these may be
     45       # over-ridden in the base class solve (via keywords), but we should
     46       # have real values by the time we're presolving.
     47
     48       if self._problem_format is None:
     49
     50          if self._valid_problem_formats[0] is ProblemFormat.nl:
     51             self._problem_format = ProblemFormat.nl
     52          else:
     53             self._problem_format = ProblemFormat.cpxlp
     54
     55       if self._problem_format is ProblemFormat.nl:
     56          self._results_format = ResultsFormat.sol
     57       else:
     58          self._results_format = ResultsFormat.log
     59
     60       # let the base class handle any remaining keywords/actions.
     61       SystemCallSolver._presolve(self, *args, **kwds)       
    4162
    4263    def executable(self):
     
    5071    def create_command_line(self,executable,problem_files):
    5172        #
    52         # Define log file
     73        # Define log file 
    5374        #
    5475        if self.log_file is None:
    5576           self.log_file = pyutilib.services.TempfileManager.create_tempfile(suffix=".cbc.log")
    56         fname = problem_files[0].split(os.sep)[-1]
    57         if '.' in fname:
    58             tmp = fname.split('.')
     77
     78        #
     79        # Define solution file
     80        #
     81
     82        # the prefix of the problem filename is required because CBC has a specific
     83        # and automatic convention for generating the output solution filename
     84        problem_filename_prefix = problem_files[0]
     85        if '.' in problem_filename_prefix:
     86            tmp = problem_filename_prefix.split('.')
    5987            if len(tmp) > 2:
    60                 fname = '.'.join(tmp[:-1])
    61             else:
    62                 fname = tmp[0]
    63         #
    64         # Define solution file
    65         #
    66         if self.soln_file is None:
    67            self.soln_file = pyutilib.services.TempfileManager.create_tempfile(suffix=fname+".cbc.soln")
    68         self.sol_file = fname+".sol"
     88                problem_filename_prefix = '.'.join(tmp[:-1])
     89            else:
     90                problem_filename_prefix = tmp[0]
     91
     92        self.soln_file = problem_filename_prefix+".sol"
     93
    6994        #
    7095        # Define results file
     
    7297        if self._results_format is None or self._results_format == ResultsFormat.log:
    7398           self.results_file = self.log_file
     99        else:
     100           self.results_file = self.soln_file
    74101        #elif self._results_format == ResultsFormat.osrl:
    75102        #   self.results_file = self.tmpDir+os.sep+"cbc.osrl.xml"
    76103
    77104        #
    78         # Define command line (only one problem format supported: MPS)
     105        # Define command line
    79106        #
    80107        if self._problem_format == ProblemFormat.nl:
     
    110137            proc = self._timer + " " + executable + opt + " -printingOptions all "+timing+ " -import "+problem_files[0]+ " -import -stat -solve -solu " + self.soln_file
    111138        return pyutilib.misc.Bunch(cmd=proc, log_file=self.log_file, env=None)
    112 
    113     def _execute_command(self,cmd):
    114         ans = SystemCallSolver._execute_command(self,cmd)
    115         if os.path.exists("cbc.soln"):
    116            os.rename("cbc.soln",self.soln_file)
    117         return ans
    118139
    119140    def process_logfile(self):
     
    223244
    224245    def process_other_data(self,results):
    225         if os.path.exists(self.sol_file):
    226             results_reader = ReaderFactory(ResultsFormat.sol)
    227             results = results_reader(self.sol_file, results, results.solution(0))
    228             return
    229         if not os.path.exists(self.soln_file):
     246
     247        # if the results format is SOL, then the results have already been read. otherwise,
     248        # parse the CBC-specific format.
     249        if self._results_format is ResultsFormat.sol:
    230250           return
     251
    231252        solution = results.solution(0)
    232253        if solution.status is SolutionStatus.infeasible:
  • trunk/coopr/pyomo/base/PyomoModel.py

    r1768 r1772  
    232232              raise ValueError, "Cannot load a SolverResults object with bad status: "+str(arg.solver.status)
    233233           if len(arg.solution) > 0:
    234               self._load_solution(arg.solution(0))
     234              self._load_solution(arg.solution(0),variable_map=arg.variable_map)
    235235              return True
    236236           else:
     
    288288            raise err
    289289
    290     def _load_solution(self,soln):
     290    def _load_solution(self,soln, variable_map=None):
    291291        """
    292292        Load a solution.
     
    300300          #
    301301          if name != "ONE_VAR_CONSTANT":
     302             # translate the name first if there is a variable map associated with the input solution.
     303             if variable_map is not None:
     304                 name = variable_map[name]
    302305             if name not in self._name_varmap:
    303306                names=""
     
    325328        if problem_writer is None:
    326329           raise ValueError, "Cannot write model in format \"" + str(format) + "\": no model writer registered for that format"
    327         fname = problem_writer(self, filename)
     330        (fname, variable_map) = problem_writer(self, filename)
    328331        if pyomo.debug("verbose"):
    329332           print "Writing model "+self.name+" to file '"+str(fname)+"'  with format "+str(format)
    330         return fname
     333        return fname, variable_map
    331334
    332335
  • trunk/coopr/pyomo/io/ampl.py

    r1670 r1772  
    2929           filename = model.name + ".nl"
    3030        OUTPUT=open(filename,"w")
    31         self._print_model_NL(model,OUTPUT)
     31        variable_map = self._print_model_NL(model,OUTPUT)
    3232        OUTPUT.close()
    33         return filename
     33        return filename, variable_map
    3434
    3535    def _get_bound(self, exp):
     
    4545
    4646    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        variable_map = {}
     53
    4754        #
    4855        # Collect statistics
     
    275282                else:
    276283                  print >>OUTPUT, "3",
    277                 print >>OUTPUT, " # V"+str(nv)+"  "+str(var)+"["+str(ndx)+"]"
     284                if ndx is not None:
     285                   print >>OUTPUT, " # V"+str(nv)+"  "+str(var)+"["+str(ndx)+"]"
     286                   variable_map["V"+str(nv)] = (str(var)+"["+str(ndx)+"]")                   
     287                else:
     288                   print >>OUTPUT, " # V"+str(nv)+"  "+str(var)
     289                   variable_map["V"+str(nv)] = str(var)
     290
    278291                nv += 1
    279292        #
     
    319332                                   print >>OUTPUT, p[1].id, p[0]
    320333
     334        return variable_map
    321335
    322336problem.WriterRegistration(str(ProblemFormat.nl), ProblemWriter_nl)
  • trunk/coopr/pyomo/io/cpxlp.py

    r1766 r1772  
    5959        self._print_model_LP(model,OUTPUT)
    6060        OUTPUT.close()
    61         return filename
     61        return filename, None
    6262
    6363    def _get_bound(self, exp):
Note: See TracChangeset for help on using the changeset viewer.