def test_ama_running(self): options = self._get_base_options() ama_options = options['kwoptions'] ama_object = ama.from_module(self.refmodelname, ama_options, use_command_line=False) ama_object.run() obj = round_pos_sig(ama_object.EF_Obj,2) self.assertEqual(obj, 810.)
def xhat_generator_farmer(scenario_names, solvername="gurobi", solver_options=None, use_integer=False, crops_multiplier=1, start_seed=None): ''' For sequential sampling. Takes scenario names as input and provide the best solution for the approximate problem associated with the scenarios. Parameters ---------- scenario_names: list of str Names of the scenario we use solvername: str, optional Name of the solver used. The default is "gurobi" solver_options: dict, optional Solving options. The default is None. use_integer: boolean indicates the integer farmer version crops_multiplier: int mulitplied by three to get the total number of crops start_seed: int, optional The starting seed, used to create different sample scenario trees. The default is 0. Returns ------- xhat: str A generated xhat, solution to the approximate problem induced by scenario_names. NOTE: This tool only works when the file is in mpisppy. In SPInstances, you must change the from_module line. ''' num_scens = len(scenario_names) ama_options = { "EF-2stage": True, "EF_solver_name": solvername, "EF_solver_options": solver_options, "num_scens": num_scens, "_mpisppy_probability": 1 / num_scens, "start_seed": start_seed, } #We use from_module to build easily an Amalgamator object ama = amalgamator.from_module("afarmer", ama_options, use_command_line=False) #Correcting the building by putting the right scenarios. ama.scenario_names = scenario_names ama.verbose = False ama.run() # get the xhat xhat = sputils.nonant_cache_from_ef(ama.ef) return {'ROOT': xhat['ROOT']}
def test_ama_creator(self): options = self._get_base_options() ama_options = { "EF-2stage": True, } ama_options.update(options['opt']) ama_object = ama.from_module(self.refmodelname, options=ama_options, use_command_line=False)
def test_ama_running(self): options = self._get_base_options() ama_options = {"EF-2stage": True} ama_options.update(options['opt']) ama_object = ama.from_module(self.refmodelname, ama_options, use_command_line=False) ama_object.run() obj = round_pos_sig(ama_object.EF_Obj, 2) self.assertEqual(obj, -130000)
def main(): solution_files = { "first_stage_solution": "farmer_first_stage.csv", } ama_options = { "EF-2stage": True, # We are solving directly the EF "write_solution": solution_files } #The module can be a local file ama = amalgamator.from_module("afarmer", ama_options) ama.run() print("first_stage_solution=", ama.first_stage_solution) print("inner bound=", ama.best_inner_bound) print("outer bound=", ama.best_outer_bound)
def xhat_generator_farmer(scenario_names, solvername="gurobi", solver_options=None, crops_multiplier=1): ''' For developer testing: Given scenario names and options, create the scenarios and compute the xhat that is minimizing the approximate problem associated with these scenarios. Parameters ---------- scenario_names: int Names of the scenario we use solvername: str, optional Name of the solver used. The default is "gurobi". solver_options: dict, optional Solving options. The default is None. crops_multiplier: int, optional A parameter of the farmer model. The default is 1. Returns ------- xhat: xhat object (dict containing a 'ROOT' key with a np.array) A generated xhat. NOTE: this is here for testing during development. ''' num_scens = len(scenario_names) ama_options = { "EF-2stage": True, "EF_solver_name": solvername, "EF_solver_options": solver_options, "use_integer": False, "crops_multiplier": crops_multiplier, "num_scens": num_scens, "_mpisppy_probability": 1 / num_scens, } #We use from_module to build easily an Amalgamator object ama = amalgamator.from_module("mpisppy.tests.examples.farmer", ama_options, use_command_line=False) #Correcting the building by putting the right scenarios. ama.scenario_names = scenario_names ama.run() # get the xhat xhat = sputils.nonant_cache_from_ef(ama.ef) return xhat
def xhat_generator_apl1p(scenario_names, solvername="gurobi", solver_options=None): ''' For sequential sampling. Takes scenario names as input and provide the best solution for the approximate problem associated with the scenarios. Parameters ---------- scenario_names: int Names of the scenario we use solvername: str, optional Name of the solver used. The default is "gurobi" solver_options: dict, optional Solving options. The default is None. Returns ------- xhat: str A generated xhat, solution to the approximate problem induced by scenario_names. ''' num_scens = len(scenario_names) ama_options = { "EF-2stage": True, "EF_solver_name": solvername, "EF_solver_options": solver_options, "num_scens": num_scens, "_mpisppy_probability": 1 / num_scens, } #We use from_module to build easily an Amalgamator object ama = amalgamator.from_module("mpisppy.tests.examples.apl1p", ama_options, use_command_line=False) #Correcting the building by putting the right scenarios. ama.scenario_names = scenario_names ama.run() # get the xhat xhat = sputils.nonant_cache_from_ef(ama.ef) return xhat
def main(): solution_files = { "first_stage_solution": "uc_first_stage.csv", #"tree_solution":"uc_ama_full_solution" #It takes too long to right the full solution } ama_options = { "2stage": True, # 2stage vs. mstage "cylinders": ['ph', 'xhatshuffle', 'lagranger'], "extensions": ['fixer'], "id_fix_list_fct": id_fix_list_fct, #Needed for fixer, but not passed in baseparsers "write_solution": solution_files } ama = amalgamator.from_module("uc_funcs", ama_options) ama.run() if ama.on_hub: print("first_stage_solution=", ama.first_stage_solution) print("inner bound=", ama.best_inner_bound) print("outer bound=", ama.best_outer_bound)
def xhat_generator_aircond(scenario_names, solvername="gurobi", solver_options=None, branching_factors=None, mudev=0, sigmadev=40, start_ups=None, start_seed=0): ''' For sequential sampling. Takes scenario names as input and provide the best solution for the approximate problem associated with the scenarios. Parameters ---------- scenario_names: list of str Names of the scenario we use solvername: str, optional Name of the solver used. The default is "gurobi" solver_options: dict, optional Solving options. The default is None. branching_factors: list, optional Branching factors of the scenario 3. The default is [3,2,3] (a 4 stage model with 18 different scenarios) mudev: float, optional The average deviation of demand between two stages; The default is 0. sigma_dev: float, optional The standard deviation from mudev for the demand difference between two stages. The default is 40. start_seed: int, optional The starting seed, used to create different sample scenario trees. The default is 0. Returns ------- xhat: str A generated xhat, solution to the approximate problem induced by scenario_names. NOTE: This tool only works when the file is in mpisppy. In SPInstances, you must change the from_module line. ''' num_scens = len(scenario_names) ama_options = { "EF-mstage": True, "EF_solver_name": solvername, "EF_solver_options": solver_options, "num_scens": num_scens, "_mpisppy_probability": 1 / num_scens, "branching_factors": branching_factors, "mudev": mudev, "start_ups": start_ups, "start_seed": start_seed, "sigmadev": sigmadev } #We use from_module to build easily an Amalgamator object ama = amalgamator.from_module("mpisppy.tests.examples.aircond", ama_options, use_command_line=False) #Correcting the building by putting the right scenarios. ama.scenario_names = scenario_names ama.verbose = False ama.run() # get the xhat xhat = sputils.nonant_cache_from_ef(ama.ef) return xhat
ama_options = { "EF-mstage": True, "EF_solver_name": solver_name, "EF_solver_options": solver_options, "num_scens": num_scens, "branching_factors": bfs, "mudev": 0, "sigmadev": 40, "start_ups": start_ups, "start_seed": 0 } refmodel = "mpisppy.tests.examples.aircond" # WARNING: Change this in SPInstances #We use from_module to build easily an Amalgamator object t0 = time.time() ama = amalgamator.from_module(refmodel, ama_options, use_command_line=False) ama.run() print('start ups costs: ', start_ups) print('branching factors: ', bfs) print('run time: ', time.time() - t0) print(f"inner bound =", ama.best_inner_bound) print(f"outer bound =", ama.best_outer_bound) xhat = sputils.nonant_cache_from_ef(ama.ef) print('xhat_one = ', xhat['ROOT']) if save_xhat: bf_string = '' for bf in bfs: bf_string = bf_string + bf + '_'
if __name__ == "__main__": num_scens = 300 solvername = 'gurobi_direct' solver_options=None scenario_names = scenario_names_creator(num_scens,start=6000) ama_options = { "EF-2stage": True, "EF_solver_name": solvername, "EF_solver_options": solver_options, "num_scens": num_scens, "_mpisppy_probability": None, } #We use from_module to build easily an Amalgamator object ama = amalgamator.from_module("mpisppy.tests.examples.gbd.gbd", ama_options,use_command_line=False) #Correcting the building by putting the right scenarios. ama.scenario_names = scenario_names ama.run() print(f"inner bound=", ama.best_inner_bound) print(f"outer bound=", ama.best_outer_bound) xhat = sputils.nonant_cache_from_ef(ama.ef) print("xhat=",xhat['ROOT']) from mpisppy.confidence_intervals.seqsampling import SeqSampling optionsFSP = {'eps': 8.0, 'solvername': "gurobi_direct", "c0":300, "kf_Gs":25, "kf_xhat":25}
print ("SUGAR_BEETS0 for scenario",sname,"is", pyo.value(s.DevotedAcreage["SUGAR_BEETS0"])) print ("FirstStageCost for scenario",sname,"is", pyo.value(s.FirstStageCost)) if __name__ == "__main__": # To test: python afarmer.py --num-scens=3 refmodel = "afarmer" #Change this path to use a different model #Compute the nonant xhat (the one used in the left term of MMW (9) ) using # the first scenarios ama_options = {"EF-2stage": True,# 2stage vs. mstage "start": False} #Are the scenario shifted by a start arg ? #add information about batches ama_extraargs = argparse.ArgumentParser(add_help=False) print(ama_extraargs) ama_object = ama.from_module(refmodel, ama_options,extraargs=ama_extraargs) ama_object.run() if global_rank==0 : print("inner bound=", ama_object.best_inner_bound) # This the xhat of the left term of LHS of MMW (9) print("outer bound=", ama_object.best_outer_bound) ########### get the nonants (the xhat) sputils.ef_ROOT_nonants_npy_serializer(ama_object.ef, "farmer_root_nonants_temp.npy")
def gap_estimators(xhat_one, mname, solving_type="EF-2stage", scenario_names=None, sample_options=None, ArRP=1, scenario_creator_kwargs={}, scenario_denouement=None, solvername=None, solver_options=None, verbose=False, objective_gap=False): ''' Given a xhat, scenario names, a scenario creator and options, gap_estimators creates a scenario tree and the associatd estimators G and s from ยง2 of [bm2011]. Returns G and s evaluated at xhat. If ArRP>1, G and s are pooled, from a number ArRP of estimators, computed with different scenario trees. Parameters ---------- xhat_one : dict A candidate first stage solution mname: str Name of the reference model, e.g. 'mpisppy.tests.examples.farmer'. solving_type: str, optional The way we solve the approximate problem. Can be "EF-2stage" (default) or "EF-mstage". scenario_names: list, optional List of scenario names used to compute G_n and s_n. Default is None Must be specified for 2 stage, but can be missing for multistage sample_options: dict, optional Only for multistage. Must contain a 'seed' and a 'branching_factors' attribute, specifying the starting seed and the branching factors of the scenario tree ArRP:int,optional Number of batches (we create a ArRP model). Default is 1 (one batch). scenario_creator_kwargs: dict, optional Additional arguments for scenario_creator. Default is {} scenario_denouement: function, optional Function to run after scenario creation. Default is None. solvername : str, optional Solver. Default is None solver_options: dict, optional Solving options. Default is None verbose: bool, optional Should it print the gap estimator ? Default is True objective_gap: bool, optional Returns a gap estimate around approximate objective value branching_factors: list, optional Only for multistage. List of branching factors of the sample scenario tree. Returns ------- G_k and s_k, gap estimator and associated standard deviation estimator. ''' global_toc("Enter gap_estimators") if solving_type not in ["EF-2stage", "EF-mstage"]: raise RuntimeError( "Only EF solve for the approximate problem is supported yet.") else: is_multi = (solving_type == "EF-mstage") if is_multi: try: branching_factors = sample_options['branching_factors'] start = sample_options['seed'] except (TypeError, KeyError, RuntimeError): raise RuntimeError( 'For multistage problems, sample_options must be a dict with branching_factors and seed attributes.' ) else: start = sputils.extract_num(scenario_names[0]) if ArRP > 1: #Special case : ArRP, G and s are pooled from r>1 estimators. if is_multi: raise RuntimeError( "Pooled estimators are not supported for multistage problems yet." ) n = len(scenario_names) if (n % ArRP != 0): raise RuntimeWarning("You put as an input a number of scenarios"+\ f" which is not a mutliple of {ArRP}.") n = n - n % ArRP G = [] s = [] for k in range(ArRP): scennames = scenario_names[k * (n // ArRP):(k + 1) * (n // ArRP)] tmp = gap_estimators( xhat_one, mname, solvername=solvername, scenario_names=scennames, ArRP=1, scenario_creator_kwargs=scenario_creator_kwargs, scenario_denouement=scenario_denouement, solver_options=solver_options, solving_type=solving_type) G.append(tmp['G']) s.append(tmp['s']) global_toc(f"ArRP {k} of {ArRP}") #Pooling G = np.mean(G) s = np.linalg.norm(s) / np.sqrt(n // ArRP) return {"G": G, "s": s, "seed": start} #A1RP #We start by computing the optimal solution to the approximate problem induced by our scenarios if is_multi: #Sample a scenario tree: this is a subtree, but starting from stage 1 samp_tree = sample_tree.SampleSubtree( mname, xhats=[], root_scen=None, starting_stage=1, branching_factors=branching_factors, seed=start, options=scenario_creator_kwargs, solvername=solvername, solver_options=solver_options) samp_tree.run() start += sputils.number_of_nodes(branching_factors) ama_object = samp_tree.ama else: #We use amalgamator to do it ama_options = dict(scenario_creator_kwargs) ama_options['start'] = start ama_options['num_scens'] = len(scenario_names) ama_options['EF_solver_name'] = solvername ama_options['EF_solver_options'] = solver_options ama_options[solving_type] = True ama_object = ama.from_module(mname, ama_options, use_command_line=False) ama_object.scenario_names = scenario_names ama_object.verbose = False ama_object.run() start += len(scenario_names) #Optimal solution of the approximate problem zstar = ama_object.best_outer_bound #Associated policies xstars = sputils.nonant_cache_from_ef(ama_object.ef) #Then, we evaluate the fonction value induced by the scenario at xstar. if is_multi: # Find feasible policies (i.e. xhats) for every non-leaf nodes if len(samp_tree.ef._ef_scenario_names) > 1: local_scenarios = { sname: getattr(samp_tree.ef, sname) for sname in samp_tree.ef._ef_scenario_names } else: local_scenarios = { samp_tree.ef._ef_scenario_names[0]: samp_tree.ef } xhats, start = sample_tree.walking_tree_xhats( mname, local_scenarios, xhat_one['ROOT'], branching_factors, start, scenario_creator_kwargs, solvername=solvername, solver_options=solver_options) #Compute then the average function value with this policy scenario_creator_kwargs = samp_tree.ama.kwargs all_nodenames = sputils.create_nodenames_from_branching_factors( branching_factors) else: #In a 2 stage problem, the only non-leaf is the ROOT node xhats = xhat_one all_nodenames = None xhat_eval_options = { "iter0_solver_options": None, "iterk_solver_options": None, "display_timing": False, "solvername": solvername, "verbose": False, "solver_options": solver_options } ev = xhat_eval.Xhat_Eval(xhat_eval_options, scenario_names, ama_object.scenario_creator, scenario_denouement, scenario_creator_kwargs=scenario_creator_kwargs, all_nodenames=all_nodenames) #Evaluating xhat and xstar and getting the value of the objective function #for every (local) scenario zhat = ev.evaluate(xhats) objs_at_xhat = ev.objs_dict zstar = ev.evaluate(xstars) objs_at_xstar = ev.objs_dict eval_scen_at_xhat = [] eval_scen_at_xstar = [] scen_probs = [] for k, s in ev.local_scenarios.items(): eval_scen_at_xhat.append(objs_at_xhat[k]) eval_scen_at_xstar.append(objs_at_xstar[k]) scen_probs.append(s._mpisppy_probability) scen_gaps = np.array(eval_scen_at_xhat) - np.array(eval_scen_at_xstar) local_gap = np.dot(scen_gaps, scen_probs) local_ssq = np.dot(scen_gaps**2, scen_probs) local_prob_sqnorm = np.linalg.norm(scen_probs)**2 local_obj_at_xhat = np.dot(eval_scen_at_xhat, scen_probs) local_estim = np.array( [local_gap, local_ssq, local_prob_sqnorm, local_obj_at_xhat]) global_estim = np.zeros(4) ev.mpicomm.Allreduce(local_estim, global_estim, op=mpi.SUM) G, ssq, prob_sqnorm, obj_at_xhat = global_estim if global_rank == 0 and verbose: print(f"G = {G}") sample_var = (ssq - G**2) / (1 - prob_sqnorm) #Unbiased sample variance s = np.sqrt(sample_var) use_relative_error = (np.abs(zstar) > 1) G = correcting_numeric(G, objfct=obj_at_xhat, relative_error=use_relative_error) if objective_gap: if is_multi: return { "G": G, "s": s, "zhats": [zhat], "zstars": [zstar], "seed": start } else: return { "G": G, "s": s, "zhats": eval_scen_at_xhat, "zstars": eval_scen_at_xstar, "seed": start } else: return {"G": G, "s": s, "seed": start}
def test_ama_creator(self): options = self._get_base_options() ama_options = options['kwoptions'] ama_object = ama.from_module(self.refmodelname, options=ama_options, use_command_line=False)
return xhats, seed if __name__ == "__main__": # This main program is provided to developers can run quick tests. branching_factors = [3,2,4,4] num_scens = np.prod(branching_factors) mname = "mpisppy.tests.examples.aircond" ama_options = { "EF-mstage": True, "num_scens": num_scens, "_mpisppy_probability": 1/num_scens, "branching_factors":branching_factors, } #We use from_module to build easily an Amalgamator object ama = amalgamator.from_module(mname, ama_options,use_command_line=False) ama.run() # get the xhat xhat_one = sputils.nonant_cache_from_ef(ama.ef)['ROOT'] #----------Find a feasible solution for a single scenario------------- scenario = ama.ef.scen0 seed = sputils.number_of_nodes(branching_factors) options = dict() #We take default aircond options xhats,seed = _feasible_solution(mname, scenario, xhat_one, branching_factors, seed, options) print(xhats) #----------Find feasible solutions for every scenario ------------