source: coopr.plugins/trunk/coopr/plugins/mip/NLOPT.py @ 2201

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

Update to Coopr to account for changes in PyUtilib? package names.

File size: 9.2 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
12import re
13from coopr.opt.base import *
14from coopr.opt.results import *
15from coopr.opt.solver import *
16import pyutilib.services
17import pyutilib.common
18import pyutilib.common
19import pyutilib.component.core
20import mockmip
21import os
22import copy
23
24
25class NLOPT(SystemCallSolver):
26    """A generic NL optimizer
27    """
28
29    def __init__(self, **kwds):
30        #
31        # Call base constructor
32        #
33        kwds["type"] = "nlopt"
34        SystemCallSolver.__init__(self, **kwds)
35        #
36        # Setup valid problem formats, and valid results for each problem format
37        #
38        self._valid_problem_formats=[ProblemFormat.nl]
39        self._valid_result_formats = {}
40        self._valid_result_formats[ProblemFormat.nl] = [ResultsFormat.sol]
41
42    def executable(self):
43        executable = pyutilib.services.registered_executable(options.solver)
44        if executable is None:
45            pyutilib.component.core.PluginGlobals.env().log.error("Could not locate the '%s' executable, which is required for solver %s" % (self.name, options.solver))
46            self.enable = False
47            return None
48        return executable.get_path()
49
50    def create_command_line(self,executable,problem_files):
51        #
52        # Define log file
53        #
54        if self.log_file is None:
55           self.log_file = pyutilib.services.TempfileManager.create_tempfile(suffix="nlopt.log")
56        fname = problem_files[0].split(os.sep)[-1]
57        if '.' in fname:
58            tmp = fname.split('.')
59            if len(tmp) > 2:
60                fname = '.'.join(tmp[:-1])
61            else:
62                fname = tmp[0]
63        self.sol_file = fname+".sol"
64        #
65        # Define results file
66        #
67        if self._results_format is None or self._results_format == ResultsFormat.sol:
68           self.results_file = self.sol_file
69        #
70        # Define command line
71        #
72        env=copy.copy(os.environ)
73        if self._problem_format is None or self._problem_format == ProblemFormat.nl:
74            if "debug" in self.options:
75                opts = []
76            else:
77                opts = ["debug=2"]
78            for key in self.options:
79                if key is 'solver':
80                    continue
81                if isinstance(self.options[key],basestring) and ' ' in self.options[key]:
82                    opts.append(key+"=\""+str(self.options[key])+"\"")
83                else:
84                    opt.append(key+"="+str(self.options[key]))
85           
86            envstr = "%s_options" % executable
87            env[envstr] = " ".join(opts)
88            proc = self._timer + " " + executable + " " + problem_files[0] + " -AMPL"
89        return pyutilib.misc.Bunch(cmd=proc, log_file=self.log_file, env=env)
90
91    def process_logfile(self):
92        """
93        Process a logfile
94        """
95        results = SolverResults()
96        #
97        # Initial values
98        #
99        soln = results.solution.add()
100        soln.objective['f'].value = None
101        #
102        # Process logfile
103        #
104        OUTPUT = open(self.log_file)
105        output = "".join(OUTPUT.readlines())
106        OUTPUT.close()
107        #
108        # Parse logfile lines
109        #
110        for line in output.split("\n"):
111          tokens = re.split('[ \t]+',line.strip())
112          if len(tokens) > 3 and tokens[0] == "ABORTED:":
113             results.solver.status=SolverStatus.aborted
114          elif len(tokens) == 5 and tokens[0] == "Final" and tokens[1] == "Solution:":
115             soln.objective['f'].value = tokens[4]
116             soln.status = SolutionStatus.optimal
117          elif len(tokens) == 3 and tokens[0] == "LP" and tokens[1] == "value=":
118             soln.objective['f'].value = tokens[2]
119             soln.status=SolutionStatus.optimal
120             if results.problem.sense == ProblemSense.minimize:
121                results.problem.lower_bound = tokens[2]
122             else:
123                results.problem.upper_bound = tokens[2]
124          elif len(tokens) == 2 and tokens[0] == "Bound:":
125             if results.problem.sense == ProblemSense.minimize:
126                results.problem.lower_bound = tokens[1]
127             else:
128                results.problem.upper_bound = tokens[1]
129          elif len(tokens) == 3 and tokens[0] == "Created":
130             results.solver.statistics.branch_and_bound.number_of_created_subproblems = tokens[1]
131          elif len(tokens) == 3 and tokens[0] == "Bounded":
132             results.solver.statistics.branch_and_bound.number_of_bounded_subproblems = tokens[1]
133          elif len(tokens) == 2 and tokens[0] == "sys":
134             results.solver.system_time=tokens[1]
135          elif len(tokens) == 2 and tokens[0] == "user":
136             results.solver.user_time=tokens[1]
137          elif len(tokens) == 3 and tokens[0] == "Solving" and tokens[1] == "problem:":
138             results.problem.name = tokens[2]
139          elif len(tokens) == 4 and tokens[2] == "constraints:":
140             results.problem.number_of_constraints = tokens[3]
141          elif len(tokens) == 4 and tokens[2] == "variables:":
142             results.problem.number_of_variables = tokens[3]
143          elif len(tokens) == 4 and tokens[2] == "nonzeros:":
144             results.problem.number_of_nonzeros = tokens[3]
145          elif len(tokens) == 3 and tokens[1] == "Sense:":
146             if tokens[2] == "minimization":
147                results.problem.sense = ProblemSense.minimize
148             else:
149                results.problem.sense = ProblemSense.maximize
150
151        if results.solver.status is SolverStatus.aborted:
152           soln.optimality=SolutionStatus.unsure
153        if soln.status is SolutionStatus.optimal:
154           soln.gap=0.0
155           if results.problem.sense == ProblemSense.minimize:
156                results.problem.lower_bound = soln.objective['f'].value
157                if "upper_bound" in dir(results.problem):
158                    del results.problem.upper_bound
159           else:
160                results.problem.upper_bound = soln.objective['f'].value
161                if "lower_bound" in dir(results.problem):
162                    del results.problem.lower_bound
163        if results.solver.status is SolverStatus.error:
164           results.solution.delete(0)
165        return results
166
167    def process_soln_file(self,results):
168        #print "HERE",self._results_format, self._results_format is ResultsFormat.sol, self.results_reader
169        if self._results_format is ResultsFormat.sol:
170           return
171
172        #if os.path.exists(self.sol_file):
173            #results_reader = ReaderFactory(ResultsFormat.sol)
174            #results = results_reader(self.sol_file, results, results.solution(0))
175            #return
176
177        if not os.path.exists(self.soln_file):
178           return
179        soln = results.solution(0)
180        results.problem.num_objectives=1
181        tmp=[]
182        flag=False
183        INPUT = open(self.soln_file,"r")
184        lp_flag=None
185        for line in INPUT:
186            tokens = re.split('[ \t]+',line.strip())
187            if len(tokens) == 0 or (len(tokens) == 1 and tokens[0]==''):
188                continue
189            if tokens[0] == "Objective":
190                continue
191            #print "LINE",tokens
192            if lp_flag is None:
193                lp_flag = (tokens[0] == "LP")
194                continue
195            if tokens[0] == "Dual" and tokens[1] == "solution:":
196                # It looks like we've just been processing primal
197                # variables.
198                for (var,val) in tmp:
199                    soln.variable[var] = val
200                tmp=[]
201                continue
202            if len(tokens) < 3:
203                print "ERROR", line,tokens
204            tmp.append( (tokens[0],eval(tokens[2])) )
205        if lp_flag:
206            for (var,val) in tmp:
207                soln.constraint[var].dual = val
208        else:
209            for (var,val) in tmp:
210                soln.variable[var] = val
211        INPUT.close()
212
213
214class MockPICO(PICO,mockmip.MockMIP):
215    """A Mock PICO solver used for testing
216    """
217
218    def __init__(self, **kwds):
219        try:
220           PICO.__init__(self,**kwds)
221        except pyutilib.common.ApplicationError: #pragma:nocover
222           pass                        #pragma:nocover
223        mockmip.MockMIP.__init__(self,"pico")
224
225    def available(self, exception_flag=True):
226        return PICO.available(self,exception_flag)
227
228    def create_command_line(self,executable,problem_files):
229        command = PICO.create_command_line(self,executable,problem_files)
230        mockmip.MockMIP.create_command_line(self,executable,problem_files)
231        return command
232
233    def executable(self):
234        return mockmip.MockMIP.executable(self)
235
236    def _execute_command(self,cmd):
237        return mockmip.MockMIP._execute_command(self,cmd)
238
239
240pyutilib.services.register_executable(name="pico")
241SolverRegistration("pico", PICO)
242SolverRegistration("_mock_pico", MockPICO)
Note: See TracBrowser for help on using the repository browser.