def run_conf(scenario_instance_factory, index_list, num_scenarios_for_solution, num_scenarios_per_sample, full_scenario_tree, xhat_ph, options): if options.MRP_directory_basename is None: AllInOne = True sense = xhat_ph._scenario_tree._scenarios[0]._objective_sense # in order to handle the case of scenarios that are not equally # likely, we will split the expectations for Gsupk # BUT we are going to assume that the groups themselves are # equally likely and just scale by n_g and n_g-1 for Gbar and VarG # really not always needed... # http://www.eecs.berkeley.edu/~mhoemmen/cs194/Tutorials/variance.pdf g_supk_of_xhat = [] g_bar = 0 sum_xstar_obj_given_xhat = 0 n_g = options.n_g for k in range(1, n_g + 1): gk_ph = None try: if AllInOne: start_index = num_scenarios_for_solution + \ (k-1)*num_scenarios_per_sample stop_index = start_index + num_scenarios_per_sample print("") print("Computing statistics for sample k=" + str(k) + ".") if options.verbose: print("Bundle start index=" + str(start_index) + ", stop index=" + str(stop_index) + ".") # compute this xstar solution for the EF associated with # sample k. print("Loading scenario instances and initializing " "scenario tree for xstar scenario bundle.") gk_ph = ph_for_bundle(start_index, stop_index, scenario_instance_factory, full_scenario_tree, index_list, options) else: options.instance_directory = \ options.MRP_directory_basename+str(k) gk_ph = PHFromScratch(options) print("Creating the xstar extensive form.") print("") print("Composite scenarios:") for scenario in gk_ph._scenario_tree._scenarios: print(scenario._name) print("") gk_ef = ExtensiveFormAlgorithm(gk_ph, options._ef_options, prefix="ef_") gk_ef.build_ef() print("Solving the xstar extensive form.") # Instance preprocessing is managed within the # ph object automatically when required for a # solve. Since we are solving the instances # outside of the ph object, we will inform it # that it should complete the instance # preprocessing early gk_ph._preprocess_scenario_instances() gk_ef.solve(io_options=\ {'output_fixed_variable_bounds': options.write_fixed_variables}) xstar_obj = gk_ef.objective # assuming this is the absolute gap xstar_obj_gap = gk_ef.gap """ gk_ef = create_ef_instance(gk_ph._scenario_tree, generate_weighted_cvar=options.generate_weighted_cvar, cvar_weight=options.cvar_weight, risk_alpha=options.risk_alpha) print("Solving the xstar extensive form.") # Instance preprocessing is managed within the ph object # automatically when required for a solve. Since we are # solving the instances outside of the ph object, we will # inform it that it should complete the instance preprocessing # early gk_ph._preprocess_scenario_instances() ef_results = solve_ef(gk_ef, options) # as in the computation of xhat, the following is required to form a # solution to the extensive form in the scenario tree itself. gk_ph._scenario_tree.pullScenarioSolutionsFromInstances() gk_ph._scenario_tree.snapshotSolutionFromScenarios() # extract the objective function value corresponding to the # xstar solution, along with any gap information. xstar_obj = gk_ph._scenario_tree.findRootNode().computeExpectedNodeCost() # assuming this is the absolute gap xstar_obj_gap = gk_ef.solutions[0].gap# ef_results.solution(0).gap """ print("Sample extensive form objective value=" + str(xstar_obj)) # CVARHACK: if CPLEX barfed, keep trucking and bury our head # in the sand. if type(xstar_obj_gap) is UndefinedData: xstar_obj_bound = xstar_obj #EW#print("xstar_obj_bound= "+str(xstar_obj_bound)) else: if sense == minimize: xstar_obj_bound = xstar_obj - xstar_obj_gap else: xstar_obj_bound = xstar_obj + xstar_obj_gap #EW#print("xstar_obj_bound= "+str(xstar_obj_bound)) #EW#print("xstar_obj = "+str(xstar_obj)) #EW#print("xstar_obj_gap = "+str(xstar_obj_gap)) # TBD: ADD VERBOSE OUTPUT HERE # to get f(xhat) for this sample, fix the first-stage # variables and re-solve the extensive form. note that the # fixing yields side-effects on the original gk_ef, but that # is fine as it isn't used after this point. print("Solving the extensive form given the xhat solution.") #xhat = pyomo.pysp.phboundbase.ExtractInternalNodeSolutionsforInner(xhat_ph) # # fix the first stage variables # gk_root_node = gk_ph._scenario_tree.findRootNode() #root_xhat = xhat[gk_root_node._name] root_xhat = xhat_ph._scenario_tree.findRootNode()._solution for variable_id in gk_root_node._standard_variable_ids: gk_root_node.fix_variable(variable_id, root_xhat[variable_id]) # Push fixed variable statuses on instances (or # transmit to the phsolverservers), since we are not # calling the solve method on the ph object, we # need to do this manually gk_ph._push_fix_queue_to_instances() gk_ph._preprocess_scenario_instances() gk_ef.solve(io_options=\ {'output_fixed_variable_bounds': options.write_fixed_variables}) #ef_results = solve_ef(gk_ef, options) # we don't need the solution - just the objective value. #objective_name = "MASTER" #objective = gk_ef.find_component(objective_name) xstar_obj_given_xhat = gk_ef.objective print("Sample extensive form objective value given xhat=" + str(xstar_obj_given_xhat)) #g_supk_of_xhat.append(xstar_obj_given_xhat - xstar_obj_bound) if sense == minimize: g_supk_of_xhat.append(xstar_obj_given_xhat - xstar_obj_bound) else: g_supk_of_xhat.append(-xstar_obj_given_xhat + xstar_obj_bound) g_bar += g_supk_of_xhat[k - 1] sum_xstar_obj_given_xhat += xstar_obj_given_xhat finally: if gk_ph is not None: # we are using the PHCleanup function for # convenience, but we need to prevent it # from shutting down the scenario_instance_factory # as it is managed outside this function if gk_ph._scenario_tree._scenario_instance_factory is \ scenario_instance_factory: gk_ph._scenario_tree._scenario_instance_factory = None PHCleanup(gk_ph) g_bar /= n_g # second pass for variance calculation (because we like storing # the g_supk) g_var = 0.0 for k in range(0, n_g): print("g_supk_of_xhat[%d]=%12.6f" % (k + 1, g_supk_of_xhat[k])) g_var = g_var + (g_supk_of_xhat[k] - g_bar) * \ (g_supk_of_xhat[k] - g_bar) if n_g != 1: # sample var g_var = g_var / (n_g - 1) print("") print("Raw results:") print("g_bar= " + str(g_bar)) print("g_stddev= " + str(math.sqrt(g_var))) print("Average f(xhat)= " + str(sum_xstar_obj_given_xhat / n_g)) if n_g in t_table_values: print("") print("Results summary:") t_table_entries = t_table_values[n_g] for key in sorted(iterkeys(t_table_entries)): print("Confidence interval width for alpha="+str(key) +" is "+str(g_bar + (t_table_entries[key] * \ math.sqrt(g_var) / \ math.sqrt(n_g)))) else: print( "No built-in t-table entries for " + str(n_g) + " degrees of freedom - cannot calculate confidence interval width") if options.write_xhat_solution: print("") print("xhat solution:") scenario_tree = xhat_ph._scenario_tree first_stage = scenario_tree._stages[0] root_node = first_stage._tree_nodes[0] for key, val in iteritems(root_node._solutions): for idx in val: if val[idx] != 0.0: print("%s %s %s" % (str(key), str(idx), str(val[idx]()))) scenario_count = len(full_scenario_tree._stages[-1]._tree_nodes) if options.append_file is not None: output_file = open(options.append_file, "a") output_file.write("\ninstancedirectory, " + str(options.instance_directory) + ", seed, " + str(options.random_seed) + ", N, " + str(scenario_count) + ", hatn, " + str(num_scenarios_for_solution) + ", n_g, " + str(options.n_g) + ", Eoffofxhat, " + str(sum_xstar_obj_given_xhat / n_g) + ", gbar, " + str(g_bar) + ", sg, " + str(math.sqrt(g_var)) + ", objforxhat, " + str(xhat_obj) + ", n," + str(num_scenarios_per_sample)) if n_g in t_table_values: t_table_entries = t_table_values[n_g] for key in sorted(iterkeys(t_table_entries)): output_file.write(" , alpha="+str(key)+" , " +str(g_bar + (t_table_entries[key] * \ math.sqrt(g_var) / \ math.sqrt(n_g)))) if options.write_xhat_solution: output_file.write(" , ") scenario_tree = xhat_ph._scenario_tree first_stage = scenario_tree._stages[0] root_node = first_stage._tree_nodes[0] for key, val in iteritems(root_node._solutions): for idx in val: if val[idx] != 0.0: output_file.write( "%s %s %s" % (str(key), str(idx), str(val[idx]()))) output_file.close() print("") print("Results summary appended to file=" + options.append_file) xhat_ph.release_components()
def run_conf( scenario_instance_factory, index_list, num_scenarios_for_solution, num_scenarios_per_sample, full_scenario_tree, xhat_ph, options, ): if options.MRP_directory_basename is None: AllInOne = True sense = xhat_ph._scenario_tree._scenarios[0]._objective_sense # in order to handle the case of scenarios that are not equally # likely, we will split the expectations for Gsupk # BUT we are going to assume that the groups themselves are # equally likely and just scale by n_g and n_g-1 for Gbar and VarG # really not always needed... # http://www.eecs.berkeley.edu/~mhoemmen/cs194/Tutorials/variance.pdf g_supk_of_xhat = [] g_bar = 0 sum_xstar_obj_given_xhat = 0 n_g = options.n_g for k in range(1, n_g + 1): gk_ph = None try: if AllInOne: start_index = num_scenarios_for_solution + (k - 1) * num_scenarios_per_sample stop_index = start_index + num_scenarios_per_sample print("") print("Computing statistics for sample k=" + str(k) + ".") if options.verbose: print("Bundle start index=" + str(start_index) + ", stop index=" + str(stop_index) + ".") # compute this xstar solution for the EF associated with # sample k. print("Loading scenario instances and initializing " "scenario tree for xstar scenario bundle.") gk_ph = ph_for_bundle( start_index, stop_index, scenario_instance_factory, full_scenario_tree, index_list, options ) else: options.instance_directory = options.MRP_directory_basename + str(k) gk_ph = PHFromScratch(options) print("Creating the xstar extensive form.") print("") print("Composite scenarios:") for scenario in gk_ph._scenario_tree._scenarios: print(scenario._name) print("") gk_ef = ExtensiveFormAlgorithm(gk_ph, options._ef_options, prefix="ef_") gk_ef.build_ef() print("Solving the xstar extensive form.") # Instance preprocessing is managed within the # ph object automatically when required for a # solve. Since we are solving the instances # outside of the ph object, we will inform it # that it should complete the instance # preprocessing early gk_ph._preprocess_scenario_instances() gk_ef.solve(io_options={"output_fixed_variable_bounds": options.write_fixed_variables}) xstar_obj = gk_ef.objective # assuming this is the absolute gap xstar_obj_gap = gk_ef.gap """ gk_ef = create_ef_instance(gk_ph._scenario_tree, generate_weighted_cvar=options.generate_weighted_cvar, cvar_weight=options.cvar_weight, risk_alpha=options.risk_alpha) print("Solving the xstar extensive form.") # Instance preprocessing is managed within the ph object # automatically when required for a solve. Since we are # solving the instances outside of the ph object, we will # inform it that it should complete the instance preprocessing # early gk_ph._preprocess_scenario_instances() ef_results = solve_ef(gk_ef, options) # as in the computation of xhat, the following is required to form a # solution to the extensive form in the scenario tree itself. gk_ph._scenario_tree.pullScenarioSolutionsFromInstances() gk_ph._scenario_tree.snapshotSolutionFromScenarios() # extract the objective function value corresponding to the # xstar solution, along with any gap information. xstar_obj = gk_ph._scenario_tree.findRootNode().computeExpectedNodeCost() # assuming this is the absolute gap xstar_obj_gap = gk_ef.solutions[0].gap# ef_results.solution(0).gap """ print("Sample extensive form objective value=" + str(xstar_obj)) # CVARHACK: if CPLEX barfed, keep trucking and bury our head # in the sand. if type(xstar_obj_gap) is UndefinedData: xstar_obj_bound = xstar_obj # EW#print("xstar_obj_bound= "+str(xstar_obj_bound)) else: if sense == minimize: xstar_obj_bound = xstar_obj - xstar_obj_gap else: xstar_obj_bound = xstar_obj + xstar_obj_gap # EW#print("xstar_obj_bound= "+str(xstar_obj_bound)) # EW#print("xstar_obj = "+str(xstar_obj)) # EW#print("xstar_obj_gap = "+str(xstar_obj_gap)) # TBD: ADD VERBOSE OUTPUT HERE # to get f(xhat) for this sample, fix the first-stage # variables and re-solve the extensive form. note that the # fixing yields side-effects on the original gk_ef, but that # is fine as it isn't used after this point. print("Solving the extensive form given the xhat solution.") # xhat = pyomo.pysp.phboundbase.ExtractInternalNodeSolutionsforInner(xhat_ph) # # fix the first stage variables # gk_root_node = gk_ph._scenario_tree.findRootNode() # root_xhat = xhat[gk_root_node._name] root_xhat = xhat_ph._scenario_tree.findRootNode()._solution for variable_id in gk_root_node._standard_variable_ids: gk_root_node.fix_variable(variable_id, root_xhat[variable_id]) # Push fixed variable statuses on instances (or # transmit to the phsolverservers), since we are not # calling the solve method on the ph object, we # need to do this manually gk_ph._push_fix_queue_to_instances() gk_ph._preprocess_scenario_instances() gk_ef.solve(io_options={"output_fixed_variable_bounds": options.write_fixed_variables}) # ef_results = solve_ef(gk_ef, options) # we don't need the solution - just the objective value. # objective_name = "MASTER" # objective = gk_ef.find_component(objective_name) xstar_obj_given_xhat = gk_ef.objective print("Sample extensive form objective value given xhat=" + str(xstar_obj_given_xhat)) # g_supk_of_xhat.append(xstar_obj_given_xhat - xstar_obj_bound) if sense == minimize: g_supk_of_xhat.append(xstar_obj_given_xhat - xstar_obj_bound) else: g_supk_of_xhat.append(-xstar_obj_given_xhat + xstar_obj_bound) g_bar += g_supk_of_xhat[k - 1] sum_xstar_obj_given_xhat += xstar_obj_given_xhat finally: if gk_ph is not None: # we are using the PHCleanup function for # convenience, but we need to prevent it # from shutting down the scenario_instance_factory # as it is managed outside this function if gk_ph._scenario_tree._scenario_instance_factory is scenario_instance_factory: gk_ph._scenario_tree._scenario_instance_factory = None PHCleanup(gk_ph) g_bar /= n_g # second pass for variance calculation (because we like storing # the g_supk) g_var = 0.0 for k in range(0, n_g): print("g_supk_of_xhat[%d]=%12.6f" % (k + 1, g_supk_of_xhat[k])) g_var = g_var + (g_supk_of_xhat[k] - g_bar) * (g_supk_of_xhat[k] - g_bar) if n_g != 1: # sample var g_var = g_var / (n_g - 1) print("") print("Raw results:") print("g_bar= " + str(g_bar)) print("g_stddev= " + str(math.sqrt(g_var))) print("Average f(xhat)= " + str(sum_xstar_obj_given_xhat / n_g)) if n_g in t_table_values: print("") print("Results summary:") t_table_entries = t_table_values[n_g] for key in sorted(iterkeys(t_table_entries)): print( "Confidence interval width for alpha=" + str(key) + " is " + str(g_bar + (t_table_entries[key] * math.sqrt(g_var) / math.sqrt(n_g))) ) else: print( "No built-in t-table entries for " + str(n_g) + " degrees of freedom - cannot calculate confidence interval width" ) if options.write_xhat_solution: print("") print("xhat solution:") scenario_tree = xhat_ph._scenario_tree first_stage = scenario_tree._stages[0] root_node = first_stage._tree_nodes[0] for key, val in iteritems(root_node._solutions): for idx in val: if val[idx] != 0.0: print("%s %s %s" % (str(key), str(idx), str(val[idx]()))) scenario_count = len(full_scenario_tree._stages[-1]._tree_nodes) if options.append_file is not None: output_file = open(options.append_file, "a") output_file.write( "\ninstancedirectory, " + str(options.instance_directory) + ", seed, " + str(options.random_seed) + ", N, " + str(scenario_count) + ", hatn, " + str(num_scenarios_for_solution) + ", n_g, " + str(options.n_g) + ", Eoffofxhat, " + str(sum_xstar_obj_given_xhat / n_g) + ", gbar, " + str(g_bar) + ", sg, " + str(math.sqrt(g_var)) + ", objforxhat, " + str(xhat_obj) + ", n," + str(num_scenarios_per_sample) ) if n_g in t_table_values: t_table_entries = t_table_values[n_g] for key in sorted(iterkeys(t_table_entries)): output_file.write( " , alpha=" + str(key) + " , " + str(g_bar + (t_table_entries[key] * math.sqrt(g_var) / math.sqrt(n_g))) ) if options.write_xhat_solution: output_file.write(" , ") scenario_tree = xhat_ph._scenario_tree first_stage = scenario_tree._stages[0] root_node = first_stage._tree_nodes[0] for key, val in iteritems(root_node._solutions): for idx in val: if val[idx] != 0.0: output_file.write("%s %s %s" % (str(key), str(idx), str(val[idx]()))) output_file.close() print("") print("Results summary appended to file=" + options.append_file) xhat_ph.release_components()
def find_candidate(scenario_instance_factory, index_list, num_scenarios_for_solution, full_scenario_tree, options): # create a ph object for finding the solution. we do this even if # we're solving the extensive form directly, mainly out of # convenience - we're leveraging the code in ph_for_bundle to # create the scenario tree and scenario instances. print("") print("Loading scenario instances and initializing " "scenario tree for xhat scenario bundle.") xhat_ph = None try: xhat_ph = ph_for_bundle(0, num_scenarios_for_solution, scenario_instance_factory, full_scenario_tree, index_list, options) xhat_obj = None sense = xhat_ph._scenario_tree._scenarios[0]._objective_sense if sense == minimize: print("We are solving a MINIMIZATION problem.") else: print("We are solving a MAXIMIZATION problem.") if not options.solve_xhat_with_ph: print("Creating the xhat extensive form.") print("") print("Composite scenarios:") for scenario in xhat_ph._scenario_tree._scenarios: print(scenario._name) print("") if options.verbose: print("Time=" + time.asctime()) with ExtensiveFormAlgorithm(xhat_ph, options._ef_options, prefix="ef_") as ef: ef.build_ef() print("Solving the xhat extensive form.") # Instance preprocessing is managed within the # ph object automatically when required for a # solve. Since we are solving the instances # outside of the ph object, we will inform it # that it should complete the instance # preprocessing early xhat_ph._preprocess_scenario_instances() ef.solve(io_options=\ {'output_fixed_variable_bounds': options.write_fixed_variables}) xhat_obj = ef.objective """ hatex_ef = create_ef_instance( xhat_ph._scenario_tree, verbose_output=options.verbose, generate_weighted_cvar=options.generate_weighted_cvar, cvar_weight=options.cvar_weight, risk_alpha=options.risk_alpha) if options.verbose: print("Time="+time.asctime()) print("Solving the xhat extensive form.") # Instance preprocessing is managed within the ph object # automatically when required for a solve. Since we are # solving the instances outside of the ph object, we will # inform it that it should complete the instance preprocessing # early xhat_ph._preprocess_scenario_instances() ef_results = solve_ef(hatex_ef, options) if options.verbose: print("Loading extensive form solution.") print("Time="+time.asctime()) # IMPT: the following method populates the _solution variables # on the scenario tree nodes by forming an average of # the corresponding variable values for all instances # particpating in that node. if you don't do this, the # scenario tree doesn't have the solution - and we need # this below for variable fixing. if options.verbose: print("Computing extensive form solution from instances.") print("Time="+time.asctime()) xhat_ph._scenario_tree.pullScenarioSolutionsFromInstances() xhat_ph._scenario_tree.snapshotSolutionFromScenarios() xhat_obj = xhat_ph._scenario_tree.findRootNode().computeExpectedNodeCost() """ print("Extensive form objective value given xhat=" + str(xhat_obj)) else: print("Solving for xhat via Progressive Hedging.") phretval = xhat_ph.solve() if phretval is not None: raise RuntimeError("No solution was obtained " "for scenario: " + phretval) # TBD - grab xhat_obj; complicated by the fact that PH may not # have converged. # TBD - also not sure if PH calls # snapshotSolutionFromAverages. print("The computation of xhat is complete - " "starting to compute confidence interval " "via sub-sampling.") finally: if xhat_ph is not None: # we are using the PHCleanup function for # convenience, but we need to prevent it # from shutting down the scenario_instance_factory # as it is managed outside this function xhat_ph._scenario_tree._scenario_instance_factory = None PHCleanup(xhat_ph) return xhat_ph
def solve_ph_code(ph, options): import pyomo.environ import pyomo.solvers.plugins.smanager.phpyro # consolidate the code to solve the problem for the "global" ph object # return a solver code (string from the solver if EF, "PH" if PH) and the objective fct val SolStatus = None ph._preprocess_scenario_instances() ObjectiveFctValue = \ float('inf') if (ph._objective_sense is minimize) else float('-inf') SolStatus = None if not options.solve_with_ph: if options.verbose is True: print("Creating the extensive form.") print("Time=" + time.asctime()) with ExtensiveFormAlgorithm(ph, options._ef_options, options_prefix="ef_") as ef: ef.build_ef() failure = ef.solve(io_options=\ {'output_fixed_variable_bounds': options.write_fixed_variables}, exception_on_failure=False) if not failure: ObjectiveFctValue = ef.objective SolStatus = str(ef.solver_status) """ ef = create_ef_instance(ph._scenario_tree, verbose_output=options.verbose) if options.verbose: print("Time="+time.asctime()) print("Solving the extensive form.") ef_results = solve_ef(ef, options) SolStatus = str(ef_results.solver.status) print("SolStatus="+SolStatus) if options.verbose is True: print("Loading extensive form solution.") print("Time="+time.asctime()) ### If the solution is infeasible, we don't want to load the results ### It is up to the caller to decide what to do with non-optimal if SolStatus != "infeasible" and SolStatus != "unknown": # IMPT: the following method populates the _solution variables on the scenario tree # nodes by forming an average of the corresponding variable values for all # instances particpating in that node. if you don't do this, the scenario tree # doesn't have the solution - and we need this below for variable bounding ph._scenario_tree.pullScenarioSolutionsFromInstances() ph._scenario_tree.snapshotSolutionFromScenarios() if options.verbose is True: print("SolStatus="+SolStatus) print("Time="+time.asctime()) _tear_down_ef(ef, ph._instances) """ else: if options.verbose: print("Solving via Progressive Hedging.") run_ph(options, ph) ph._scenario_tree.pullScenarioSolutionsFromInstances() root_node = ph._scenario_tree._stages[0]._tree_nodes[0] ObjectiveFctValue = root_node.computeExpectedNodeCost() SolStatus = "PH" """ phretval = ph.solve() #print("--------->>>> "+str(phretval)) SolStatus = "PH" if phretval is not None: print("Iteration zero solve was not successful for scenario: "+str(phretval)) if options.verbose is True: print("Iteration zero solve was not successful for scenario: "+str(phretval)) SolStatus = "PHFailAtScen"+str(phretval) # TBD - also not sure if PH calls snapshotSolutionFromAverages. if options.verbose is True: print("Done with PH solve.") ##begin copy from phinit solution_writer_plugins = ExtensionPoint(ISolutionWriterExtension) for plugin in solution_writer_plugins: plugin.write(ph._scenario_tree, "ph") # store the binding instance, if created, in order to load # the solution back into the scenario tree. binding_instance = None # # create the extensive form binding instance, so that we can either write or solve it (if specified). # if (options.write_ef) or (options.solve_ef): # The post-solve plugins may have done more variable # fixing. These should be pushed to the instance at this # point. print("Pushing fixed variable statuses to scenario instances") ph._push_all_node_fixed_to_instances() total_fixed_discrete_vars, total_fixed_continuous_vars = \ ph.compute_fixed_variable_counts() print("Number of discrete variables fixed " "prior to ef creation=" +str(total_fixed_discrete_vars)+ " (total="+str(ph._total_discrete_vars)+")") print("Number of continuous variables fixed " "prior to ef creation=" +str(total_fixed_continuous_vars)+ " (total="+str(ph._total_continuous_vars)+")") print("Creating extensive form for remainder problem") ef_instance_start_time = time.time() binding_instance = create_ef_instance(ph._scenario_tree) ef_instance_end_time = time.time() print("Time to construct extensive form instance=%.2f seconds" % (ef_instance_end_time - ef_instance_start_time)) ph._preprocess_scenario_instances() # # solve the extensive form and load the solution back into the PH scenario tree. # contents from the PH solve will obviously be over-written! # if options.write_ef: output_filename = os.path.expanduser(options.ef_output_file) # technically, we don't need the symbol map since we aren't solving it. print("Starting to write the extensive form") ef_write_start_time = time.time() symbol_map = write_ef(binding_instance, output_filename, symbolic_solver_labels=options.symbolic_solver_labels, output_fixed_variable_bounds=options.write_fixed_variables) ef_write_end_time = time.time() print("Extensive form written to file="+output_filename) print("Time to write output file=%.2f seconds" % (ef_write_end_time - ef_write_start_time)) if options.solve_ef: # set the value of each non-converged, non-final-stage variable to None - # this will avoid infeasible warm-stats. reset_nonconverged_variables(ph._scenario_tree, ph._instances) reset_stage_cost_variables(ph._scenario_tree, ph._instances) ef_results = solve_ef(binding_instance, options) print("Storing solution in scenario tree") ph._scenario_tree.pullScenarioSolutionsFromInstances() ph._scenario_tree.snapshotSolutionFromScenarios() ef_solve_end_time = time.time() print("Time to solve and load results for the " "extensive form=%.2f seconds" % (ef_solve_end_time - ef_solve_start_time)) # print *the* metric of interest. print("") root_node = ph._scenario_tree._stages[0]._tree_nodes[0] print("***********************************************************************************************") print(">>>THE EXPECTED SUM OF THE STAGE COST VARIABLES="+str(root_node.computeExpectedNodeCost())+"<<<") print("***********************************************************************************************") print("") print("Extensive form solution:") ph._scenario_tree.pprintSolution() print("") print("Extensive form costs:") ph._scenario_tree.pprintCosts() solution_writer_plugins = ExtensionPoint(ISolutionWriterExtension) for plugin in solution_writer_plugins: plugin.write(ph._scenario_tree, "postphef") if binding_instance is not None: _tear_down_ef(binding_instance, ph._instances) """ print("SolStatus=" + str(SolStatus)) if options.verbose: print("Time=" + time.asctime()) ## print "(using PySP Cost vars) ObjectiveFctValue=",ObjectiveFctValue return SolStatus, ObjectiveFctValue