def solve_dm(p_model, p_data, opt_solver): #This function solves a deterministic model with the inputs for #uncertainty values represented by their average values at each stage #We assume the ReferenceModel.dat as the average problem properly represented #inside the stochastic folder def return_obj(instance): from pyomo.core import Objective obj = instance.component_objects(Objective, active=True) obj_values = list() for o in obj: # See section 18.6.3 in Pyomo online doc method_obj = getattr(instance, str(o)) obj_values.append(method_obj()) # Assuming there is only one objective function return obj_values[0] import sys, os from collections import deque, defaultdict from pyomo.core import Objective, Var #not sure if Var is right after the Objective (head, tail) = os.path.split(p_model) sys.path.insert(0, head) pwd = os.getcwd() os.chdir(p_data) model_module = __import__(tail[:-3], globals(), locals()) model = model_module.model dm_result = { 'cost': list(), 'flowin': list(), 'flowout': list(), 'capacity': list() } data = DataPortal(model=model) dat = "AverageModel.dat" #Loading the model from the data file data.load(filename=dat) instance = model.create_instance( data) #Defining the model instance with the data from .dat file optimizer = SolverFactory(opt_solver) #Defining the optimization solver results = optimizer.solve(instance) #Solving the optimization model instance.solutions.load_from(results) #Saving solutions in memory #Getting objective function values obj_val = return_obj(instance) dm_result['cost'].append(obj_val) #Writting to the Shell sys.stdout.write( '\nSolved deterministic model with uncertainty at average valures \n') sys.stdout.write(' Total cost: {}\n'.format(obj_val)) os.chdir(pwd) return instance #Returning instance solved, values will be used later
def construct_scenario_instance(self, scenario_name, scenario_tree, profile_memory=False, output_instance_construction_time=False, compile_instance=False): if not scenario_tree.contains_scenario(scenario_name): raise ValueError("ScenarioTree does not contain scenario " "with name %s." % (scenario_name)) scenario = scenario_tree.get_scenario(scenario_name) node_name_list = [n._name for n in scenario._node_list] if self._verbose: print("Creating instance for scenario=%s" % (scenario_name)) scenario_instance = None try: if self._model_callback is not None: assert self._model_object is None scenario_instance = self._model_callback(scenario_name, node_name_list) elif self._model_object is not None: if scenario_tree._scenario_based_data: scenario_data_filename = \ os.path.join(self._scenario_tree_directory, str(scenario_name)) # JPW: The following is a hack to support # initialization of block instances, which # don't work with .dat files at the # moment. Actually, it's not that bad of a # hack - it just needs to be extended a bit, # and expanded into the node-based data read # logic (where yaml is completely ignored at # the moment. if os.path.exists(scenario_data_filename+'.dat'): scenario_data_filename = \ scenario_data_filename + ".dat" data = None elif os.path.exists(scenario_data_filename+'.yaml'): import yaml scenario_data_filename = \ scenario_data_filename + ".yaml" yaml_input_file=open(scenario_data_filename,"r") data = yaml.load(yaml_input_file) yaml_input_file.close() else: raise RuntimeError( "Cannot find the scenario data for " + scenario_data_filename) if self._verbose: print("Data for scenario=%s loads from file=%s" % (scenario_name, scenario_data_filename)) if data is None: scenario_instance = \ self._model_object.create_instance( filename=scenario_data_filename, preprocess=False, profile_memory=profile_memory, report_timing=output_instance_construction_time) else: scenario_instance = \ self._model_object.create_instance( data, preprocess=False, profile_memory=profile_memory, report_timing=output_instance_construction_time) else: data_files = [] for node_name in node_name_list: node_data_filename = \ os.path.join(self._scenario_tree_directory, str(node_name)+".dat") if not os.path.exists(node_data_filename): raise RuntimeError( "Node data file="+node_data_filename+ " does not exist or cannot be accessed") data_files.append(node_data_filename) scenario_data = DataPortal(model=self._model_object) for data_file in data_files: if self._verbose: print("Node data for scenario=%s partially " "loading from file=%s" % (scenario_name, data_file)) scenario_data.load(filename=data_file) scenario_instance = self._model_object.create_instance( scenario_data, preprocess=False, profile_memory=profile_memory, report_timing=output_instance_construction_time) else: raise RuntimeError("Unable to construct scenario instance. " "Neither a reference model or callback " "is defined.") # name each instance with the scenario name scenario_instance.name = scenario_name # apply each of the post-instance creation plugins. this # really shouldn't be associated (in terms of naming) with the # pyomo script - this should be rectified with a workflow # re-work. it is unclear how this interacts, or doesn't, with # the preprocessors. ep = ExtensionPoint(IPyomoScriptModifyInstance) for ep in ExtensionPoint(IPyomoScriptModifyInstance): logger.warning( "DEPRECATED: IPyomoScriptModifyInstance extension " "point callbacks will be ignored by PySP in the future") ep.apply(options=None, model=reference_model, instance=scenario_instance) if compile_instance: from pyomo.repn.beta.matrix import compile_block_linear_constraints compile_block_linear_constraints( scenario_instance, "_PySP_compiled_linear_constraints", verbose=self._verbose) except Exception as exc: msg = ("Failed to create model instance for scenario=%s" % (scenario_name)) print(msg) raise return scenario_instance
def solve_pf(p_model, p_data): """ solve_pf(p_model, p_data) -> dict() Solves the model in perfect sight mode. p_model -> string, the path to the model file. p_data -> string, the path to the directory of data for the stochastic mdoel, where ScenarioStructure.dat should resides. Returns a dictionary including the value of objective function for each scenario and its conditional probability. """ def return_obj(instance): from pyomo.core import Objective obj = instance.component_objects(Objective, active = True) obj_values = list() for o in obj: # See section 18.6.3 in Pyomo online doc # https://taizilongxu.gitbooks.io/stackoverflow-about-python/content/59/README.html method_obj = getattr(instance, str(o)) obj_values.append(method_obj()) # Assuming there is only one objective function return obj_values[0] # Out-of-date for Pyomo 4.1 # obj = instance.active_components(Objective) # objs = obj.items()[0] # obj_name, obj_value = objs[0], value(objs[1]()) # return obj_value import sys, os from collections import deque, defaultdict from pyomo.pysp.util.scenariomodels import scenario_tree_model from pyomo.core import Objective (head, tail) = os.path.split(p_model) sys.path.insert(0, head) pwd = os.getcwd() os.chdir(p_data) s2fp_dict = defaultdict(deque) # Scenario to 'file path' dictionary, .dat not included s2cd_dict = defaultdict(float) # Scenario to conditonal density mapping sStructure = scenario_tree_model.create_instance( filename='ScenarioStructure.dat' ) # The following code is borrowed from Kevin's temoa_lib.py ########################################################################### # Step 1: find the root node. PySP doesn't make this very easy ... # a child -> parent mapping, because every child has only one parent, but # not vice-versa ctpTree = dict() # Child to parent dict, one to one mapping to_process = deque() to_process.extend( sStructure.Children.keys() ) while to_process: node = to_process.pop() if node in sStructure.Children: # it's a parent! new_nodes = set( sStructure.Children[ node ] ) to_process.extend( new_nodes ) ctpTree.update({n : node for n in new_nodes }) # parents - children root_node = (set( ctpTree.values() ) - set( ctpTree.keys() )).pop() # ptcTree = defaultdict( list ) # Parent to child node, one to multiple mapping # for c, p in ctpTree.iteritems(): # ptcTree[ p ].append( c ) # ptcTree = dict( ptcTree ) # be slightly defensive; catch any additions # leaf_nodes = set(ctpTree.keys()) - set(ctpTree.values()) leaf_nodes = set(sStructure.ScenarioLeafNode.values()) # Try to hack Kevin's code scenario_nodes = dict() # Map from leafnode to 'node path' for node in leaf_nodes: # e.g.: {Rs0s0: [R, Rs0, Rs0s0]} s = deque() scenario_nodes[ node ] = s while node in ctpTree: s.append( node ) node = ctpTree[ node ] s.append( node ) s.reverse() ########################################################################### for s in sStructure.Scenarios: cp = 1.0 # Starting probability for n in scenario_nodes[sStructure.ScenarioLeafNode[s]]: cp = cp*sStructure.ConditionalProbability[n] if not sStructure.ScenarioBasedData.value: s2fp_dict[s].append(n + '.dat') s2cd_dict[s] = cp from pyomo.core import Objective if sStructure.ScenarioBasedData.value: for s in sStructure.Scenarios: s2fp_dict[s].append(s + '.dat') model_module = __import__(tail[:-3], globals(), locals()) model = model_module.model pf_result = {'cost': list(), 'cd': list()} for s in sStructure.Scenarios: pf_result['cd'].append(s2cd_dict[s]) data = DataPortal(model=model) for dat in s2fp_dict[s]: data.load(filename=dat) instance = model.create_instance(data) optimizer = SolverFactory('cplex') results = optimizer.solve(instance) instance.solutions.load_from(results) # instance.load(results) obj_val = return_obj(instance) pf_result['cost'].append(obj_val) sys.stdout.write('\nSolved .dat(s) {}\n'.format(s2fp_dict[s])) sys.stdout.write(' Total cost: {}\n'.format(obj_val)) # instance.load does not work for Pyomo 4.1 # if instance.load(results): # obj_val = return_obj(instance) # pf_result['cost'].append(obj_val) # sys.stdout.write('\nSolved .dat(s) {}\n'.format(s2fp_dict[s])) # sys.stdout.write(' Total cost: {}\n'.format(obj_val)) # else: # pf_result['cost'].append(None) # sys.stdout.write('\nSolved .dat(s) {}\n'.format(s2fp_dict[s])) # sys.stdout.write(' This scenario has no feasible solution.\n') os.chdir(pwd) return pf_result
from pyomo.core import DataPortal from pyomo.opt import SolverFactory from DiseaseEstimation import model model.pprint() # @modeldata: modeldata = DataPortal(model=model) modeldata.load(filename='DiseaseEstimation.dat') modeldata.load(filename='DiseasePop.dat') # @:modeldata instance = model.create(modeldata) instance.pprint() opt = SolverFactory("ipopt") results = opt.solve(instance) results.write()
from pyomo.core import DataPortal from pyomo.opt import SolverFactory from DiseaseEstimation import model # create the instance from multiple data files data = DataPortal(model=model) data.load(filename='DiseaseEstimation.dat') data.load(filename='DiseasePop.dat') instance = model.create_instance(data) # create the solver and solve with SolverFactory("ipopt") as solver: solver.solve(instance, tee=True) # report results instance.pprint()
def construct_scenario_instance(self, scenario_name, scenario_tree, profile_memory=False, output_instance_construction_time=False, compile_instance=False, verbose=False): assert not self._closed if not scenario_tree.contains_scenario(scenario_name): raise ValueError("ScenarioTree does not contain scenario " "with name %s." % (scenario_name)) scenario = scenario_tree.get_scenario(scenario_name) node_name_list = [n._name for n in scenario._node_list] if verbose: print("Creating instance for scenario=%s" % (scenario_name)) scenario_instance = None try: if self._model_callback is not None: assert self._model_object is None try: _scenario_tree_arg = None # new callback signature if (self._scenario_tree_filename is not None) and \ self._scenario_tree_filename.endswith('.dat'): # we started with a .dat file, so # send the PySP scenario tree _scenario_tree_arg = scenario_tree elif self._scenario_tree_model is not None: # We started from a Pyomo # scenario tree model instance, or a # networkx tree. _scenario_tree_arg = self._scenario_tree_model else: # send the PySP scenario tree _scenario_tree_arg = scenario_tree scenario_instance = self._model_callback( _scenario_tree_arg, scenario_name, node_name_list) except TypeError: # old callback signature # TODO: #logger.warning( # "DEPRECATED: The 'pysp_instance_creation_callback' function " # "signature has changed. An additional argument should be " # "added to the beginning of the arguments list that will be " # "set to the user provided scenario tree object when called " # "by PySP (e.g., a Pyomo scenario tree model instance, " # "a networkx tree, or a PySP ScenarioTree object.") scenario_instance = self._model_callback( scenario_name, node_name_list) elif self._model_object is not None: if (not isinstance(self._model_object, AbstractModel)) or \ (self._model_object.is_constructed()): scenario_instance = self._model_object.clone() elif scenario_tree._scenario_based_data: assert self.data_directory() is not None scenario_data_filename = \ os.path.join(self.data_directory(), str(scenario_name)) # JPW: The following is a hack to support # initialization of block instances, which # don't work with .dat files at the # moment. Actually, it's not that bad of a # hack - it just needs to be extended a bit, # and expanded into the node-based data read # logic (where yaml is completely ignored at # the moment. if os.path.exists(scenario_data_filename + '.dat'): scenario_data_filename = \ scenario_data_filename + ".dat" data = None elif os.path.exists(scenario_data_filename + '.yaml'): if not has_yaml: raise ValueError( "Found yaml data file for scenario '%s' " "but he PyYAML module is not available" % (scenario_name)) scenario_data_filename = \ scenario_data_filename+".yaml" with open(scenario_data_filename) as f: data = yaml.load(f) else: raise RuntimeError( "Cannot find a data file for scenario '%s' " "in directory: %s\nRecognized formats: .dat, " ".yaml" % (scenario_name, self.data_directory())) if verbose: print("Data for scenario=%s loads from file=%s" % (scenario_name, scenario_data_filename)) if data is None: scenario_instance = \ self._model_object.create_instance( filename=scenario_data_filename, profile_memory=profile_memory, report_timing=output_instance_construction_time) else: scenario_instance = \ self._model_object.create_instance( data, profile_memory=profile_memory, report_timing=output_instance_construction_time) else: assert self.data_directory() is not None data_files = [] for node_name in node_name_list: node_data_filename = \ os.path.join(self.data_directory(), str(node_name)+".dat") if not os.path.exists(node_data_filename): raise RuntimeError( "Cannot find a data file for scenario tree " "node '%s' in directory: %s\nRecognized " "formats: .dat" % (node_name, self.data_directory())) data_files.append(node_data_filename) scenario_data = DataPortal(model=self._model_object) for data_file in data_files: if verbose: print("Node data for scenario=%s partially " "loading from file=%s" % (scenario_name, data_file)) scenario_data.load(filename=data_file) scenario_instance = self._model_object.create_instance( scenario_data, profile_memory=profile_memory, report_timing=output_instance_construction_time) else: raise RuntimeError("Unable to construct scenario instance. " "Neither a reference model or callback " "is defined.") # name each instance with the scenario name scenario_instance._name = scenario_name # apply each of the post-instance creation plugins. this # really shouldn't be associated (in terms of naming) with the # pyomo script - this should be rectified with a workflow # re-work. it is unclear how this interacts, or doesn't, with # the preprocessors. ep = ExtensionPoint(IPyomoScriptModifyInstance) for ep in ExtensionPoint(IPyomoScriptModifyInstance): logger.warning( "DEPRECATED: IPyomoScriptModifyInstance extension " "point callbacks will be ignored by PySP in the future") ep.apply(options=None, model=reference_model, instance=scenario_instance) if compile_instance: from pyomo.repn.beta.matrix import \ compile_block_linear_constraints compile_block_linear_constraints( scenario_instance, "_PySP_compiled_linear_constraints", verbose=verbose) except: logger.error("Failed to create model instance for scenario=%s" % (scenario_name)) raise return scenario_instance