Ejemplo n.º 1
0
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
Ejemplo n.º 2
0
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,
                                  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