source: coopr.pysp/trunk/coopr/pysp/ef_writer_script.py @ 2452

Last change on this file since 2452 was 2452, checked in by jwatson, 11 years ago

Based on new extensive form solution reader, added solve options to efwriter script and pretty-prints of the resulting solution in scenario tree format.

  • Property svn:executable set to *
File size: 9.4 KB
Line 
1#  _________________________________________________________________________
2#
3#  Coopr: A COmmon Optimization Python Repository
4#  Copyright (c) 2009 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 sys
13import os
14from optparse import OptionParser
15
16import pyutilib.services
17import textwrap
18import traceback
19import cProfile
20import pstats
21import gc
22
23from coopr.pysp.ef import *
24
25from coopr.opt.base import SolverFactory
26from coopr.opt.parallel import SolverManagerFactory
27
28#
29# utility method to construct an option parser for ef writer arguments
30#
31
32def construct_ef_writer_options_parser(usage_string):
33
34   parser = OptionParser()
35   parser.add_option("--verbose",
36                     help="Generate verbose output, beyond the usual status output. Default is False.",
37                     action="store_true",
38                     dest="verbose",
39                     default=False)
40   parser.add_option("--model-directory",
41                     help="The directory in which all model (reference and scenario) definitions are stored. Default is \".\".",
42                     action="store",
43                     dest="model_directory",
44                     type="string",
45                     default=".")
46   parser.add_option("--instance-directory",
47                     help="The directory in which all instance (reference and scenario) definitions are stored. Default is \".\".",
48                     action="store",
49                     dest="instance_directory",
50                     type="string",
51                     default=".")
52   parser.add_option("--generate-weighted-cvar",
53                     help="Add a weighted CVaR term to the primary objective",
54                     action="store_true",
55                     dest="generate_weighted_cvar",
56                     default=False)
57   parser.add_option("--cvar-weight",
58                     help="The weight associated with the CVaR term in the risk-weighted objective formulation. Default is 1.0. If the weight is 0, then *only* a non-weighted CVaR cost will appear in the EF objective - the expected cost component will be dropped.",
59                     action="store",
60                     dest="cvar_weight",
61                     type="float",
62                     default=1.0)
63   parser.add_option("--risk-alpha",
64                     help="The probability threshold associated with cvar (or any future) risk-oriented performance metrics. Default is 0.95.",
65                     action="store",
66                     dest="risk_alpha",
67                     type="float",
68                     default=0.95)
69   parser.add_option("--output-file",
70                     help="Specify the name of the extensive form output file",
71                     action="store",
72                     dest="output_file",
73                     type="string",
74                     default="efout.lp")
75   parser.add_option("--solve",
76                     help="Following write of the extensive form model, solve it.",
77                     action="store_true",
78                     dest="solve_ef",
79                     default=False)
80   parser.add_option("--solver",
81                     help="The type of solver used to solve scenario sub-problems. Default is cplex.",
82                     action="store",
83                     dest="solver_type",
84                     type="string",
85                     default="cplex")
86   parser.add_option("--solver-manager",
87                     help="The type of solver manager used to coordinate scenario sub-problem solves. Default is serial.",
88                     action="store",
89                     dest="solver_manager_type",
90                     type="string",
91                     default="serial")
92   parser.add_option("--solver-options",
93                     help="Solver options for the extension form problem",
94                     action="append",
95                     dest="solver_options",
96                     type="string",
97                     default=[])
98   parser.add_option("--mipgap",
99                     help="Specifies the mipgap for the EF solve",
100                     action="store",
101                     dest="mipgap",
102                     type="float",
103                     default=None)   
104   parser.add_option("--output-solver-log",
105                     help="Output solver log during the extensive form solve",
106                     action="store_true",
107                     dest="output_solver_log",
108                     default=False)   
109   parser.add_option("--profile",
110                     help="Enable profiling of Python code.  The value of this option is the number of functions that are summarized.",
111                     action="store",
112                     dest="profile",
113                     default=0)
114   parser.add_option("--disable-gc",
115                     help="Disable the python garbage collecter. Default is False.",
116                     action="store_true",
117                     dest="disable_gc",
118                     default=False)
119   parser.usage=usage_string
120
121   return parser
122   
123def run_ef_writer(options, args):
124
125   # if the user enabled the addition of the weighted cvar term to the objective,
126   # then validate the associated parameters.
127   generate_weighted_cvar = False
128   cvar_weight = None
129   risk_alpha = None
130
131   if options.generate_weighted_cvar is True:
132
133      generate_weighted_cvar = True
134      cvar_weight = options.cvar_weight
135      risk_alpha = options.risk_alpha
136
137   scenario_tree, binding_instance, scenario_instances = write_ef_from_scratch(os.path.expanduser(options.model_directory),
138                                                                               os.path.expanduser(options.instance_directory),
139                                                                               os.path.expanduser(options.output_file),
140                                                                               options.verbose,
141                                                                               generate_weighted_cvar, cvar_weight, risk_alpha)
142
143   if options.solve_ef is True:
144
145      ef_solver = SolverFactory(options.solver_type)
146      if ef_solver is None:
147         raise ValueError, "Failed to create solver of type="+options.solver_type+" for use in extensive form solve"
148      if len(options.solver_options) > 0:
149         print "Initializing ef solver with options="+str(options.solver_options)         
150         ef_solver.set_options("".join(options.solver_options))
151      if options.mipgap is not None:
152         if (options.mipgap < 0.0) or (options.mipgap > 1.0):
153            raise ValueError, "Value of the mipgap parameter for the EF solve must be on the unit interval; value specified=" + `options.mipgap`
154         else:
155            ef_solver.mipgap = options.mipgap
156
157      ef_solver_manager = SolverManagerFactory(options.solver_manager_type)
158      if ef_solver is None:
159         raise ValueError, "Failed to create solver manager of type="+options.solver_type+" for use in extensive form solve"
160
161      print "Queuing extensive form solve"
162      ef_action_handle = ef_solver_manager.queue(os.path.expanduser(options.output_file), opt=ef_solver, warmstart=False, tee=options.output_solver_log)
163      print "Waiting for extensive form solve"
164      ef_results = ef_solver_manager.wait_for(ef_action_handle)
165      load_ef_solution(ef_results, binding_instance, scenario_instances)
166      scenario_tree.snapshotSolutionFromInstances(scenario_instances)
167      print ""
168      print "Extensive form solution:"
169      scenario_tree.pprintSolution()
170      print ""
171      print "Extensive form costs:"
172      scenario_tree.pprintCosts(scenario_instances)
173
174def run(args=None):
175
176    #
177    # Top-level command that executes the extensive form writer.
178    # This is segregated from run_ef_writer to enable profiling.
179    #
180
181    #
182    # Parse command-line options.
183    #
184    try:
185       options_parser = construct_ef_writer_options_parser("efwriter [options]")
186       (options, args) = options_parser.parse_args(args=args)
187    except SystemExit:
188       # the parser throws a system exit if "-h" is specified - catch
189       # it to exit gracefully.
190       return
191
192    if options.disable_gc is True:
193       gc.disable()
194    else:
195       gc.enable()
196
197    if options.profile > 0:
198        #
199        # Call the main ef writer with profiling.
200        #
201        tfile = pyutilib.services.TempfileManager.create_tempfile(suffix=".profile")
202        tmp = cProfile.runctx('run_ef_writer(options,args)',globals(),locals(),tfile)
203        p = pstats.Stats(tfile).strip_dirs()
204        p.sort_stats('time', 'cum')
205        options.profile = eval(options.profile)
206        p = p.print_stats(options.profile)
207        p.print_callers(options.profile)
208        p.print_callees(options.profile)
209        p = p.sort_stats('cum','calls')
210        p.print_stats(options.profile)
211        p.print_callers(options.profile)
212        p.print_callees(options.profile)
213        p = p.sort_stats('calls')
214        p.print_stats(options.profile)
215        p.print_callers(options.profile)
216        p.print_callees(options.profile)
217        pyutilib.services.TempfileManager.clear_tempfiles()
218        ans = [tmp, None]
219    else:
220        #
221        # Call the main EF writer without profiling.
222        #
223        ans = run_ef_writer(options, args)
224
225    gc.enable()
226   
227    return ans
228
Note: See TracBrowser for help on using the repository browser.