Changeset 2936


Ignore:
Timestamp:
Aug 14, 2010 6:39:28 PM (9 years ago)
Author:
wehart
Message:

Merged revisions 2731-2935 via svnmerge from
https://software.sandia.gov/svn/public/coopr/coopr.plugins/trunk

........

r2746 | khunter | 2010-06-30 12:57:16 -0600 (Wed, 30 Jun 2010) | 2 lines


NFC

........

r2747 | khunter | 2010-06-30 12:58:38 -0600 (Wed, 30 Jun 2010) | 5 lines


Add OSiL writer plugin; enables pyomo --solver


Enable OSiL writer plugin as a command line option through pyomo
--solver=ossolver

........

r2771 | wehart | 2010-07-05 15:18:20 -0600 (Mon, 05 Jul 2010) | 2 lines


Resolving backwards compatibility for Python 2.4

........

r2774 | khunter | 2010-07-06 09:23:13 -0600 (Tue, 06 Jul 2010) | 2 lines


NFC: Whitespace removal, and 80-char update to selected functions.

........

r2775 | khunter | 2010-07-06 09:30:23 -0600 (Tue, 06 Jul 2010) | 3 lines


General refactor of GLPK executable line creation. Specifically,
this should fix r4083 (for Al Holder).

........

r2776 | khunter | 2010-07-06 10:15:04 -0600 (Tue, 06 Jul 2010) | 3 lines


4 lines to 2 lines in slightly less efficient, but perhaps cleaner
way. It's used but once, so performance is not a concern.

........

r2777 | khunter | 2010-07-06 10:33:22 -0600 (Tue, 06 Jul 2010) | 5 lines


Backslash line continuation not universal


Apparently you can't use the '\' line continuation trick for import
lines.

........

r2825 | jwatson | 2010-07-20 14:00:36 -0600 (Tue, 20 Jul 2010) | 3 lines


Modified GLPK plugin to throw an exception when unexpected line parse issues are encountered, so we (and the user) can quickly identify the line at fault. And figure out that GLPK is the issue.

........

r2853 | jwatson | 2010-07-25 22:17:28 -0600 (Sun, 25 Jul 2010) | 3 lines


Adding solution infeasible status to CPLEX plugin - Pyomo will now indicate status correctly.

........

r2854 | jwatson | 2010-07-26 21:53:26 -0600 (Mon, 26 Jul 2010) | 1 line


Fixed exception raised by GLPK plugin when encountering the previously unknown NF (non-basic free/unbounded variable) in a solution file

........

r2855 | khunter | 2010-07-27 09:59:14 -0600 (Tue, 27 Jul 2010) | 2 lines


NFC: EOL whitespace

........

r2856 | khunter | 2010-07-27 10:00:14 -0600 (Tue, 27 Jul 2010) | 2 lines


NFC: Use a more pythonic form; easier to read.

........

r2857 | khunter | 2010-07-27 10:00:58 -0600 (Tue, 27 Jul 2010) | 2 lines


NFC: Remove unnecessary branch.

........

r2902 | prsteel | 2010-08-03 10:54:48 -0600 (Tue, 03 Aug 2010) | 10 lines


Fixes parsing error on infeasible/unbounded problems.


Not actually sure exactly what fixed the problem; I started by making
the indentation uniform so my editor could play nicely with the code,
and the error went away, suggesting that a 'raise' statement was
poorly aligned in the original code.


Doesn't

........

r2903 | prsteel | 2010-08-03 10:58:43 -0600 (Tue, 03 Aug 2010) | 2 lines


Reverting previous change to give a better commit message...

........

r2904 | prsteel | 2010-08-03 11:02:33 -0600 (Tue, 03 Aug 2010) | 15 lines


Fixes bug in Pyomo reading unbounded/infeasible solution files from
GLPK.


Bug fixed as a side effect while formatting code to fix the bug,
indicating that it was likely caused by a poorly-indented raise
statement, or some other source of an Exception that was resolved via
new indentation.


It is worthwhile here to note that our solution may still read as
'infeasible' when the problem is in fact known to be unbounded; this
is due to GLPK's presolver, and short of turning off GLPK's presolver
this is beyond Pyomo's abilities to fix.

........

r2909 | wehart | 2010-08-05 15:11:34 -0600 (Thu, 05 Aug 2010) | 2 lines


Bug fix ... always need to create the test suties, in order for nose to find it.

........

r2925 | wehart | 2010-08-14 13:19:38 -0600 (Sat, 14 Aug 2010) | 6 lines


Fixing logic in parsing of marginal values. I believe that a bug was
introduced in the reformatting of this section in r2904. (This is a case
where Python's white-space indention proved problematic!)


Added additional I/O for general exceptions.

........

r2926 | wehart | 2010-08-14 13:36:36 -0600 (Sat, 14 Aug 2010) | 2 lines


Evaluating tokens before they are used to define values in the results object.

........

r2933 | wehart | 2010-08-14 16:32:27 -0600 (Sat, 14 Aug 2010) | 2 lines


Update to baseline to eliminate 'None' string.

........

Location:
coopr.plugins/stable/2.4
Files:
7 edited
1 copied

Legend:

Unmodified
Added
Removed
  • coopr.plugins/stable/2.4

  • coopr.plugins/stable/2.4/coopr/plugins/converter/pyomo.py

    r2731 r2936  
    3333    def can_convert(self, from_type, to_type):
    3434        """Returns true if this object supports the specified conversion"""
     35        if from_type != ProblemFormat.pyomo:
     36            return False
    3537        #
    3638        # Return True for specific from/to pairs
    3739        #
    38         if from_type == ProblemFormat.pyomo and to_type == ProblemFormat.nl:
     40        if to_type in ( ProblemFormat.nl, ProblemFormat.cpxlp,
     41                        ProblemFormat.osil ):
    3942            return True
    40         if from_type == ProblemFormat.pyomo and to_type == ProblemFormat.cpxlp:
     43
     44        if to_type == ProblemFormat.mps and self.pico_converter.available():
    4145            return True
    42         if self.pico_converter.available() and from_type == ProblemFormat.pyomo and to_type == ProblemFormat.mps:
    43             return True
     46
    4447        return False
    4548
     
    8386            #
    8487            # Convert from NL to MPS
    85             # 
     88            #
    8689            # TBD: We don't support a variable map file when going from NL to MPS within the PICO converter.
    8790            # NOTE: this is a problem with the MPS writer that is provided by COIN-OR
     
    9295            return ans
    9396
     97        elif args[1] is ProblemFormat.osil:
     98            problem_filename = pyutilib.services.TempfileManager.create_tempfile(suffix='pyomo.osil')
     99            if instance:
     100                (problem_filename, varmap) = instance.write(filename=problem_filename, format=ProblemFormat.osil)
     101                return (problem_filename,), None
     102            else:
     103                msg = 'There is currently no script conversion available from\n'
     104                msg += 'Pyomo to OSiL format.'
     105
     106                raise NotImplementedError, msg
  • coopr.plugins/stable/2.4/coopr/plugins/mip/CPLEX.py

    r2731 r2936  
    284284            elif len(tokens) >= 3 and tokens[0] == "Variables":
    285285                if results.problem.number_of_variables is None: # CPLEX 11.2 and subsequent versions have two Variables sections in the log file output.
    286                     results.problem.number_of_variables = tokens[2]
     286                    results.problem.number_of_variables = eval(tokens[2])
    287287            # In CPLEX 11 (and presumably before), there was only a single line output to
    288288            # indicate the constriant count, e.g., "Linear constraints : 16 [Less: 7, Greater: 6, Equal: 3]".
     
    292292            # that's all.
    293293            elif len(tokens) >= 4 and tokens[0] == "Linear" and tokens[1] == "constraints":
    294                 results.problem.number_of_constraints = tokens[3]
     294                results.problem.number_of_constraints = eval(tokens[3])
    295295            elif len(tokens) >= 3 and tokens[0] == "Nonzeros":
    296296                if results.problem.number_of_nonzeros is None: # CPLEX 11.2 and subsequent has two Nonzeros sections.               
    297                     results.problem.number_of_nonzeros = tokens[2]
     297                    results.problem.number_of_nonzeros = eval(tokens[2])
    298298            elif len(tokens) >= 5 and tokens[4] == "MINIMIZE":
    299299                results.problem.sense = ProblemSense.minimize
     
    348348                results.solver.termination_condition = TerminationCondition.unbounded
    349349                results.solver.termination_message = ' '.join(tokens)
     350
     351        try:
     352            results.solver.termination_message = pyutilib.misc.yaml_fix(results.solver.termination_message)
     353        except:
     354            pass
    350355        return results
    351356
     
    473478            elif tokens[0].startswith("objectiveValue"):
    474479                objective_value = (string.strip(tokens[0].split('=')[1])).lstrip("\"").rstrip("\"")
    475                 soln.objective['f'].value = objective_value
     480                soln.objective['f'].value = eval(objective_value)
    476481            elif tokens[0].startswith("solutionStatusString"):
    477482                solution_status = (string.strip(" ".join(tokens).split('=')[1])).lstrip("\"").rstrip("\"")
     
    488493                            del results.problem.lower_bound
    489494                    mip_problem=True
     495                elif solution_status in ["infeasible"]:
     496                    soln.status = SolutionStatus.infeasible
     497                    soln.gap = None
    490498            elif tokens[0].startswith("MIPNodes"):
    491499                if mip_problem:
    492                     n = eval(string.strip(" ".join(tokens).split('=')[1])).lstrip("\"").rstrip("\"")
     500                    n = eval(eval(string.strip(" ".join(tokens).split('=')[1])).lstrip("\"").rstrip("\""))
    493501                    results.solver.statistics.branch_and_bound.number_of_created_subproblems=n
    494502                    results.solver.statistics.branch_and_bound.number_of_bounded_subproblems=n
  • coopr.plugins/stable/2.4/coopr/plugins/mip/GLPK.py

    r2731 r2936  
    1212import os
    1313import re
     14
    1415from coopr.opt.base import *
    1516from coopr.opt.results import *
    1617from coopr.opt.solver import *
    1718import mockmip
    18 import pyutilib.services
    19 import pyutilib.misc
    20 import pyutilib.common
    21 import pyutilib.component.core
     19from pyutilib.common import ApplicationError
     20from pyutilib.component.core import alias, PluginGlobals
     21from pyutilib.misc import Bunch, Options
     22from pyutilib.services import register_executable, registered_executable
     23from pyutilib.services import TempfileManager
    2224
    2325
    2426class GLPK(SystemCallSolver):
    25     """The GLPK LP/MIP solver
    26     """
    27 
    28     pyutilib.component.core.alias('glpk')
     27    """The GLPK LP/MIP solver"""
     28
     29    alias('glpk')
    2930
    3031    def __init__(self, **kwds):
     
    3738        # Valid problem formats, and valid results for each format
    3839        #
    39         self._valid_problem_formats=[ProblemFormat.mod, ProblemFormat.cpxlp, ProblemFormat.mps]
    40         self._valid_result_formats={}
    41         self._valid_result_formats[ProblemFormat.mod] = [ResultsFormat.soln]
    42         self._valid_result_formats[ProblemFormat.cpxlp] = [ResultsFormat.soln]
    43         self._valid_result_formats[ProblemFormat.mps] = [ResultsFormat.soln]
     40        self._valid_problem_formats = [
     41               ProblemFormat.mod, ProblemFormat.cpxlp, ProblemFormat.mps]
     42        self._valid_result_formats = {
     43            ProblemFormat.mod: ResultsFormat.soln,
     44            ProblemFormat.cpxlp: ResultsFormat.soln,
     45            ProblemFormat.mps: ResultsFormat.soln,
     46        }
    4447
    4548        # Note: Undefined capabilities default to 'None'
    46         self._capabilities = pyutilib.misc.Options()
     49        self._capabilities = Options()
    4750        self._capabilities.linear = True
    4851        self._capabilities.integer = True
    4952
    5053    def executable(self):
    51         executable = pyutilib.services.registered_executable("glpsol")
     54        executable = registered_executable('glpsol')
    5255        if executable is None:
    53             pyutilib.component.core.PluginGlobals.env().log.error("Could not locate the 'glpsol' executable, which is required for solver %s" % self.name)
     56            msg = "Could not locate the 'glpsol' executable, which is " \
     57                  "required for solver '%s'"
     58            PluginGlobals.env().log.error(msg % self.name)
    5459            self.enable = False
    5560            return None
     61
    5662        return executable.get_path()
    5763
    58     def create_command_line(self,executable,problem_files):
     64    def create_command_line(self, executable, problem_files):
    5965        #
    6066        # Define log file
    6167        #
    6268        if self.log_file is None:
    63            self.log_file = pyutilib.services.TempfileManager.create_tempfile(suffix = '.glpk.log')
     69            self.log_file = TempfileManager.create_tempfile(suffix='.glpk.log')
    6470
    6571        #
     
    6773        #
    6874        if self.soln_file is None:
    69             self.soln_file = pyutilib.services.TempfileManager.create_tempfile(suffix = '.glpk.soln')
     75            self.soln_file = \
     76                           TempfileManager.create_tempfile(suffix='.glpk.soln')
    7077
    7178        #
    7279        # Define results file
    7380        #
    74         if self._results_format is None or self._results_format == ResultsFormat.soln:
    75            self.results_file = self.soln_file
    76            
     81        if self._results_format is None \
     82           or self._results_format == ResultsFormat.soln:
     83            self.results_file = self.soln_file
     84
    7785        #
    7886        # Define command line
    7987        #
     88        cmd = [self._timer, '"%s"' % executable]
     89        for key in self.options:
     90            if isinstance(self.options[key], basestring) \
     91                   and ' ' in self.options[key]:
     92                cmd.append('--%s "%s"' % (key, str(self.options[key])))
     93            else:
     94                cmd.append('--%s %s' % (key, str(self.options[key])))
     95
    8096        if self._timelimit is not None and self._timelimit > 0.0:
    81            timing = " --tmlim "+str(self._timelimit)+" "
    82         else:
    83            timing = ""
     97            cmd.append('--tmlim ' + str(self._timelimit))
     98
    8499        if (self.mipgap is not None) and (self.mipgap > 0.0):
    85            mipgap = " --mipgap "+str(self.mipgap)+" "
    86         else:
    87            mipgap = ""           
     100            cmd.append('--mipgap ' + str(self.mipgap))
     101        cmd.append('--output ' + self.soln_file)
     102
    88103        if self._problem_format == ProblemFormat.cpxlp:
    89             problem=" --cpxlp " + problem_files[0]
     104            cmd.append('--cpxlp ' + problem_files[0])
    90105        elif self._problem_format == ProblemFormat.mps:
    91             problem=" --freemps " + problem_files[0]
     106            cmd.append('--freemps ' + problem_files[0])
    92107        elif self._problem_format == ProblemFormat.mod:
    93             problem=" --math " + problem_files[0]
    94             for filename in problem_files[1:]:
    95                 problem += " --data " + filename
    96         opt = ""
    97         for key in self.options:
    98             if isinstance(self.options[key],basestring) and ' ' in self.options[key]:
    99                 opt += " --"+key+" \""+str(self.options[key])+"\""
    100             else:
    101                 opt += " --"+key+" "+str(self.options[key])
    102         proc = self._timer + " " + executable + opt + " " + timing + mipgap + " --output " + self.soln_file + problem
    103         return pyutilib.misc.Bunch(cmd=proc, log_file=self.log_file, env=None)
     108            cmd.append('--math ' + problem_files[0])
     109            cmd.append('--data "%s"' % fname for fname in problem_files[1:])
     110
     111        cmd = ' '.join(cmd)
     112
     113        return Bunch(cmd=cmd, log_file=self.log_file, env=None)
    104114
    105115    def process_logfile(self):
     
    111121        # Initial values
    112122        #
    113         #results.solver.statistics.branch_and_bound.number_of_created_subproblems=0
    114         #results.solver.statistics.branch_and_bound.number_of_bounded_subproblems=0
     123        # results.solver.statistics.branch_and_bound.
     124        #     number_of_created_subproblems=0
     125        # results.solver.statistics.branch_and_bound.
     126        #     number_of_bounded_subproblems=0
    115127        soln = results.solution.add()
    116         soln.objective['f']=float('inf')
     128        soln.objective['f'] = float('inf')
    117129        #
    118130        # Process logfile
     
    124136        # Parse logfile lines
    125137        #
     138
     139        # Handle long variable names
     140        stats = results.solver.statistics
     141
    126142        for line in output.split("\n"):
    127           tokens = re.split('[ \t]+',line.strip())
    128           if len(tokens) > 4 and tokens[1] == "objval":
    129              soln.objective['f'] = tokens[3]
    130           elif len(tokens) > 3 and tokens[0] == "Objective" and tokens[1] == "value":
    131              soln.objective['f'] = tokens[3]
    132           elif len(tokens) > 4 and tokens[0] == "!" and tokens[2] == "objval":
    133              soln.objective['f'] = tokens[4]
    134           elif len(tokens) > 4 and tokens[0] == "+" and tokens[2] == "objval":
    135              soln.objective['f'] = tokens[4]
    136           elif len(tokens) > 4 and tokens[0] == "*" and tokens[2] == "objval":
    137              soln.objective['f'] = tokens[4]
    138           elif len(tokens) > 4 and tokens[0] == "+" and tokens[2] == "mip" and tokens[4] == "not":
    139              soln.objective['f'] = "unknown"
    140              results.problem.lower_bound = tokens[8]
    141           elif len(tokens) > 4 and tokens[0] == "+" and tokens[1] == "mip" and tokens[4] == "not":
    142              soln.objective['f'] = "unknown"
    143              results.problem.lower_bound = tokens[7]
    144           elif len(tokens) > 4 and tokens[0] == "+" and tokens[2] == "mip" and tokens[4] != "not":
    145              soln.objective['f'] = tokens[4]
    146              if tokens[6] != "tree":
    147                 results.problem.lower_bound = tokens[6]
    148           elif len(tokens) > 4 and tokens[0] == "+" and tokens[1] == "mip" and tokens[4] != "not":
    149              soln.objective['f'] = tokens[3]
    150              results.problem.lower_bound = tokens[5]
    151           elif len(tokens) == 6 and tokens[0] == "OPTIMAL" and tokens[1] == "SOLUTION" and tokens[5] == "PRESOLVER":
    152              results.solver.statistics.branch_and_bound.number_of_created_subproblems = 0
    153              results.solver.statistics.branch_and_bound.number_of_bounded_subproblems = 0
    154              soln.status = SolutionStatus.optimal
    155           elif len(tokens) == 7 and tokens[1] == "OPTIMAL" and tokens[2] == "SOLUTION" and tokens[6] == "PRESOLVER":
    156              results.solver.statistics.branch_and_bound.number_of_created_subproblems = 0
    157              results.solver.statistics.branch_and_bound.number_of_bounded_subproblems = 0
    158              soln.status = SolutionStatus.optimal
    159           elif len(tokens) > 10 and tokens[0] == "+" and tokens[8] == "empty":
    160              results.solver.statistics.branch_and_bound.number_of_created_subproblems = tokens[11][:-1]
    161              results.solver.statistics.branch_and_bound.number_of_bounded_subproblems = tokens[11][:-1]
    162           elif len(tokens) > 9 and tokens[0] == "+" and tokens[7] == "empty":
    163              results.solver.statistics.branch_and_bound.number_of_created_subproblems = tokens[10][:-1]
    164              results.solver.statistics.branch_and_bound.number_of_bounded_subproblems = tokens[10][:-1]
    165           elif len(tokens) == 2 and tokens[0] == "sys":
    166              results.solver.system_time=tokens[1]
    167           elif len(tokens) == 2 and tokens[0] == "user":
    168              results.solver.user_time=tokens[1]
    169           elif len(tokens) > 2 and tokens[0] == "OPTIMAL" and tokens[1] == "SOLUTION":
    170              soln.status = SolutionStatus.optimal
    171           elif len(tokens) > 2 and tokens[0] == "INTEGER" and tokens[1] == "OPTIMAL":
    172              soln.status = SolutionStatus.optimal
    173              results.solver.statistics.branch_and_bound.number_of_created_subproblems = 0
    174              results.solver.statistics.branch_and_bound.number_of_bounded_subproblems = 0
    175           elif len(tokens) > 2 and tokens[0] == "TIME" and tokens[2] == "EXCEEDED;":
    176              soln.status = SolutionStatus.stoppedByLimit
     143            tokens = re.split('[ \t]+', line.strip())
     144            if len(tokens) > 4 and tokens[1] == "objval":
     145                soln.objective['f'] = tokens[3]
     146            elif len(tokens) > 3 and tokens[0] == "Objective" and \
     147                     tokens[1] == "value":
     148                soln.objective['f'] = tokens[3]
     149            elif len(tokens) > 4 and tokens[0] == "!" and \
     150                     tokens[2] == "objval":
     151                soln.objective['f'] = tokens[4]
     152            elif len(tokens) > 4 and tokens[0] == "+" and \
     153                     tokens[2] == "objval":
     154                soln.objective['f'] = tokens[4]
     155            elif len(tokens) > 4 and tokens[0] == "*" and \
     156                     tokens[2] == "objval":
     157                soln.objective['f'] = tokens[4]
     158            elif len(tokens) > 4 and tokens[0] == "+" and \
     159                     tokens[2] == "mip" and tokens[4] == "not":
     160                soln.objective['f'] = "unknown"
     161                results.problem.lower_bound = tokens[8]
     162            elif len(tokens) > 4 and tokens[0] == "+" and \
     163                     tokens[1] == "mip" and tokens[4] == "not":
     164                soln.objective['f'] = "unknown"
     165                results.problem.lower_bound = tokens[7]
     166            elif len(tokens) > 4 and tokens[0] == "+" and \
     167                     tokens[2] == "mip" and tokens[4] != "not":
     168                soln.objective['f'] = tokens[4]
     169                if tokens[6] != "tree":
     170                    results.problem.lower_bound = tokens[6]
     171            elif len(tokens) > 4 and tokens[0] == "+" and \
     172                     tokens[1] == "mip" and tokens[4] != "not":
     173                soln.objective['f'] = tokens[3]
     174                results.problem.lower_bound = tokens[5]
     175            elif len(tokens) == 6 and tokens[0] == "OPTIMAL" and \
     176                     tokens[1] == "SOLUTION" and tokens[5] == "PRESOLVER":
     177                stats.branch_and_bound.number_of_created_subproblems = 0
     178                stats.branch_and_bound.number_of_bounded_subproblems = 0
     179                soln.status = SolutionStatus.optimal
     180            elif len(tokens) == 7 and tokens[1] == "OPTIMAL" and \
     181                     tokens[2] == "SOLUTION" and tokens[6] == "PRESOLVER":
     182                stats.branch_and_bound.number_of_created_subproblems = 0
     183                stats.branch_and_bound.number_of_bounded_subproblems = 0
     184                soln.status = SolutionStatus.optimal
     185            elif len(tokens) > 10 and tokens[0] == "+" and \
     186                     tokens[8] == "empty":
     187                stats.branch_and_bound.number_of_created_subproblems = tokens[11][:-1]
     188                stats.branch_and_bound.number_of_bounded_subproblems = tokens[11][:-1]
     189            elif len(tokens) > 9 and tokens[0] == "+" and \
     190                     tokens[7] == "empty":
     191                stats.branch_and_bound.number_of_created_subproblems = tokens[10][:-1]
     192                stats.branch_and_bound.number_of_bounded_subproblems = tokens[10][:-1]
     193            elif len(tokens) == 2 and tokens[0] == "sys":
     194                results.solver.system_time = tokens[1]
     195            elif len(tokens) == 2 and tokens[0] == "user":
     196                results.solver.user_time = tokens[1]
     197            elif len(tokens) > 2 and tokens[0] == "OPTIMAL" and \
     198                     tokens[1] == "SOLUTION":
     199                soln.status = SolutionStatus.optimal
     200            elif len(tokens) > 2 and tokens[0] == "INTEGER" and \
     201                     tokens[1] == "OPTIMAL":
     202                soln.status = SolutionStatus.optimal
     203                stats.branch_and_bound.number_of_created_subproblems = 0
     204                stats.branch_and_bound.number_of_bounded_subproblems = 0
     205            elif len(tokens) > 2 and tokens[0] == "TIME" and \
     206                     tokens[2] == "EXCEEDED;":
     207                soln.status = SolutionStatus.stoppedByLimit
    177208        if results.problem.upper_bound == "inf":
    178            results.problem.upper_bound = 'Infinity'
     209            results.problem.upper_bound = 'Infinity'
    179210        if results.problem.lower_bound == "-inf":
    180            results.problem.lower_bound = "-Infinity"
     211            results.problem.lower_bound = "-Infinity"
    181212        try:
    182213            val = results.problem.upper_bound
     
    198229            pass
    199230        if soln.status is SolutionStatus.optimal:
    200            soln.gap=0.0
     231            soln.gap = 0.0
    201232        elif soln.status is SolutionStatus.stoppedByLimit:
    202            soln.gap = "Infinity" # until proven otherwise
    203            if "lower_bound" in dir(results.problem):
    204               if results.problem.lower_bound is "-Infinity":
    205                  soln.gap="Infinity"
    206               elif not results.problem.lower_bound is None:
    207                  if "upper_bound" not in dir(results.problem):
    208                     gap="Infinity"
    209                  elif results.problem.upper_bound is None:
    210                     gap="Infinity"
    211                  else:
    212                     soln.gap=eval(soln.objective['f']) - eval(results.problem.lower_bound)
    213            elif "upper_bound" in dir(results.problem):
    214               if results.problem.upper_bound is "Infinity":
    215                  soln.gap="Infinity"
    216               elif not results.problem.upper_bound is None:
    217                  soln.gap=eval(results.problem.upper_bound) - eval(soln.objective['f'])
     233            soln.gap = "Infinity"  # until proven otherwise
     234            if "lower_bound" in dir(results.problem):
     235                if results.problem.lower_bound is "-Infinity":
     236                    soln.gap = "Infinity"
     237                elif not results.problem.lower_bound is None:
     238                    if "upper_bound" not in dir(results.problem):
     239                        gap = "Infinity"
     240                    elif results.problem.upper_bound is None:
     241                        gap = "Infinity"
     242                    else:
     243                        soln.gap = eval(soln.objective['f']) - \
     244                                   eval(results.problem.lower_bound)
     245            elif "upper_bound" in dir(results.problem):
     246                if results.problem.upper_bound is "Infinity":
     247                    soln.gap = "Infinity"
     248                elif not results.problem.upper_bound is None:
     249                    soln.gap = eval(results.problem.upper_bound) - \
     250                               eval(soln.objective['f'])
    218251        if results.solver.status is SolverStatus.error:
    219            results.solution.delete(0)
     252            results.solution.delete(0)
    220253        return results
    221254
    222     def process_soln_file(self,results):
     255    def process_soln_file(self, results):
    223256
    224257        # the only suffixes that we extract from GLPK are
    225258        # constraint duals. scan through the solver suffix
    226         # list and throw an exception if the user has 
     259        # list and throw an exception if the user has
    227260        # specified any others.
    228261        extract_duals = False
    229262        for suffix in self.suffixes:
    230             flag=False
    231             if re.match(suffix,"dual"):
     263            flag = False
     264            if re.match(suffix, "dual"):
    232265                extract_duals = True
    233                 flag=True
     266                flag = True
    234267            if not flag:
    235                 raise RuntimeError,"***GLPK solver plugin cannot extract solution suffix="+suffix
    236 
    237         lp_solution = True # if false, we're dealing with a MIP!
     268                raise RuntimeError, \
     269                      ("***GLPK solver plugin cannot extract solution " + \
     270                       "suffix='%s'") % (suffix)
     271
     272        lp_solution = True  # if false, we're dealing with a MIP!
    238273        if not os.path.exists(self.soln_file):
    239            return
     274            return
    240275        soln = results.solution(0)
    241         INPUT = open(self.soln_file,"r")
    242        
    243         state = 0 # 0=initial header, 1=constraints, 2=variables, -1=done
    244        
    245         results.problem.number_of_objectives = 1
    246        
    247         number_of_constraints_read = 0 # for validation of the total count read and the order
    248         number_of_variables_read = 0
    249         active_constraint_name = "" # constraint names and their value/bounds can be split across multiple lines
    250         active_variable_name = "" # variable names and their value/bounds can be split across multiple lines
    251        
    252         for line in INPUT:
    253           tokens = re.split('[ \t]+',line.strip())
    254 
    255           if (len(tokens) == 1) and (len(tokens[0]) == 0):
    256              pass
    257           elif state == 0:
    258              #
    259              # Processing initial header
    260              #
    261              if len(tokens) == 2 and tokens[0] == "Problem:":
    262                 # the problem name may be absent, in which case the "Problem:" line will be skipped.
    263                 results.problem.name = tokens[1]
    264              elif len(tokens) == 2 and tokens[0] == "Rows:":
    265                 results.problem.number_of_constraints = eval(tokens[1])
    266              elif len(tokens) == 2 and tokens[0] == "Columns:":
    267                 lp_solution = True
    268                 results.problem.number_of_variables = eval(tokens[1])
    269              elif len(tokens) > 2 and tokens[0] == "Columns:":
    270                 lp_solution = False
    271                 results.problem.number_of_variables = eval(tokens[1])               
    272              elif len(tokens) == 2 and tokens[0] == "Non-zeros:":
    273                 results.problem.number_of_nonzeros = eval(tokens[1])
    274              elif len(tokens) >= 2 and tokens[0] == "Status:":
    275                 if tokens[1] == "OPTIMAL":
    276                    soln.status = SolutionStatus.optimal
    277                 elif len(tokens) == 3 and tokens[1] == "INTEGER" and tokens[2] == "NON-OPTIMAL":
    278                    soln.status = SolutionStatus.bestSoFar
    279                 elif len(tokens) == 3 and tokens[1] == "INTEGER" and tokens[2] == "OPTIMAL":
    280                    soln.status = SolutionStatus.optimal
    281                 elif len(tokens) == 3 and tokens[1] == "INTEGER" and tokens[2] == "UNDEFINED":
    282                    soln.status = SolutionStatus.stoppedByLimit
    283                 elif (len(tokens) == 2) and (tokens[1] == "UNDEFINED"):
    284                    soln.status = SolutionStatus.infeasible
    285                 else:
    286                    print "WARNING: Read unknown status while parsing GLPK solution file - status="+" ".join(tokens[1:])
    287              elif len(tokens) >= 2 and tokens[0] == "Objective:":
    288                 if tokens[4] == "(MINimum)":
    289                    results.problem.sense = ProblemSense.minimize
    290                 else:
    291                    results.problem.sense = ProblemSense.maximize
    292                 soln.objective['f']=tokens[3]
    293                 if soln.status is SolutionStatus.optimal:
    294                    if tokens[4] == "(MINimum)":
    295                         results.problem.lower_bound = soln.objective['f'].value
    296                         if "upper_bound" in dir(results.problem):
    297                             del results.problem.upper_bound
    298                    else:
    299                         results.problem.upper_bound = soln.objective['f'].value
    300                         if "lower_bound" in dir(results.problem):
    301                             del results.problem.lower_bound
    302                 # the objective is the last entry in the problem section - move on to constraints.
    303                 state = 1
    304 
    305           elif state == 1:
    306              #
    307              # Process Constraint Info
    308              #
    309              
    310              if (len(tokens) == 2) and (len(active_constraint_name) == 0):
    311 
    312                 number_of_constraints_read = number_of_constraints_read + 1
    313                 active_constraint_name = tokens[1].strip()
    314                 index = eval(tokens[0].strip())
    315 
    316                 # sanity check - the indices should be in sequence.
    317                 if index != number_of_constraints_read:
    318                    raise ValueError,"***ERROR: Unexpected constraint index encountered on line="+line+"; expected value="+str(number_of_constraints_read)+"; actual value="+str(index)
    319 
    320              else:
    321 
    322                 index = None
    323                 activity = None
    324                 lower_bound = None
    325                 upper_bound = None
    326                 marginal = None
    327 
    328                 # extract the field names and process accordingly. there
    329                 # is some wasted processing w.r.t. single versus double-line
    330                 # entries, but it's not significant enough to worry about.               
    331                  
    332                 index_string = line[0:6].strip()
    333                 name_string = line[7:19].strip()
    334                 activity_string = line[23:36].strip()
    335                 lower_bound_string = line[37:50].strip()
    336                 upper_bound_string = line[51:64].strip()
    337 
    338                 state_string = None               
    339                 marginal_string = None
    340 
    341                 # skip any headers
    342                 if (index_string == "------") or (index_string == "No."):
    343                    continue
    344 
    345                 if len(index_string) > 0:
    346                    index = eval(index_string)               
    347 
    348                 if lp_solution is True:
    349                    state_string = line[20:22].strip()
    350                    marginal_string = line[65:78].strip()
    351                    if (activity_string != "< eps") and (len(activity_string) > 0):
    352                       activity = eval(activity_string)
    353                    else:
    354                       activity = 0.0
    355                    if (lower_bound_string != "< eps") and (len(lower_bound_string) > 0):
    356                       lower_bound = eval(lower_bound_string)
    357                    else:
    358                       lower_bound = 0.0
    359                    if state_string != "NS":
    360                       if (upper_bound_string != "< eps") and (len(upper_bound_string) > 0):
    361                          upper_bound = eval(upper_bound_string)
    362                       else:
    363                          upper_bound = 0.0
    364                    if (marginal_string != "< eps") and (len(marginal_string) > 0):
    365                       marginal = eval(marginal_string)
    366                    else:
    367                       marginal = 0.0
    368 
    369                 else:
    370                     # no constraint-related attributes/values are extracted currently for MIPs.
     276        INPUT = open(self.soln_file, "r")
     277
     278        try:
     279
     280            state = 0  # 0=initial header, 1=constraints, 2=variables, -1=done
     281
     282            results.problem.number_of_objectives = 1
     283
     284            # for validation of the total count read and the order
     285            number_of_constraints_read = 0
     286            number_of_variables_read = 0
     287
     288            # constraint names and their value/bounds can be split
     289            # across multiple lines
     290            active_constraint_name = ""
     291
     292            # variable names and their value/bounds can be split across
     293            # multiple lines
     294            active_variable_name = ""
     295
     296            for line in INPUT:
     297                tokens = re.split('[ \t]+', line.strip())
     298
     299                if (len(tokens) == 1) and (len(tokens[0]) == 0):
    371300                    pass
    372                
    373                 constraint_name = None
    374                 if len(active_constraint_name) > 0:
    375                    # if there is an active constraint name, the identifier was
    376                    # too long for everything to be on a single line; the second
    377                    # line contains all of the value information.                   
    378                    constraint_name = active_constraint_name
    379                    active_constraint_name = ""
    380                 else:
    381                    # everything is on a single line.
    382                    constraint_name = name_string
    383                    number_of_constraints_read = number_of_constraints_read + 1
    384                    # sanity check - the indices should be in sequence.
    385                    if index != number_of_constraints_read:
    386                       raise ValueError,"***ERROR: Unexpected constraint index encountered on line="+line+"; expected value="+str(number_of_constraints_read)+"; actual value="+str(index)
    387    
    388                 if lp_solution is True:
    389                    # GLPK doesn't report slacks directly.
    390                    constraint_dual = activity
    391                    if state_string == "B":
    392                       constraint_dual = 0.0
    393                    elif (state_string == "NS") or (state_string == "NL") or (state_string == "NU"):
    394                       constraint_dual = marginal
    395                    else:
    396                       raise ValueError, "Unknown status="+tokens[0]+" encountered for constraint="+active_constraint_name+" in line="+line+" of solution file="+self.soln_file
    397 
    398                    if extract_duals is True:
    399                       soln.constraint[constraint_name].dual = constraint_dual
    400                  
    401                 else:
    402                    # there isn't anything interesting to do with constraints in the MIP case.
    403                    pass
    404 
    405                 # if all of the constraints have been read, exit.
    406                 if number_of_constraints_read == results.problem.number_of_constraints:
    407                    state = 2
    408                      
    409           elif state == 2:
    410              #
    411              # Process Variable Info
    412              #
    413 
    414              if (len(tokens) == 2) and (len(active_variable_name) == 0):
    415                  
    416                 # in the case of name over-flow, there are only two tokens
    417                 # on the first of two lines for the variable entry.
    418                 number_of_variables_read = number_of_variables_read + 1
    419                 active_variable_name = tokens[1].strip()
    420                 index = eval(tokens[0].strip())
    421 
    422                 # sanity check - the indices should be in sequence.
    423                 if index != number_of_variables_read:
    424                    raise ValueError,"***ERROR: Unexpected variable index encountered on line="+line+"; expected value="+str(number_of_variables_read)+"; actual value="+str(index)                   
    425                
    426              else:
    427                  
    428                 index = None
    429                 activity = None
    430                 lower_bound = None
    431                 upper_bound = None
    432                 marginal = None
    433 
    434                 # extract the field names and process accordingly. there
    435                 # is some wasted processing w.r.t. single versus double-line
    436                 # entries, but it's not significant enough to worry about.
    437 
    438                 index_string = line[0:6].strip()
    439                 name_string = line[7:19].strip()
    440                 activity_string = line[23:36].strip()
    441                 lower_bound_string = line[37:50].strip()
    442                 upper_bound_string = line[51:64].strip()
    443 
    444                 state_string = None
    445                 marginal_string = None
    446 
    447                 # skip any headers
    448                 if (index_string == "------") or (index_string == "No."):
    449                    continue
    450 
    451                 if len(index_string) > 0:
    452                    index = eval(index_string)
    453 
    454                 if lp_solution is True:
    455                    state_string = line[20:22].strip()
    456                    marginal_string = line[65:78].strip()
    457 
    458                    if (activity_string != "< eps") and (len(activity_string) > 0):
    459                       activity = eval(activity_string)
    460                    else:
    461                       activity = 0.0
    462                    if (lower_bound_string != "< eps") and (len(lower_bound_string) > 0):
    463                       lower_bound = eval(lower_bound_string)
    464                    else:
    465                       lower_bound = 0.0
    466                    if state_string != "NS":                   
    467                       if (upper_bound_string != "< eps") and (len(upper_bound_string) > 0):
    468                          upper_bound = eval(upper_bound_string)
    469                       else:
    470                          upper_bound = 0.0
    471                    if (marginal_string != "< eps") and (len(marginal_string) > 0):
    472                       marginal = eval(marginal_string)
    473                    else:
    474                       marginal = 0.0
    475 
    476                 else:
    477 
    478                    if (activity_string != "< eps") and (len(activity_string) > 0):
    479                       activity = eval(activity_string)
    480                    else:
    481                       activity = 0.0                   
    482 
    483                 variable_name = None
    484                 if len(active_variable_name) > 0:
    485                    # if there is an active variable name, the identifier was
    486                    # too long for everything to be on a single line; the second
    487                    # line contains all of the value information.
    488                    variable_name = active_variable_name
    489                    active_variable_name = ""
    490                 else:
    491                    # everything is on a single line.
    492                    variable_name = name_string
    493                    number_of_variables_read = number_of_variables_read + 1
    494                    # sanity check - the indices should be in sequence.
    495                    if index != number_of_variables_read:
    496                       raise ValueError,"***ERROR: Unexpected variable index encountered on line="+line+"; expected value="+str(number_of_variables_read)+"; actual value="+str(index)
    497 
    498                 if lp_solution is True:
    499                    # the "activity" column always specifies the variable value.
    500                    # embedding the if-then-else to validate the basis status.
    501                    # we are currently ignoring all bound-related information.
    502                    variable_value = None
    503                    if state_string == "B":
    504                       variable_value = activity
    505                    elif (state_string == "NL") or (state_string == "NS") or (state_string == "NU"):
    506                       variable_value = activity
    507                    else:
    508                       raise ValueError, "Unknown status="+state_string+" encountered for variable="+active_variable_name+" in line="+line+" of solution file="+self.soln_file
    509                
    510                    soln.variable[variable_name].value = variable_value
    511                 else:
    512                    soln.variable[variable_name].value = activity
    513                
    514              # if all of the variables have been read, exit.
    515              if number_of_variables_read == results.problem.number_of_variables:
    516                 state = -1
    517              
    518           if state==-1:
    519              break
    520          
    521         INPUT.close()
     301                elif state == 0:
     302                    #
     303                    # Processing initial header
     304                    #
     305                    if len(tokens) == 2 and tokens[0] == "Problem:":
     306                        # the problem name may be absent, in which case
     307                        # the "Problem:" line will be skipped.
     308                        results.problem.name = tokens[1]
     309                    elif len(tokens) == 2 and tokens[0] == "Rows:":
     310                        results.problem.number_of_constraints = eval(tokens[1])
     311                    elif len(tokens) == 2 and tokens[0] == "Columns:":
     312                        lp_solution = True
     313                        results.problem.number_of_variables = eval(tokens[1])
     314                    elif len(tokens) > 2 and tokens[0] == "Columns:":
     315                        lp_solution = False
     316                        results.problem.number_of_variables = eval(tokens[1])
     317                    elif len(tokens) == 2 and tokens[0] == "Non-zeros:":
     318                        results.problem.number_of_nonzeros = eval(tokens[1])
     319                    elif len(tokens) >= 2 and tokens[0] == "Status:":
     320                        if tokens[1] == "OPTIMAL":
     321                            soln.status = SolutionStatus.optimal
     322                        elif len(tokens) == 3 and tokens[1] == "INTEGER" and \
     323                                 tokens[2] == "NON-OPTIMAL":
     324                            soln.status = SolutionStatus.bestSoFar
     325                        elif len(tokens) == 3 and tokens[1] == "INTEGER" and \
     326                                 tokens[2] == "OPTIMAL":
     327                            soln.status = SolutionStatus.optimal
     328                        elif len(tokens) == 3 and tokens[1] == "INTEGER" and \
     329                                 tokens[2] == "UNDEFINED":
     330                            soln.status = SolutionStatus.stoppedByLimit
     331                        elif (len(tokens) == 2) and (tokens[1] == "UNDEFINED"):
     332                            soln.status = SolutionStatus.infeasible
     333                        else:
     334                            print ("WARNING: Read unknown status while " + \
     335                                   "parsing GLPK solution file - " + \
     336                                   "status='%s'") % (" ".join(tokens[1:]))
     337                    elif len(tokens) >= 2 and tokens[0] == "Objective:":
     338                        if tokens[4] == "(MINimum)":
     339                            results.problem.sense = ProblemSense.minimize
     340                        else:
     341                            results.problem.sense = ProblemSense.maximize
     342                        soln.objective['f'] = tokens[3]
     343                        if soln.status is SolutionStatus.optimal:
     344                            if tokens[4] == "(MINimum)":
     345                                results.problem.lower_bound = soln.objective['f'].value
     346                                if "upper_bound" in dir(results.problem):
     347                                    del results.problem.upper_bound
     348                            else:
     349                                results.problem.upper_bound = soln.objective['f'].value
     350                                if "lower_bound" in dir(results.problem):
     351                                    del results.problem.lower_bound
     352                        # the objective is the last entry in the problem section - move on to constraints.
     353                        state = 1
     354
     355                elif state == 1:
     356                    #
     357                    # Process Constraint Info
     358                    #
     359
     360                    if (len(tokens) == 2) and (len(active_constraint_name) == 0):
     361                        number_of_constraints_read = number_of_constraints_read + 1
     362                        active_constraint_name = tokens[1].strip()
     363                        index = eval(tokens[0].strip())
     364
     365                        # sanity check - the indices should be in sequence.
     366                        if index != number_of_constraints_read:
     367                            raise ValueError, \
     368                                  ("***ERROR: Unexpected constraint index " + \
     369                                   "encountered on line=%s; expected " + \
     370                                   "value=%s; actual value=%s") % \
     371                                   (line, str(number_of_consrtaints_read),
     372                                    str(index))
     373                    else:
     374                        index = None
     375                        activity = None
     376                        lower_bound = None
     377                        upper_bound = None
     378                        marginal = None
     379
     380                        # extract the field names and process accordingly. there
     381                        # is some wasted processing w.r.t. single versus double-line
     382                        # entries, but it's not significant enough to worry about.
     383
     384                        index_string = line[0:6].strip()
     385                        name_string = line[7:19].strip()
     386                        activity_string = line[23:36].strip()
     387                        lower_bound_string = line[37:50].strip()
     388                        upper_bound_string = line[51:64].strip()
     389
     390                        state_string = None
     391                        marginal_string = None
     392
     393                        # skip any headers
     394                        if (index_string == "------") or (index_string == "No."):
     395                            continue
     396
     397                        if len(index_string) > 0:
     398                            index = eval(index_string)
     399
     400                        if lp_solution is True:
     401                            state_string = line[20:22].strip()
     402                            marginal_string = line[65:78].strip()
     403                            if (activity_string != "< eps") and (len(activity_string) > 0):
     404                                activity = eval(activity_string)
     405                            else:
     406                                activity = 0.0
     407                            if (lower_bound_string != "< eps") and (len(lower_bound_string) > 0):
     408                                lower_bound = eval(lower_bound_string)
     409                            else:
     410                                lower_bound = 0.0
     411                            if state_string != "NS":
     412                                if (upper_bound_string != "< eps") and (len(upper_bound_string) > 0):
     413                                    upper_bound = eval(upper_bound_string)
     414                                else:
     415                                    upper_bound = 0.0
     416                            if (marginal_string != "< eps") and (len(marginal_string) > 0):
     417                                marginal = eval(marginal_string)
     418                            else:
     419                                marginal = 0.0
     420
     421                        else:
     422                            # no constraint-related attributes/values are extracted currently for MIPs.
     423                            pass
     424
     425                        constraint_name = None
     426                        if len(active_constraint_name) > 0:
     427                            # if there is an active constraint name, the identifier was
     428                            # too long for everything to be on a single line; the second
     429                            # line contains all of the value information.
     430                            constraint_name = active_constraint_name
     431                            active_constraint_name = ""
     432                        else:
     433                            # everything is on a single line.
     434                            constraint_name = name_string
     435                            number_of_constraints_read = number_of_constraints_read + 1
     436                            # sanity check - the indices should be in sequence.
     437                            if index != number_of_constraints_read:
     438                                raise ValueError,"***ERROR: Unexpected constraint index encountered on line="+line+"; expected value="+str(number_of_constraints_read)+"; actual value="+str(index)
     439
     440                        if lp_solution is True:
     441                            # GLPK doesn't report slacks directly.
     442                            constraint_dual = activity
     443                            if state_string == "B":
     444                                constraint_dual = 0.0
     445                            elif (state_string == "NS") or (state_string == "NL") or (state_string == "NU"):
     446                                constraint_dual = marginal
     447                            else:
     448                                raise ValueError, "Unknown status="+tokens[0]+" encountered for constraint="+active_constraint_name+" in line="+line+" of solution file="+self.soln_file
     449
     450                            if extract_duals is True:
     451                                soln.constraint[constraint_name].dual = constraint_dual
     452
     453                        else:
     454                            # there isn't anything interesting to do with constraints in the MIP case.
     455                            pass
     456
     457                        # if all of the constraints have been read, exit.
     458                        if number_of_constraints_read == results.problem.number_of_constraints:
     459                            state = 2
     460
     461                elif state == 2:
     462                    #
     463                    # Process Variable Info
     464                    #
     465
     466                    if (len(tokens) == 2) and (len(active_variable_name) == 0):
     467
     468                        # in the case of name over-flow, there are only two tokens
     469                        # on the first of two lines for the variable entry.
     470                        number_of_variables_read = number_of_variables_read + 1
     471                        active_variable_name = tokens[1].strip()
     472                        index = eval(tokens[0].strip())
     473
     474                        # sanity check - the indices should be in sequence.
     475                        if index != number_of_variables_read:
     476                            raise ValueError,"***ERROR: Unexpected variable index encountered on line="+line+"; expected value="+str(number_of_variables_read)+"; actual value="+str(index)
     477
     478                    else:
     479
     480                        index = None
     481                        activity = None
     482                        lower_bound = None
     483                        upper_bound = None
     484                        marginal = None
     485
     486                        # extract the field names and process accordingly. there
     487                        # is some wasted processing w.r.t. single versus double-line
     488                        # entries, but it's not significant enough to worry about.
     489
     490                        index_string = line[0:6].strip()
     491                        name_string = line[7:19].strip()
     492                        activity_string = line[23:36].strip()
     493                        lower_bound_string = line[37:50].strip()
     494                        upper_bound_string = line[51:64].strip()
     495
     496                        state_string = None
     497                        marginal_string = None
     498
     499                        # skip any headers
     500                        if (index_string == "------") or (index_string == "No."):
     501                            continue
     502
     503                        if len(index_string) > 0:
     504                            index = eval(index_string)
     505
     506                        if lp_solution is True:
     507
     508                            state_string = line[20:22].strip()
     509                            marginal_string = line[65:78].strip()
     510
     511                            if (activity_string != "< eps") and (len(activity_string) > 0):
     512                                activity = eval(activity_string)
     513                            else:
     514                                activity = 0.0
     515                                if (lower_bound_string != "< eps") and (len(lower_bound_string) > 0):
     516                                    lower_bound = eval(lower_bound_string)
     517                                else:
     518                                    lower_bound = 0.0
     519                            if state_string != "NS":
     520                                if (upper_bound_string != "< eps") and (len(upper_bound_string) > 0):
     521                                    upper_bound = eval(upper_bound_string)
     522                                else:
     523                                    upper_bound = 0.0
     524                            if (marginal_string != "< eps") and (len(marginal_string) > 0):
     525                                marginal = eval(marginal_string)
     526                            else:
     527                                marginal = 0.0
     528                        else:
     529                            if (activity_string != "< eps") and (len(activity_string) > 0):
     530                                activity = eval(activity_string)
     531                            else:
     532                                activity = 0.0
     533
     534                        variable_name = None
     535                        if len(active_variable_name) > 0:
     536                            # if there is an active variable name, the identifier was
     537                            # too long for everything to be on a single line; the second
     538                            # line contains all of the value information.
     539                            variable_name = active_variable_name
     540                            active_variable_name = ""
     541                        else:
     542                            # everything is on a single line.
     543                            variable_name = name_string
     544                            number_of_variables_read = number_of_variables_read + 1
     545                            # sanity check - the indices should be in sequence.
     546                            if index != number_of_variables_read:
     547                                raise ValueError,"***ERROR: Unexpected variable index encountered on line="+line+"; expected value="+str(number_of_variables_read)+"; actual value="+str(index)
     548
     549                        if lp_solution is True:
     550                            # the "activity" column always specifies the variable value.
     551                            # embedding the if-then-else to validate the basis status.
     552                            # we are currently ignoring all bound-related information.
     553                            variable_value = None
     554                            if state_string in ('B', 'NL', 'NS', 'NU', 'NF'):
     555                                # NF = non-basic free (unbounded) variable
     556                                # NL = non-basic variable at its lower bound
     557                                # NU = non-basic variable at its upper bound
     558                                # NS = non-basic fixed variable
     559                                variable_value = activity
     560                            else:
     561                                raise ValueError, "Unknown status="+state_string+" encountered for variable="+variable_name+" in the following line of the GLPK solution file="+self.soln_file+":\n"+line
     562
     563                            soln.variable[variable_name].value = variable_value
     564                        else:
     565                            soln.variable[variable_name].value = activity
     566
     567                    # if all of the variables have been read, exit.
     568                    if number_of_variables_read == results.problem.number_of_variables:
     569                        state = -1
     570
     571                if state==-1:
     572                    break
     573
     574            INPUT.close()
     575
     576        except ValueError, msg:
     577            INPUT.close()
     578            raise RuntimeError, msg
     579        except Exception, msg:
     580            INPUT.close()
     581            raise RuntimeError, "Unexpected input encountered in GLPK solution file, yielding parse failure; line="+str(line)+"\nException: "+str(msg)
    522582
    523583class MockGLPK(GLPK,mockmip.MockMIP):
     
    525585    """
    526586
    527     pyutilib.component.core.alias('_mock_glpk')
     587    alias('_mock_glpk')
    528588
    529589    def __init__(self, **kwds):
    530590        try:
    531591           GLPK.__init__(self, **kwds)
    532         except pyutilib.common.ApplicationError: #pragma:nocover
     592        except ApplicationError: #pragma:nocover
    533593           pass                        #pragma:nocover
    534594        mockmip.MockMIP.__init__(self,"glpk")
     
    555615
    556616
    557 pyutilib.services.register_executable(name="glpsol")
     617register_executable( name='glpsol')
  • coopr.plugins/stable/2.4/coopr/plugins/mip/__init__.py

    r2604 r2936  
    1818from GUROBI import GUROBI
    1919from ASL import ASL, MockASL
     20from ossolver import OSSolver
    2021#from NLWRITE import NLWRITE
    2122
    22 #   
     23#
    2324# Interrogate the CBC executable to see if it recognizes the -AMPL flag
    24 #   
     25#
    2526import CBCplugin
    2627CBCplugin.configure()
  • coopr.plugins/stable/2.4/coopr/plugins/tests/mip/test4_cbc.txt

    r2731 r2936  
    77# ----------------------------------------------------------
    88Problem:
    9 - Name: None
    10   Lower bound: 88.578
     9- Lower bound: 88.578
    1110  Upper bound: .inf
    1211  Number of objectives: 1
  • coopr.plugins/stable/2.4/coopr/plugins/tests/mip/test_mip.py

    r2731 r2936  
    1111import pyutilib.autotest
    1212
     13pyutilib.autotest.create_test_suites(filename=currdir+'test_mip.yml', _globals=globals())
     14
    1315if __name__ == "__main__":
    14     pyutilib.autotest.create_test_suites(filename=currdir+'test_mip.yml', _globals=globals())
    1516    unittest.main()
    1617
Note: See TracChangeset for help on using the changeset viewer.