def _apply_to(self, model, **kwds): self._preprocess('pao.bilevel.highpoint', model) for key, sub in self.submodel.items(): model.reclassify_component_type(sub, Block) setattr(model, 'hpr', create_submodel_hp_block(model)) model._transformation_data['pao.bilevel.highpoint'].submodel_cuid = \ ComponentUID(model) model._transformation_data['pao.bilevel.highpoint'].block_cuid = \ ComponentUID(getattr(model, 'hpr'))
def EXTERNAL_collect_solution(worker, node_name): solution = {} tmp = {} node = worker.scenario_tree.get_node(node_name) scenario = node.scenarios[0] stage = node.stage instance = scenario.instance assert instance is not None bySymbol = instance._ScenarioTreeSymbolMap.bySymbol for id_ in node._variable_ids: # TODO #cost_variable_name, cost_variable_index = \ # stage._cost_variable #stage_cost_obj = instance.find_component(cost_variable_name)\ # [cost_variable_index] #if not stage_cost_obj.is_expression(): # solution[ComponentUID(stage_cost_obj,cuid_buffer=tmp)] = \ # (stage_cost_obj.value, stage_cost_obj.stale) for variable_id in node._variable_ids: var = bySymbol[variable_id] if var.is_expression(): continue solution[ComponentUID(var, cuid_buffer=tmp)] = \ (var.value, var.stale) return solution
def _preprocess(self, tname, instance): """ Iterate over the model collecting variable data, until all submodels are found. """ var = {} for (name, data) in instance.component_map(active=True).items(): if isinstance(data, Var): var[name] = data elif isinstance(data, SubModel): submodel = data if submodel is None: e = "Missing submodel: " + str(name) logger.error(e) raise RuntimeError(e) instance._transformation_data[tname].submodel = [name] #nest_level = self._nest_level(submodel) if submodel._fixed: self._fixed_vardata[name] = [ vardata for v in submodel._fixed for vardata in v.values() ] instance._transformation_data[tname].fixed = [ ComponentUID(v) for v in self._fixed_vardata[name] ] self._submodel[name] = submodel else: e = "Must specify 'fixed' or 'unfixed' options" logger.error(e) raise RuntimeError(e) self._preprocess(tname, submodel) return
def write_nl(model, nl_filename, **kwds): """ Writes a Pyomo model in NL file format and stores information about the symbol map that allows it to be recovered at a later time for a Pyomo model with matching component names. """ symbol_map_filename = nl_filename + ".symbol_map.pickle" # write the model and obtain the symbol_map _, smap_id = model.write(nl_filename, format=ProblemFormat.nl, io_options=kwds) symbol_map = model.solutions.symbol_map[smap_id] # save a persistent form of the symbol_map (using pickle) by # storing the NL file label with a ComponentUID, which is # an efficient lookup code for model components (created # by John Siirola) tmp_buffer = {} # this makes the process faster symbol_cuid_pairs = tuple( (symbol, ComponentUID(var_weakref(), cuid_buffer=tmp_buffer)) for symbol, var_weakref in symbol_map.bySymbol.items()) with open(symbol_map_filename, "wb") as f: pickle.dump(symbol_cuid_pairs, f) return symbol_map_filename
def _apply_to(self, model, **kwds): submodel_name = kwds.pop('submodel_name', 'hpr') self._preprocess('pao.pyomo.highpoint', model) map = ComponentMap() for key, sub in self.submodel.items(): model.reclassify_component_type(sub, Block) setattr(model, submodel_name, create_submodel_hp_block(model)) model._transformation_data['pao.pyomo.highpoint'].submodel_cuid = \ ComponentUID(model) model._transformation_data['pao.pyomo.highpoint'].block_cuid = \ ComponentUID(getattr(model, submodel_name)) for key, sub in self.submodel.items(): model.reclassify_component_type(sub, SubModel)
def _sub_transformation(model, sub, key): model.reclassify_component_type(sub, Block) # # Create a block with optimality conditions # setattr( model, key + '_kkt', create_submodel_kkt_block(model, sub, deterministic, self.fixed_vardata[key])) model._transformation_data['pao.bilevel.linear_mpec'].submodel_cuid =\ ComponentUID(sub) model._transformation_data['pao.bilevel.linear_mpec'].block_cuid =\ ComponentUID(getattr(model, key +'_kkt')) # # Disable the original submodel and # for data in sub.component_map(active=True).values(): if not isinstance(data, Var) and not isinstance(data, Set): data.deactivate()
def _apply_to(self, model, **kwds): deterministic = kwds.pop('deterministic', False) submodel_name = kwds.pop('submodel', None) # # Process options # submodel = self._preprocess('pao.bilevel.linear_mpec', model, sub=submodel_name) model.reclassify_component_type(submodel, Block) # # Create a block with optimality conditions # setattr(model, self._submodel+'_kkt', create_submodel_kkt_block(model, submodel, deterministic, self._fixed_vardata)) model._transformation_data['pao.bilevel.linear_mpec'].submodel_cuid =\ ComponentUID(submodel) model._transformation_data['pao.bilevel.linear_mpec'].block_cuid =\ ComponentUID(getattr(model, self._submodel+'_kkt')) # # Disable the original submodel and # for data in submodel.component_map(active=True).values(): if not isinstance(data, Var) and not isinstance(data, Set): data.deactivate()
def _apply_solver(self): start_time = time.time() # # Cache the instance # xfrm = TransformationFactory('bilevel.linear_dual') xfrm.apply_to(self._instance) # # Apply an additional transformation to remap bilinear terms # if self.options.transform is None: xfrm = None else: xfrm = TransformationFactory(self.options.transform) xfrm.apply_to(self._instance) # # Solve with a specified solver # solver = self.options.solver if not self.options.solver: solver = 'glpk' # use the with block here so that deactivation of the # solver plugin always occurs thereby avoiding memory # leaks caused by plugins! with pyomo.opt.SolverFactory(solver) as opt: self.results = [] # # **NOTE: It would be better to override _presolve on the # base class of this solver as you might be # missing a number of keywords that were passed # into the solve method (e.g., none of the # io_options are getting relayed to the subsolver # here). # self.results.append( opt.solve(self._instance, tee=self._tee, timelimit=self._timelimit)) # # Transform the result back into the original model # tdata = self._instance._transformation_data['bilevel.linear_dual'] unfixed_cuids = set() # Copy variable values and fix them for vuid in tdata.fixed: for index_, data_ in vuid.find_component_on( self._instance).iteritems(): if not data_.fixed: data_.value = self._instance.find_component( data_).value data_.fixed = True unfixed_cuids.add(ComponentUID(data_)) # Reclassify the SubModel components and resolve for name_ in tdata.submodel: submodel = getattr(self._instance, name_) submodel.activate() dual_submodel = getattr(self._instance, name_ + '_dual') dual_submodel.deactivate() pyomo.util.PyomoAPIFactory( 'pyomo.repn.compute_canonical_repn')({}, model=submodel) self._instance.reclassify_component_type(name_, Block) # use the with block here so that deactivation of the # solver plugin always occurs thereby avoiding memory # leaks caused by plugins! with pyomo.opt.SolverFactory(solver) as opt_inner: # # **NOTE: It would be better to override _presolve on the # base class of this solver as you might be # missing a number of keywords that were passed # into the solve method (e.g., none of the # io_options are getting relayed to the subsolver # here). # self.results.append( opt_inner.solve(self._instance, tee=self._tee, timelimit=self._timelimit, select=None)) self._instance.solutions.select(0, ignore_fixed_vars=True) data_.parent_component().parent_block( ).reclassify_component_type(name_, SubModel) # Unfix variables for vuid in tdata.fixed: for index_, data_ in vuid.find_component_on( self._instance).iteritems(): if ComponentUID(data_) in unfixed_cuids: data_.fixed = False stop_time = time.time() self.wall_time = stop_time - start_time # Reactivate top level objective for oname, odata in self._instance.component_map( Objective).items(): odata.activate() # # Return the sub-solver return condition value and log # return pyutilib.misc.Bunch(rc=getattr(opt, '_rc', None), log=getattr(opt, '_log', None))
def get_modified_instance( ph, scenario_tree, scenario_or_bundle, **options): # Find the model if scenario_tree.contains_bundles(): model = ph._bundle_binding_instance_map[scenario_or_bundle._name] else: model = ph._instances[scenario_or_bundle._name] b = model.component('_interscenario_plugin') if b is not None: return model # # We need to add the interscenario information to this model # model._interscenario_plugin = b = Block() # Save our options # b.epsilon = options.pop('epsilon') b.cut_scale = options.pop('cut_scale') b.allow_slack = options.pop('allow_slack') b.enable_rho = options.pop('enable_rho') b.enable_cuts = options.pop('enable_cuts') assert( len(options) == 0 ) # Information for generating cuts # b.cutlist = ConstraintList() b.abs_int_vars = VarList(within=NonNegativeIntegers) b.abs_binary_vars = VarList(within=Binary) # Note: the var_ids are on the ORIGINAL scenario models rootNode = scenario_tree.findRootNode() var_ids = list(iterkeys(rootNode._variable_datas)) # Right now, this is hard-coded for 2-stage problems - so we only # need to worry about the variables from the root node. These # variables should exist on all scenarios. Set up a (trivial) # equality constraint for each variable: # var == current_value{param} + separation_variable{var, fixed=0} b.STAGE1VAR = _S1V = Set(initialize=var_ids) b.separation_variables = _sep = Var( _S1V, dense=True ) b.fixed_variable_values = _param = Param(_S1V, mutable=True, initialize=0) b.rho = weakref.ref(model.component('PHRHO_%s' % rootNode._name)) b.weights = weakref.ref(model.component('PHWEIGHT_%s' % rootNode._name)) if b.allow_slack: for idx in _sep: _sep[idx].setlb(-b.epsilon) _sep[idx].setub(b.epsilon) else: _sep.fix(0) _cuidBuffer = {} _src = b.local_stage1_varmap = {} for i in _S1V: # Note indexing: for each 1st stage var, pick an arbitrary # (first) scenario and return the variable (and not it's # probability) _cuid = ComponentUID(rootNode._variable_datas[i][0][0], _cuidBuffer) _src[i] = weakref.ref(_cuid.find_component_on(model)) #_base_src[i] = weakref.ref(_cuid.find_component_on(base_model)) def _set_var_value(b, i): return _param[i] + _sep[i] - _src[i]() == 0 b.fixed_variables_constraint \ = _con = Constraint( _S1V, rule=_set_var_value ) # # TODO: When we get the duals of the first-stage variables, do we # want the dual WRT the original objective, or the dual WRT the # augmented objective? # # Move the objective to a standardized place so we can easily find it later if PYOMO_4_0: _orig_objective = list( x[2] for x in model.all_component_data( Objective, active=True, descend_into=True ) ) else: _orig_objective = list( model.component_data_objects( Objective, active=True, descend_into=True ) ) assert(len(_orig_objective) == 1) _orig_objective = _orig_objective[0] b.original_obj = weakref.ref(_orig_objective) # add (and deactivate) the objective for the infeasibility # separation problem. b.separation_obj = Objective( expr= sum( _sep[i]**2 for i in var_ids ), sense = minimize ) # Make sure we get dual information if 'dual' not in model: # Export and import floating point data model.dual = Suffix(direction=Suffix.IMPORT_EXPORT) #if 'rc' not in model: # model.rc = Suffix(direction=Suffix.IMPORT_EXPORT) if FALLBACK_ON_BRUTE_FORCE_PREPROCESS: model.preprocess() else: _map = {} preprocess_block_constraints(b, idMap=_map) # Note: we wait to deactivate the objective until after we # preprocess so that the obective is correctly processed. b.separation_obj.deactivate() # (temporarily) deactivate the fixed stage-1 variables _con.deactivate() toc("InterScenario plugin: generated modified problem instance") return model
def _apply_solver(self): start_time = time.time() # # Cache the instance # xfrm = TransformationFactory('bilevel.linear_dual') xfrm.apply_to(self._instance) # # Verify whether the objective is linear # nonlinear = False for odata in self._instance.component_objects(Objective, active=True): nonlinear = odata.expr.polynomial_degree() != 1 # Stop after the first objective break # # Apply an additional transformation to remap bilinear terms # if nonlinear: gdp_xfrm = TransformationFactory("gdp.bilinear") gdp_xfrm.apply_to(self._instance) mip_xfrm = TransformationFactory("gdp.bigm") mip_xfrm.apply_to(self._instance, bigM=self.options.get('bigM', 100000)) # # Solve with a specified solver # solver = self.options.solver if not self.options.solver: solver = 'glpk' # use the with block here so that deactivation of the # solver plugin always occurs thereby avoiding memory # leaks caused by plugins! with pyomo.opt.SolverFactory(solver) as opt: self.results = [] # # **NOTE: It would be better to override _presolve on the # base class of this solver as you might be # missing a number of keywords that were passed # into the solve method (e.g., none of the # io_options are getting relayed to the subsolver # here). # self.results.append( opt.solve(self._instance, tee=self._tee, timelimit=self._timelimit)) #print("POST-SOLVE - BEGIN") #self._instance.write("tmp.lp", io_options={"symbolic_solver_labels":True}) #self._instance.pprint() #self._instance.display() #print("POST-SOLVE - END") # # If the problem was bilinear, then reactivate the original data # if nonlinear: i = 0 for v in self._instance.bilinear_data_.vlist.itervalues(): #print(v) #print(v.name) #print(type(v)) #print(v.value) if abs(v.value) <= 1e-7: self._instance.bilinear_data_.vlist_boolean[i] = 0 else: self._instance.bilinear_data_.vlist_boolean[i] = 1 i = i + 1 # self._instance.bilinear_data_.deactivate() # # Transform the result back into the original model # tdata = self._instance._transformation_data['bilevel.linear_dual'] unfixed_cuids = set() # Copy variable values and fix them for vuid in tdata.fixed: for index_, data_ in vuid.find_component_on( self._instance).iteritems(): if not data_.fixed: data_.value = self._instance.find_component( data_).value data_.fixed = True unfixed_cuids.add(ComponentUID(data_)) # Reclassify the SubModel components and resolve for name_ in tdata.submodel: submodel = getattr(self._instance, name_) submodel.activate() for (name, data) in submodel.component_map(active=False).items(): if not isinstance(data, Var) and not isinstance(data, Set): data.activate() dual_submodel = getattr(self._instance, name_ + '_dual') dual_submodel.deactivate() pyomo.common.PyomoAPIFactory( 'pyomo.repn.compute_standard_repn')({}, model=submodel) self._instance.reclassify_component_type(name_, Block) # use the with block here so that deactivation of the # solver plugin always occurs thereby avoiding memory # leaks caused by plugins! with pyomo.opt.SolverFactory(solver) as opt_inner: # # **NOTE: It would be better to override _presolve on the # base class of this solver as you might be # missing a number of keywords that were passed # into the solve method (e.g., none of the # io_options are getting relayed to the subsolver # here). # results = opt_inner.solve(self._instance, tee=self._tee, timelimit=self._timelimit) #select=None) # Unfix variables for vuid in tdata.fixed: for index_, data_ in vuid.find_component_on( self._instance).iteritems(): if ComponentUID(data_) in unfixed_cuids: data_.fixed = False # self._instance.solutions.select(0, ignore_fixed_vars=True) self.results.append(results) # stop_time = time.time() self.wall_time = stop_time - start_time self.results_obj = self._setup_results_obj() # # Reactivate top level objective # and reclassify the submodel # for oname, odata in self._instance.component_map( Objective).items(): odata.activate() # TODO: rework the Block logic to allow for searching SubModel objects for variables, etc. #data_.parent_component().parent_block().reclassify_component_type(name_, SubModel) # # Return the sub-solver return condition value and log # return Bunch(rc=getattr(opt, '_rc', None), log=getattr(opt, '_log', None))
def solve(self, sp, *args, **kwds): """ Solve a stochastic program. Args: sp: The stochastic program to solve. reference_model: A pyomo model with at least the set of non-anticipative variable objects that were declared on th e scenario tree of the stochastic program. If this keyword is changed from its default value of None, the non leaf-stage variable values in the solution will be stored into the variable objects on the reference model. Otherwise, the results object that is returned will contain a solution dictionary called 'xhat' that stores the solution nested by tree node name. options: Ephemeral solver options that will temporarily overwrite any matching options currently set for the solver. output_solver_log (bool): Stream the solver output during the solve. *args: Passed to the derived solver class (see the _solve_impl method). **kwds: Passed to the derived solver class (see the _solve_impl method). Returns: A results object with information about the solution. """ start = time.time() reference_model = kwds.pop('reference_model', None) tmp_options = kwds.pop('options', None) orig_options = self.options if tmp_options is not None: self.set_options_to_default() for opt in orig_options.user_values(): self.options[opt.name()] = opt.value(accessValue=False) for key, val in tmp_options.items(): self.options[key] = val # reset the _userAccessed flag on all options # so we can verify that all set options are used # each time for key in self.options: self.options.get(key)._userAccessed = False try: if isinstance(sp, EmbeddedSP): num_scenarios = "<unknown>" num_stages = len(sp.time_stages) num_na_variables = 0 num_na_continuous_variables = 0 for stage in sp.time_stages[:-1]: for var, derived in sp.stage_to_variables_map[stage]: if not derived: num_na_variables += 1 if var.is_continuous(): num_na_continuous_variables += 1 else: scenario_tree = sp.scenario_tree num_scenarios = len(scenario_tree.scenarios) num_stages = len(scenario_tree.stages) num_na_variables = 0 num_na_continuous_variables = 0 for stage in scenario_tree.stages[:-1]: for tree_node in stage.nodes: num_na_variables += len( tree_node._standard_variable_ids) for id_ in tree_node._standard_variable_ids: if not tree_node.is_variable_discrete(id_): num_na_continuous_variables += 1 if kwds.get('output_solver_log', False): print("\n") print("-" * 20) print("Problem Statistics".center(20)) print("-" * 20) print("Total number of scenarios.................: %10s" % (num_scenarios)) if scenario_tree.contains_bundles(): print("Total number of scenario bundles..........: %10s" % (len(scenario_tree.bundles))) print("Total number of time stages...............: %10s" % (num_stages)) print("Total number of non-anticipative variables: %10s\n" " continuous: %10s\n" " discrete: %10s" % (num_na_variables, num_na_continuous_variables, num_na_variables - num_na_continuous_variables)) results = self._solve_impl(sp, *args, **kwds) stop = time.time() results.solver.pysp_time = stop - start results.solver.name = self.name if (results.status is None) or \ isinstance(results.status, UndefinedData): results.status = results.solver.termination_condition results.xhat_loaded = False if (reference_model is not None): # TODO: node/stage costs if results.xhat is not None: xhat = results.xhat for tree_obj_name in xhat: tree_obj_solution = xhat[tree_obj_name] for id_ in tree_obj_solution: var = ComponentUID(id_).\ find_component(reference_model) if not var.is_expression_type(): var.value = tree_obj_solution[id_] var.stale = False results.xhat_loaded = True del results.xhat finally: # warn about ignored options self.options.check_usage(error=False) # reset options (if temporary ones were provided) if tmp_options is not None: current_options = self.options self.set_options_to_default() for opt in orig_options.user_values(): current = current_options.get(opt.name()) self.options[opt.name()] = \ opt.value(accessValue=current._userAccessed) return results
def create_model(n_buses=3, n_snapshots=10, name='small_model', p_min_PV=0.1, co2_constraint=None): # The function creates a pypsa model with three generators, namely wind, solar and pv # The model will contain the specified number of busses and snapshots # Lines are added in a ring network = pypsa.Network() network.set_snapshots(range(n_snapshots)) network.add("Carrier", 'ocgt', co2_emissions=1) network.add("Carrier", "onwind") network.add("Carrier", "offwind") network.add("Carrier", "wind") network.add("Carrier", "solar") #add buses for i in range(n_buses): network.add("Bus", "My bus {}".format(i), x=i, y=i % 2 + 1) #add lines in a ring for i in range(n_buses): network.add( "Link", "My line {}".format(i), bus0="My bus {}".format(i), bus1="My bus {}".format((i + 1) % n_buses), p_nom=0, p_nom_extendable=True, length=1, capital_cost=np.random.rand() + 0.1, ) # Add generators for i in range(n_buses): for gen in ['solar', 'wind', 'ocgt']: network.add( "Generator", "{}{}".format(gen, i), bus="My bus {}".format(i), p_nom_max=10, type=gen, carrier=gen, p_max_pu=p_min_PV if gen == 'solar' and i % 2 == 0 else 1, #p_max_pu = float((np.random.rand()>0.5)*0.8), p_nom=0, capital_cost=np.random.rand() + 0.1, marginal_cost=np.random.rand() * 0.1, p_nom_extendable=True) network.add("Load", "My load {}".format(i), bus="My bus {}".format(i), p_set=np.random.rand(n_snapshots) * 10) if co2_constraint != None: network.add("GlobalConstraint", "co2_limit", sense="<=", carrier_attribute="co2_emissions", constant=50) # %% Solve pyomo model and add MGA constraint network.lopf(formulation="cycles", solver_name='gurobi') old_objective_value = network.objective model = network.model #%% MGA_slack = 0.1 # Add the MGA slack constraint. model.mga_constraint = pyomo_env.Constraint( expr=model.objective.expr <= (1 + MGA_slack) * old_objective_value) # Saving model as .lp file _, smap_id = model.write(name + ".lp", ) # Creating symbol map, such that variables can be maped back from .lp file to pyomo model symbol_map = model.solutions.symbol_map[smap_id] #%% tmp_buffer = {} # this makes the process faster symbol_cuid_pairs = dict( (symbol, ComponentUID(var_weakref(), cuid_buffer=tmp_buffer)) for symbol, var_weakref in symbol_map.bySymbol.items()) # %% Pickeling variable pairs with open(name + '.pickle', 'wb') as handle: pickle.dump(symbol_cuid_pairs, handle, protocol=pickle.HIGHEST_PROTOCOL)
def get_modified_instance(ph, scenario_tree, scenario_or_bundle, **options): # Find the model if scenario_tree.contains_bundles(): model = ph._bundle_binding_instance_map[scenario_or_bundle._name] else: model = ph._instances[scenario_or_bundle._name] b = model.component('_interscenario_plugin') if b is not None: return model # # We need to add the interscenario information to this model # model._interscenario_plugin = b = Block() # Save our options # b.epsilon = options.pop('epsilon') b.cut_scale = options.pop('cut_scale') b.allow_slack = options.pop('allow_slack') b.enable_rho = options.pop('enable_rho') b.enable_cuts = options.pop('enable_cuts') assert (len(options) == 0) # Information for generating cuts # b.cutlist = ConstraintList() b.abs_int_vars = VarList(within=NonNegativeIntegers) b.abs_binary_vars = VarList(within=Binary) # Note: the var_ids are on the ORIGINAL scenario models rootNode = scenario_tree.findRootNode() var_ids = list(iterkeys(rootNode._variable_datas)) # Right now, this is hard-coded for 2-stage problems - so we only # need to worry about the variables from the root node. These # variables should exist on all scenarios. Set up a (trivial) # equality constraint for each variable: # var == current_value{param} + separation_variable{var, fixed=0} b.STAGE1VAR = _S1V = Set(initialize=var_ids) b.separation_variables = _sep = Var(_S1V, dense=True) b.fixed_variable_values = _param = Param(_S1V, mutable=True, initialize=0) b.rho = weakref.ref(model.component('PHRHO_%s' % rootNode._name)) b.weights = weakref.ref(model.component('PHWEIGHT_%s' % rootNode._name)) if b.allow_slack: for idx in _sep: _sep[idx].setlb(-b.epsilon) _sep[idx].setub(b.epsilon) else: _sep.fix(0) _cuidBuffer = {} _src = b.local_stage1_varmap = {} for i in _S1V: # Note indexing: for each 1st stage var, pick an arbitrary # (first) scenario and return the variable (and not it's # probability) _cuid = ComponentUID(rootNode._variable_datas[i][0][0], _cuidBuffer) _src[i] = weakref.ref(_cuid.find_component_on(model)) #_base_src[i] = weakref.ref(_cuid.find_component_on(base_model)) def _set_var_value(b, i): return _param[i] + _sep[i] - _src[i]() == 0 b.fixed_variables_constraint \ = _con = Constraint( _S1V, rule=_set_var_value ) # # TODO: When we get the duals of the first-stage variables, do we # want the dual WRT the original objective, or the dual WRT the # augmented objective? # # Move the objective to a standardized place so we can easily find it later if PYOMO_4_0: _orig_objective = list(x[2] for x in model.all_component_data( Objective, active=True, descend_into=True)) else: _orig_objective = list( model.component_data_objects(Objective, active=True, descend_into=True)) assert (len(_orig_objective) == 1) _orig_objective = _orig_objective[0] b.original_obj = weakref.ref(_orig_objective) # add (and deactivate) the objective for the infeasibility # separation problem. b.separation_obj = Objective(expr=sum(_sep[i]**2 for i in var_ids), sense=minimize) # Make sure we get dual information if 'dual' not in model: # Export and import floating point data model.dual = Suffix(direction=Suffix.IMPORT_EXPORT) #if 'rc' not in model: # model.rc = Suffix(direction=Suffix.IMPORT_EXPORT) if FALLBACK_ON_BRUTE_FORCE_PREPROCESS: model.preprocess() else: _map = {} preprocess_block_constraints(b, idMap=_map) # Note: we wait to deactivate the objective until after we # preprocess so that the obective is correctly processed. b.separation_obj.deactivate() # (temporarily) deactivate the fixed stage-1 variables _con.deactivate() toc("InterScenario plugin: generated modified problem instance") return model
def solve(self, sp, *args, **kwds): """ Solve a stochastic program. Args: sp: The stochastic program to solve. reference_model: A pyomo model with at least the set of non-anticipative variable objects that were declared on th e scenario tree of the stochastic program. If this keyword is changed from its default value of None, the non leaf-stage variable values in the solution will be stored into the variable objects on the reference model. Otherwise, the results object that is returned will contain a solution dictionary called 'xhat' that stores the solution nested by tree node name. options: Ephemeral solver options that will temporarily overwrite any matching options currently set for the solver. output_solver_log (bool): Stream the solver output during the solve. *args: Passed to the derived solver class (see the _solve_impl method). **kwds: Passed to the derived solver class (see the _solve_impl method). Returns: A results object with information about the solution. """ start = time.time() reference_model = kwds.pop('reference_model', None) tmp_options = kwds.pop('options', None) orig_options = self.options if tmp_options is not None: self.set_options_to_default() for opt in orig_options.user_values(): self.options[opt.name()] = opt.value(accessValue=False) for key, val in tmp_options.items(): self.options[key] = val # reset the _userAccessed flag on all options # so we can verify that all set options are used # each time for key in self.options: self.options.get(key)._userAccessed = False try: if isinstance(sp, EmbeddedSP): num_scenarios = "<unknown>" num_stages = len(sp.time_stages) num_na_variables = 0 num_na_continuous_variables = 0 for stage in sp.time_stages[:-1]: for var,derived in sp.stage_to_variables_map[stage]: if not derived: num_na_variables += 1 if var.is_continuous(): num_na_continuous_variables += 1 else: scenario_tree = sp.scenario_tree num_scenarios = len(scenario_tree.scenarios) num_stages = len(scenario_tree.stages) num_na_variables = 0 num_na_continuous_variables = 0 for stage in scenario_tree.stages[:-1]: for tree_node in stage.nodes: num_na_variables += len(tree_node._standard_variable_ids) for id_ in tree_node._standard_variable_ids: if not tree_node.is_variable_discrete(id_): num_na_continuous_variables += 1 if kwds.get('output_solver_log', False): print("\n") print("-"*20) print("Problem Statistics".center(20)) print("-"*20) print("Total number of scenarios.................: %10s" % (num_scenarios)) if scenario_tree.contains_bundles(): print("Total number of scenario bundles..........: %10s" % (len(scenario_tree.bundles))) print("Total number of time stages...............: %10s" % (num_stages)) print("Total number of non-anticipative variables: %10s\n" " continuous: %10s\n" " discrete: %10s" % (num_na_variables, num_na_continuous_variables, num_na_variables - num_na_continuous_variables)) results = self._solve_impl(sp, *args, **kwds) stop = time.time() results.solver.pysp_time = stop - start results.solver.name = self.name if (results.status is None) or \ isinstance(results.status, UndefinedData): results.status = results.solver.termination_condition results.xhat_loaded = False if (reference_model is not None): # TODO: node/stage costs if results.xhat is not None: xhat = results.xhat for tree_obj_name in xhat: tree_obj_solution = xhat[tree_obj_name] for id_ in tree_obj_solution: var = ComponentUID(id_).\ find_component(reference_model) if not var.is_expression_type(): var.value = tree_obj_solution[id_] var.stale = False results.xhat_loaded = True del results.xhat finally: # warn about ignored options self.options.check_usage(error=False) # reset options (if temporary ones were provided) if tmp_options is not None: current_options = self.options self.set_options_to_default() for opt in orig_options.user_values(): current = current_options.get(opt.name()) self.options[opt.name()] = \ opt.value(accessValue=current._userAccessed) return results
def job(ref_lst, q_done): d = dict() for symbol, var_weakref in ref_lst.items(): d[symbol] = ComponentUID(var_weakref) q_done.put(d, block=True) return
def get_symbol_cuid_pairs_seriel(symbol_map): symbol_cuid_pairs = dict( (symbol, ComponentUID(var_weakref())) for symbol, var_weakref in symbol_map.bySymbol.items()) return symbol_cuid_pairs