Exemplo n.º 1
0
def solve(localsolver, solvername, instance,
          logfilename='logfile_loadobjective.log',
          get_suffixes=True, solver_options=None, outputfile=None):
    # Wall time - clock starts.
    starttime_modelsolve = time.time()

    if localsolver:
        solver = SolverFactory(solvername)

        # Configure with solver options
        # file_print_levels (Output Level-of-Detail):
        #   4 for just # of iterations, and final objective, infeas,etc. values
        #   6 for summary information about all iterations, but not variable values
        #   8 for variable values at all iterations
        #   10 for all iterations
        if solver_options:
            for k, v in solver_options.items():
                solver.options[k] = v
        solver.options['OF_mumps_mem_percent'] = '5'  # "OF_" prefix signals to Pyomo to create a temporary options file
        solver.options['OF_output_file'] = outputfile

        if get_suffixes:
            instance.dual = pyo.Suffix(direction=pyo.Suffix.IMPORT)
            instance.ipopt_zL_out = pyo.Suffix(direction=pyo.Suffix.IMPORT)
            instance.ipopt_zU_out = pyo.Suffix(direction=pyo.Suffix.IMPORT)
            setattr(instance, 'lambda', pyo.Suffix(direction=pyo.Suffix.IMPORT))  # use setattr because 'lambda' is reserved keyword

        try:
            results = solver.solve(instance, tee=True, symbolic_solver_labels=True,
                                   keepfiles=False, logfile=logfilename)
        except pyutilib.common._exceptions.ApplicationError:
            traceback.print_exc()
            return None


    else:
        opt = SolverFactory("cbc")
        solver_manager = SolverManagerFactory('neos')

        instance.dual = pyo.Suffix(direction=pyo.Suffix.IMPORT)
        instance.rc = pyo.Suffix(direction=pyo.Suffix.IMPORT)
        instance.dual = pyo.Suffix(direction=pyo.Suffix.IMPORT_EXPORT)
        # self.instance.slack = pyo.Suffix(direction=pyo.Suffix.IMPORT)

        opt.options["display_width"] = 170
        opt.options["display"] = '_varname, _var.rc, _var.lb, _var, _var.ub, _var.slack'
        results = solver_manager.solve(instance, opt=opt, solver=solvername, logfile=logfilename)

        results.write()

    # Wall time - clock stops.
    _endtime_modelsolve = time.time()
    timefor_modelsolve = _endtime_modelsolve - starttime_modelsolve
    logger.info('*solving done* <- it took %f seconds>' % timefor_modelsolve)

    feasible = check_whether_feasible(instance, results)

    return instance, results, feasible
Exemplo n.º 2
0
def optimize_model(model, email, cet, solver=OPT_DEFAULT):
    if not set_neos_email(email):
        if solver is not OPT_DEFAULT:
            assert_solver_available_locally(solver)
        elif cet == CET_ADDI:
            solver = "mosek"
        elif cet == CET_MULT:
            raise ValueError(
                "Please specify the solver for optimizing multiplicative model locally."
            )
        solver_instance = SolverFactory(solver)
        print("Estimating the {} locally with {} solver.".format(
            CET_Model_Categories[cet], solver),
              flush=True)
        return solver_instance.solve(model, tee=True), 1
    else:
        if solver is OPT_DEFAULT and cet is CET_ADDI:
            solver = "mosek"
        elif solver is OPT_DEFAULT and cet == CET_MULT:
            solver = "knitro"
        solver_instance = SolverManagerFactory('neos')
        print("Estimating the {} remotely with {} solver.".format(
            CET_Model_Categories[cet], solver),
              flush=True)
        return solver_instance.solve(model, tee=True, opt=solver), 1
Exemplo n.º 3
0
    def optimize(self, remote=True):
        """Optimize the function by requested method"""
        # TODO(error/warning handling): Check problem status after optimization
        if remote == False:
            if self.cet == "addi":
                solver = SolverFactory("mosek")
                self.problem_status = solver.solve(self.__model__, tee=True)
                self.optimization_status = 1

            elif self.cet == "mult":
                # TODO(warning handling): Use log system instead of print()
                print(
                    "Estimating the multiplicative model will be available in near future."
                )
                return False

        else:
            if self.cet == "addi":
                opt = "mosek"

            elif self.cet == "mult":
                opt = "knitro"

            solver = SolverManagerFactory('neos')
            self.problem_status = solver.solve(self.__model__,
                                               tee=True,
                                               opt=opt)
            self.optimization_status = 1
Exemplo n.º 4
0
    def optimize(self, remote=True):
        """Optimize the function by requested method"""
        # TODO(error/warning handling): Check problem status after optimization
        if not remote:
            if self.cet == "addi":
                solver = SolverFactory("mosek")
                self.problem_status = solver.solve(self.__model__, tee=True)
                self.optimization_status = 1

            elif self.cet == "mult":
                solver = SolverFactory('gams')
                self.problem_status = solver.solve(self.__model__, solver='minos', tee=True)
                self.optimization_status = 1

        else:
            if self.cet == "addi":
                opt = "mosek"

            elif self.cet == "mult":
                opt = "knitro"

            solver = SolverManagerFactory('neos')
            self.problem_status = solver.solve(self.__model__,
                                               tee=True,
                                               opt=opt)
            self.optimization_status = 1
Exemplo n.º 5
0
def solve_ef(master_instance, options):

    with SolverFactory(options.solver_type) as ef_solver:

        with SolverManagerFactory(
                options.solver_manager_type) as ef_solver_manager:
            if ef_solver is None:
                raise ValueError("Failed to create solver manager of type=" +
                                 options.solver_type +
                                 " for use in extensive form solve")
            if len(options.ef_solver_options) > 0:
                print("Initializing ef solver with options=" +
                      str(options.ef_solver_options))
                ef_solver.set_options("".join(options.ef_solver_options))
            if options.ef_mipgap is not None:
                if (options.ef_mipgap < 0.0) or \
                   (options.ef_mipgap > 1.0):
                    raise ValueError("Value of the mipgap parameter for the "
                                     "EF solve must be on the unit interval; "
                                     "value specified=" +
                                     str(options.ef_mipgap))
                else:
                    ef_solver.mipgap = options.ef_mipgap

            solve_kwds = {}
            solve_kwds['load_solutions'] = False
            if options.keep_solver_files:
                solve_kwds['keepfiles'] = True
            if options.symbolic_solver_labels:
                solve_kwds['symbolic_solver_labels'] = True
            if options.output_solver_log:
                solve_kwds['tee'] = True
            if options.write_fixed_variables:
                solve_kwds['output_fixed_variable_bounds'] = True

            if options.verbose:
                print("Solving extensive form.")

            if (not options.disable_warmstarts) and \
               (ef_solver.warm_start_capable()):
                ef_action_handle = ef_solver_manager.queue(master_instance,
                                                           opt=ef_solver,
                                                           warmstart=True,
                                                           **solve_kwds)
            else:
                ef_action_handle = ef_solver_manager.queue(master_instance,
                                                           opt=ef_solver,
                                                           **solve_kwds)
            results = ef_solver_manager.wait_for(ef_action_handle)

            # check the return code - if this is anything but "have a solution", we need to bail.
            if (results.solver.status == SolverStatus.ok) and \
               ((results.solver.termination_condition == TerminationCondition.optimal) or \
                ((len(results.solution) > 0) and (results.solution(0).status == SolutionStatus.optimal))):

                master_instance.solutions.load_from(results)
                return results

    raise RuntimeError("Extensive form was infeasible!")
Exemplo n.º 6
0
 def optimize(self, remote=True):
     """Optimize the function by requested method"""
     if remote == False:
         solver = SolverFactory("mosek")
         print("Estimating the model locally with mosek solver")
         self.problem_status = solver.solve(self.__model__, tee=True)
         self.optimization_status = 1
     else:
         solver = SolverManagerFactory("neos")
         print("Estimating the model remotely with mosek solver")
         self.problem_status = solver.solve(self.__model__,
                                            tee=True,
                                            opt="mosek")
         self.optimization_status = 1
Exemplo n.º 7
0
    def optimize(self, remote=False):
        """Optimize the function by requested method"""
        # TODO(error/warning handling): Check problem status after optimization
        if remote == False:
            print("Estimating the model locally with mosek solver")
            solver = SolverFactory("mosek")
            self.problem_status = solver.solve(self.__model__, tee=True)
            print(self.problem_status)
            self.optimization_status = 1

        else:
            print("Estimating the model remotely with mosek solver")
            solver = SolverManagerFactory('neos')
            self.problem_status = solver.solve(self.__model__,
                                               tee=True,
                                               opt="mosek")
            print(self.problem_status)
            self.optimization_status = 1
Exemplo n.º 8
0
def run(args=None):
###################################

   # to import plugins
   import pyomo.environ
   import pyomo.solvers.plugins.smanager.phpyro

   def LagrangeMorePR(args=None):
      print("lagrangeMorePR begins %s" % datetime_string())
      blanks = "                          "  # used for formatting print statements
      class Object(object): pass
      Result = Object()

# options used
      betaTol       = options.beta_tol          # tolerance used to separate b-values
      IndVarName    = options.indicator_var_name
      multName      = options.lambda_parm_name
      CCStageNum    = options.stage_num
      MaxMorePR     = options.max_number         # max PR points to be generated (above F^* with all delta fixed)
      MaxTime       = options.max_time           # max time before terminate
      csvPrefix = options.csvPrefix          # input filename prefix (eg, case name)
      probFileName  = options.probFileName       # name of file containing probabilities
##HG override
#      options.verbosity = 2
      verbosity     = options.verbosity

      Result.status = 'starting '+datetime_string()
      STARTTIME = time.time()

      ph = PHFromScratch(options)
      rootnode = ph._scenario_tree._stages[0]._tree_nodes[0]   # use rootnode to loop over scenarios

      if find_active_objective(ph._scenario_tree._scenarios[0]._instance,safety_checks=True).is_minimizing():
         print("We are solving a MINIMIZATION problem.")
      else:
         print("We are solving a MAXIMIZATION problem.")

# initialize
      ScenarioList = []
      with open(csvPrefix+"ScenarioList.csv",'r') as inputFile:
         for line in inputFile.readlines():
            L = line.split(',')
            ScenarioList.append([L[0],float(L[1])])

      addstatus = str(len(ScenarioList))+' scenarios read from file: ' + csvPrefix+'ScenarioList.csv'
      if verbosity > 0: print(addstatus)
      Result.status = Result.status + '\n' + addstatus

      PRoptimal = []
      with open(csvPrefix+"PRoptimal.csv",'r') as inputFile:
         for line in inputFile.readlines():
            bzS = line.split(',')
            PRoptimal.append( [None, float(bzS[0]), float(bzS[1])] )

      addstatus = str(len(PRoptimal))+' PR points read from file: '+ csvPrefix+'PRoptimal.csv (envelope function)'
      if verbosity > 0:
         print(addstatus)
      Result.status = Result.status + '\n' + addstatus
# ensure PR points on envelope function are sorted by probability
      PRoptimal.sort(key=operator.itemgetter(1))

      PRoptimal[0][0] = 0   # initial lambda (for b=0)
      for p in range(1,len(PRoptimal)):
         dz = PRoptimal[p][2] - PRoptimal[p-1][2]
         db = PRoptimal[p][1] - PRoptimal[p-1][1]
         PRoptimal[p][0] = dz/db
      if verbosity > 0:
         PrintPRpoints(PRoptimal)
      Result.PRoptimal = PRoptimal

      lambdaval = 0.
      lagrUtil.Set_ParmValue(ph, options.lambda_parm_name,lambdaval)

      # IMPORTANT: Preprocess the scenario instances
      #            before fixing variables, otherwise they
      #            will be preprocessed out of the expressions
      #            and the output_fixed_variable_bounds option
      #            will have no effect when we update the
      #            fixed variable values (and then assume we
      #            do not need to preprocess again because
      #            of this option).
      ph._preprocess_scenario_instances()

## read scenarios to select for each PR point on envelope function
      with open(csvPrefix+"OptimalSelections.csv",'r') as inputFile:
         OptimalSelections = []
         for line in inputFile.readlines():
            if len(line) == 0: break # eof
            selections = line.split(',')
            L = len(selections)
            Ls = len(selections[L-1])
            selections[L-1] = selections[L-1][0:Ls-1]
            if verbosity > 1:
               print(str(selections))
            OptimalSelections.append(selections)

      Result.OptimalSelections = OptimalSelections

      addstatus = str(len(OptimalSelections)) + ' Optimal selections read from file: ' \
            + csvPrefix + 'OptimalSelections.csv'
      Result.status = Result.status + '\n' + addstatus

      if len(OptimalSelections) == len(PRoptimal):
         if verbosity > 0:
            print(addstatus)
      else:
         addstatus = addstatus + '\n** Number of selections not equal to number of PR points'
         print(addstatus)
         Result.status = Result.status + '\n' + addstatus
         print(str(OptimalSelections))
         print((PRoptimal))
         return Result

#####################################################################################

# get probabilities
      if probFileName is None:
# ...generate from widest gap regions
         PRlist = FindPRpoints(options, PRoptimal)
      else:
# ...read probabilities
         probList = []
         with open(probFileName,'r') as inputFile:
            if verbosity > 0:
               print("reading from probList = "+probFileName)
            for line in inputFile.readlines():  # 1 probability per line
               if len(line) == 0:
                  break
               prob = float(line)
               probList.append(prob)

         if verbosity > 0:
            print("\t "+str(len(probList))+" probabilities")
         if verbosity > 1:
            print(str(probList))
         PRlist = GetPoints(options, PRoptimal, probList)
         if verbosity > 1:
            print("PRlist:")
            for interval in PRlist:
               print(str(interval))

# We now have PRlist = [[i, b], ...], where b is in PRoptimal interval (i-1,i)
      addstatus = str(len(PRlist)) + ' probabilities'
      if verbosity > 0:
         print(addstatus)
      Result.status = Result.status + '\n' + addstatus

#####################################################################################

      lapsedTime = time.time() - STARTTIME
      addstatus = 'Initialize complete...lapsed time = ' + str(lapsedTime)
      if verbosity > 1:
         print(addstatus)
      Result.status = Result.status + '\n' + addstatus

#####################################################################################

      if verbosity > 1:
        print("\nlooping over Intervals to generate PR points by flipping heuristic")
      Result.morePR = []
      for interval in PRlist:
         lapsedTime = time.time() - STARTTIME
         if lapsedTime > MaxTime:
            addstatus = '** lapsed time = ' + str(lapsedTime) + ' > max time = ' + str(MaxTime)
            if verbosity > 0: print(addstatus)
            Result.status = Result.status + '\n' + addstatus
            break

         i = interval[0] # = PR point index
         b = interval[1] # = target probability to reach by flipping from upper endpoint
         bU = PRoptimal[i][1]   # = upper endpoint
         bL = PRoptimal[i-1][1] # = lower endpoint
         if verbosity > 1:
            print( "target probability = "+str(b)+" < bU = PRoptimal[" + str(i) + "][1]" \
                 " and > bL = PRoptimal["+str(i-1)+"][1]")
         if b < bL or b > bU:
            addstatus = '** probability = '+str(b) + ', not in gap interval: (' \
                + str(bL) + ', ' + str(bU) + ')'
            print(addstatus)
            print(str(PRoptimal))
            print(str(PRlist))
            Result.status = Result.status + '\n' + addstatus
            return Result

         if verbosity > 1:
            print( "i = "+str(i)+" : Starting with bU = "+str(bU)+" having "+ \
                str(len(OptimalSelections[i]))+ " selections:")
            print(str(OptimalSelections[i]))

# first fix all scenarios = 0
         for sname, sprob in ScenarioList:
            scenario = ph._scenario_tree.get_scenario(sname)
            lagrUtil.FixIndicatorVariableOneScenario(ph,
                                                     scenario,
                                                     IndVarName,
                                                     0)

# now fix optimal selections = 1
         for sname in OptimalSelections[i]:
            scenario = ph._scenario_tree.get_scenario(sname)
            lagrUtil.FixIndicatorVariableOneScenario(ph,
                                                     scenario,
                                                     IndVarName,
                                                     1)

# flip scenario selections from bU until we reach b (target probability)
         bNew = bU
         for sname, sprob in ScenarioList:
            scenario = ph._scenario_tree.get_scenario(sname)
            if bNew - sprob < b:
               continue
            instance = ph._instances[sname]
            if getattr(instance, IndVarName).value == 0:
               continue
            bNew = bNew - sprob
            # flipped scenario selection
            lagrUtil.FixIndicatorVariableOneScenario(ph,
                                                     scenario,
                                                     IndVarName,
                                                     0)
            if verbosity > 1:
               print("\tflipped "+sname+" with prob = "+str(sprob)+" ...bNew = "+str(bNew))

         if verbosity > 1:
            print("\tflipped selections reach "+str(bNew)+" >= target = "+str(b)+" (bL = "+str(bL)+")")
         if bNew <= bL + betaTol or bNew >= bU - betaTol:
            if verbosity > 0:
               print("\tNot generating PR point...flipping from bU failed")
            continue # to next interval in list

 # ready to solve to get cost for fixed scenario selections associated with probability = bNew

         if verbosity > 1:
# check that scenarios are fixed as they should be
            totalprob = 0.
            for scenario in ScenarioList:
               sname = scenario[0]
               sprob = scenario[1]
               instance = ph._instances[sname]
               print("fix "+sname+" = "+str(getattr(instance,IndVarName).value)+\
                  " is "+str(getattr(instance,IndVarName).fixed)+" probability = "+str(sprob))
               if getattr(instance,IndVarName).value == 1:
                  totalprob = totalprob + sprob
               lambdaval = getattr(instance, multName).value
            print("\ttotal probability = %f" % totalprob)

# solve (all delta fixed); lambda=0, so z = Lagrangian
         if verbosity > 0:
            print("solve begins %s" % datetime_string())
            print("\t- lambda = %f" % lambdaval)
         SolStat, z = lagrUtil.solve_ph_code(ph, options)
         b = Compute_ExpectationforVariable(ph, IndVarName, CCStageNum)
         if verbosity > 0:
            print("solve ends %s" % datetime_string())
            print("\t- SolStat = %s" % str(SolStat))
            print("\t- b = %s" % str(b))
            print("\t- z = %s" % str(z))
            print("(adding to more PR points)")

         Result.morePR.append([None,b,z])
         if verbosity > 1:
            PrintPRpoints(Result.morePR)
      ######################################################
      # end loop over target probabilities

      with open(csvPrefix+"PRmore.csv",'w') as outFile:
         for point in Result.morePR:
            outFile.write(str(point[1])+','+str(point[2]))

      addstatus = str(len(Result.morePR)) + ' PR points written to file: '+ csvPrefix + 'PRmore.csv'
      if verbosity > 0: print(addstatus)
      Result.status = Result.status + '\n' + addstatus
      addstatus = 'lapsed time = ' + putcommas(time.time() - STARTTIME)
      if verbosity > 0: print(addstatus)
      Result.status = Result.status + '\n' + addstatus

      return Result
################################
# LagrangeMorePR ends here
################################

#### start run ####

   AllInOne = False
#   VERYSTARTTIME=time.time()
#   print "##############VERYSTARTTIME:",str(VERYSTARTTIME-VERYSTARTTIME)

##########################
# options defined here
##########################
   try:
      conf_options_parser = construct_ph_options_parser("lagrange [options]")
      conf_options_parser.add_argument("--beta-min",
                                     help="The min beta level for the chance constraint. Default is None",
                                     action="store",
                                     dest="beta_min",
                                     type=float,
                                     default=None)
      conf_options_parser.add_argument("--beta-max",
                                     help="The beta level for the chance constraint. Default is None",
                                     action="store",
                                     dest="beta_max",
                                     type=float,
                                     default=None)
      conf_options_parser.add_argument("--min-prob",
                                     help="Tolerance for testing probability > 0. Default is 1e-5",
                                     action="store",
                                     dest="min_prob",
                                     type=float,
                                     default=1e-5)
      conf_options_parser.add_argument("--beta-tol",
                                     help="Tolerance for testing equality to beta. Default is 10^-2",
                                     action="store",
                                     dest="beta_tol",
                                     type=float,
                                     default=1e-2)
      conf_options_parser.add_argument("--Lagrange-gap",
                                     help="The (relative) Lagrangian gap acceptable for the chance constraint. Default is 10^-4.",
                                     action="store",
                                     type=float,
                                     dest="Lagrange_gap",
                                     default=0.0001)
      conf_options_parser.add_argument("--max-number",
                                     help="The max number of PR points. Default = 10.",
                                     action="store",
                                     dest="max_number",
                                     type=int,
                                     default=10)
      conf_options_parser.add_argument("--max-time",
                                     help="Maximum time (seconds). Default is 3600.",
                                     action="store",
                                     dest="max_time",
                                     type=float,
                                     default=3600)
      conf_options_parser.add_argument("--csvPrefix",
                                     help="Input file name prefix.  Default is ''",
                                     action="store",
                                     dest="csvPrefix",
                                     type=str,
                                     default="")
      conf_options_parser.add_argument("--lambda-parm-name",
                                     help="The name of the lambda parameter in the model. Default is lambdaMult",
                                     action="store",
                                     dest="lambda_parm_name",
                                     type=str,
                                     default="lambdaMult")
      conf_options_parser.add_argument("--indicator-var-name",
                                     help="The name of the indicator variable for the chance constraint. The default is delta",
                                     action="store",
                                     dest="indicator_var_name",
                                     type=str,
                                     default="delta")
      conf_options_parser.add_argument("--stage-num",
                                     help="The stage number of the CC indicator variable (number, not name). Default is 2",
                                     action="store",
                                     dest="stage_num",
                                     type=int,
                                     default=2)
      conf_options_parser.add_argument("--verbosity",
                                     help="verbosity=0 is no extra output, =1 is medium, =2 is debug, =3 super-debug. Default is 1.",
                                     action="store",
                                     dest="verbosity",
                                     type=int,
                                     default=1)
      conf_options_parser.add_argument("--prob-file",
                                     help="file name specifiying probabilities",
                                     action="store",
                                     dest="probFileName",
                                     type=str,
                                     default=None)
# The following needed for solve_ph_code in lagrangeutils
      conf_options_parser.add_argument("--solve-with-ph",
                                     help="Perform solves via PH rather than an EF solve. Default is False",
                                     action="store_true",
                                     dest="solve_with_ph",
                                     default=False)

################################################################

      options = conf_options_parser.parse_args(args=args)
      # temporary hack
      options._ef_options = conf_options_parser._ef_options
      options._ef_options.import_argparse(options)
   except SystemExit as _exc:
      # the parser throws a system exit if "-h" is specified - catch
      # it to exit gracefully.
      return _exc.code

   if options.verbose is True:
      print("Loading reference model and scenario tree")

   scenario_instance_factory = \
        ScenarioTreeInstanceFactory(options.model_directory,
                                    options.instance_directory)

   full_scenario_tree = \
            GenerateScenarioTreeForPH(options,
                                      scenario_instance_factory)

   solver_manager = SolverManagerFactory(options.solver_manager_type)
   if solver_manager is None:
      raise ValueError("Failed to create solver manager of "
                       "type="+options.solver_manager_type+
                       " specified in call to PH constructor")
   if isinstance(solver_manager,
                 pyomo.solvers.plugins.smanager.phpyro.SolverManager_PHPyro):
      solver_manager.deactivate()
      raise ValueError("PHPyro can not be used as the solver manager")

   try:

      if (scenario_instance_factory is None) or (full_scenario_tree is None):
         raise RuntimeError("***ERROR: Failed to initialize the model and/or scenario tree data.")

      # load_model gets called again, so lets make sure unarchived directories are used
      options.model_directory = scenario_instance_factory._model_filename
      options.instance_directory = scenario_instance_factory._scenario_tree_filename

      scenario_count = len(full_scenario_tree._stages[-1]._tree_nodes)

      # create ph objects for finding the solution. we do this even if
      # we're solving the extensive form

      if options.verbose is True:
         print("Loading scenario instances and initializing scenario tree for full problem.")

########## Here is where multiplier search is called ############
      Result = LagrangeMorePR()
#####################################################################################
   finally:

      solver_manager.deactivate()
      # delete temporary unarchived directories
      scenario_instance_factory.close()

   print("\n====================  returned from LagrangeMorePR")
   print(str(Result.status))
   try:
     print("Envelope:")
     print(str(PrintPRpoints(Result.PRoptimal)))
     print("\nAdded:")
     PrintPRpoints(Result.morePR)
   except:
     print("from run:  PrintPRpoints failed")
     sys.exit()

# combine tables and sort by probability
   if len(Result.morePR) > 0:
     PRpoints = copy.deepcopy(Result.PRoptimal)
     for lbz in Result.morePR: PRpoints.append(lbz)
     print("Combined table of PR points (sorted):")
     PRpoints.sort(key=operator.itemgetter(1))
     print(str(PrintPRpoints(PRpoints)))
Exemplo n.º 9
0
    def solve_model(self, model):
        """
        Method to solve an optimization model using a specified solver
        Returns:
            :dict - solver statistics and model solution
        """

        # Set a few default values
        attr_to_check = [
            'solver_name', 'neos', 'write_solution', 'return_solution',
            'verbosity', 'solver_progress'
        ]
        for attr in attr_to_check:
            self.__chkattrt(attr)

        # Get model name
        model_name = model.name
        self.__model_name_str = str(re.sub(" ", "_", model_name))

        # Solver name to lower case characters
        self.solver_name = self.solver_name.lower()

        # Confirm solver paths and thus availability
        self.__solvers_path_check()

        # NEOS vs local solvers: check solvers are recognised/available
        self.__solvers_compatibility_check()  # Run solvers check

        # Call solver factory
        opt_solver = SolverFactory(self.solver_name)

        # Change solver temporary folder path
        log_folder = path.join('_log', '')
        if self.solver_name in ['gurobi', 'baron', 'cplex']:
            if not path.exists(log_folder):
                makedirs(log_folder)
            self.__set_tempdir(log_folder)
        else:
            pass

        # Include solver-compatible options
        if self.solver_name in ['cplex', 'gurobi']:
            opt_solver.options['threads'] = self.threads
            opt_solver.options['mipgap'] = self.rel_gap
            opt_solver.options['timelimit'] = self.time_limit
        elif self.solver_name in ['baron']:
            opt_solver.options['threads'] = self.threads
            opt_solver.options['LPSol'] = 3
            opt_solver.options['EpsR'] = self.rel_gap
            opt_solver.options['MaxTime'] = self.time_limit
            # For Unix systems ensure "libcplexxxxx.dylib" is in the system PATH for baron to use CPLEX for MIPs
        elif self.solver_name in ['cbc']:
            opt_solver.options['threads'] = self.threads
            opt_solver.options['ratio'] = self.rel_gap
            opt_solver.options['seconds'] = self.time_limit
            opt_solver.options['log'] = int(self.solver_progress) * 2
            opt_solver.options['mess'] = 'on'
            opt_solver.options['timeM'] = "elapsed"
            opt_solver.options['preprocess'] = "equal"
        elif self.solver_name in ['glpk']:
            opt_solver.options['mipgap'] = self.rel_gap
            opt_solver.options['tmlim'] = self.time_limit
        elif self.solver_name in ['ipopt']:
            opt_solver.options['max_wall_time'] = self.time_limit
        elif self.solver_name in ['bonmin']:
            opt_solver.options['time_limit'] = self.time_limit
            opt_solver.options['number_cpx_threads'] = self.threads
            opt_solver.options['allowable_fraction_gap'] = self.rel_gap
        elif self.solver_name in ['couenne']:
            opt_solver.options['time_limit'] = self.time_limit
            opt_solver.options['threads'] = self.threads
            opt_solver.options['ratio'] = self.rel_gap
            opt_solver.options['seconds'] = self.time_limit
            opt_solver.options['log'] = int(self.solver_progress) * 2
            opt_solver.options['mess'] = 'on'
            opt_solver.options['timeM'] = "elapsed"
            opt_solver.options['preprocess'] = "equal"
        else:
            pass

        # Write log to file named <model_name>/DD_MM_YY_HH_MM_xx.log
        # Create (if it does not exist) the '_log' folder
        log_store_folder = path.join(log_folder, self.__model_name_str, '')
        if not path.exists(log_store_folder):
            makedirs(log_store_folder)

        self.__current_datetime_str = datetime.now().strftime(
            "%d_%m_%y_%H_%M_")
        file_suffix = 0
        # Results filename
        if self.__model_name_str == 'Unknown' or len(
                self.__model_name_str) <= 10:
            log_filename = self.__model_name_str + self.__current_datetime_str + str(
                file_suffix) + ".log"
        else:
            log_filename = self.__model_name_str[:4] + '..' + self.__model_name_str[-4:] + \
                           self.__current_datetime_str + str(file_suffix) + ".log"
        while path.exists(log_store_folder + log_filename):
            file_suffix += 1
            log_filename = self.__current_datetime_str + str(
                file_suffix) + ".log"
        log_filename = self.__current_datetime_str + str(file_suffix) + ".log"

        # Solve <model> with/without writing final solution to stdout
        processed_results = None
        self.__page_borders()  # Headers for page
        try:
            if self.neos:
                self.solver_results = SolverManagerFactory('neos').solve(
                    model, opt=opt_solver, tee=self.solver_progress)
            else:
                self.solver_results = opt_solver.solve(
                    model,
                    tee=self.solver_progress,
                    logfile=log_store_folder + log_filename)

            # Process results obtained
            if self.neos:
                self.__msg(
                    "Currently, results are not post-processed for NEOS server runs"
                )  #FIXME Find a work around
            else:
                processed_results = self._process_solver_results(model)
        except ValueError:
            self.__psmsg("Something went wrong with the solver")

        # Return model solution and solver statistics
        self.final_results = processed_results

        self.__page_borders(bottom=True)  # Footer for page
Exemplo n.º 10
0
class SolverWrapper:
    class __SolversInfo:
        """
        Default info for solvers
        """
        def __init__(self):
            self.configured_solvers = {
                # solver_name: ['windows executable', 'unix executable', 'solver_io']
                'cbc': ['cbc', 'cbc', 'lp'],
                'cplex': ['cplex', 'cplex', 'lp'],
                'glpk': ['glpk', 'glpk', 'lp'],
                'gurobi': ['gurobi', 'gurobi.sh',
                           'python'],  # Configure gurobi to use python api?
                'baron': ['baron', 'baron', 'nl'],
                'ipopt': ['ipopt', 'ipopt', 'lp'],
                'couenne': ['couenne', 'couenne', 'nl'],
                'bonmin': ['bonmin', 'bonmin', 'nl']
            }
            self.neos_compatible = [
                'bonmin', 'cbc', 'conopt', 'couenne', 'cplex', 'filmint',
                'filter', 'ipopt', 'knitro', 'l-bfgs-b', 'lancelot', 'lgo',
                'loqo', 'minlp', 'minos', 'minto', 'mosek', 'ooqp', 'path',
                'raposa', 'snopt'
            ]

    class __Constants:
        """
        Default constants for use throughout the class
        """
        def __init__(self):
            self.var_defaults = {
                'solver_name': 'gurobi',
                'solver_path': False,
                'time_limit': 1200,
                'threads': 2,
                'neos': False,
                'verbosity': False,
                'debug_mode': False,
                'solver_progress': True,
                'write_solution': True,
                'write_solution_to_stdout': True,
                'return_solution': True,
                'rel_gap': 0.0,
                'result_precision': 6
            }
            self.var_types = {
                'time_limit': [int, float],
                'threads': [int],
                'neos': [bool],
                'verbosity': [bool],
                'debug_mode': [bool],
                'solver_progress': [bool],
                'write_solution': [bool],
                'write_solution_to_stdout': [bool],
                'return_solution': [bool],
                'rel_gap': [int, float],
                'result_precision': [int]
            }
            self.os_name = platform.system()

    def __init__(self,
                 solver_name=None,
                 solver_path=None,
                 time_limit=None,
                 threads=None,
                 neos=None,
                 verbosity=None,
                 debug_mode=None,
                 solver_progress=None,
                 write_solution=None,
                 write_solution_to_stdout=None,
                 return_solution=None,
                 rel_gap=None,
                 result_precision=None,
                 neos_registered_email=None):
        # Set methods defaults
        self.solver_info = self.__SolversInfo()
        self.constants = self.__Constants()
        self.solver_name = self.__apattr(
            solver_name, self.constants.var_defaults['solver_name'])
        self.solver_path = self.__apattr(
            solver_path, self.constants.var_defaults['solver_path'])

        # Set solver defaults
        self.time_limit = self.__apattr(
            time_limit, self.constants.var_defaults['time_limit'])
        self.threads = self.__apattr(threads,
                                     self.constants.var_defaults['threads'])
        self.neos = self.__apattr(neos, self.constants.var_defaults['neos'])
        self.verbosity = self.__apattr(
            verbosity, self.constants.var_defaults['verbosity'])
        self.debug_mode = self.__apattr(
            debug_mode, self.constants.var_defaults['debug_mode'])
        self.verbose_debug_mode = False
        self.solver_progress = self.__apattr(
            solver_progress, self.constants.var_defaults['solver_progress'])
        self.write_solution = self.__apattr(
            write_solution, self.constants.var_defaults['write_solution'])
        self.write_solution_to_stdout = self.__apattr(
            write_solution_to_stdout,
            self.constants.var_defaults['write_solution_to_stdout'])
        self.return_solution = self.__apattr(
            return_solution, self.constants.var_defaults['return_solution'])
        self.rel_gap = self.__apattr(rel_gap,
                                     self.constants.var_defaults['rel_gap'])
        self.result_precision = self.__apattr(
            result_precision, self.constants.var_defaults['result_precision'])

        # Set other defaults
        self.__model_name_str = None
        self.__current_datetime_str = None
        self.__pyomo_version = pyoversion.version
        self.__pyutilib_version = self.__get_pkg_version("PyUtilib")
        self.__dependency_check_count = 1
        self.__dependency_check = self.__pyutilib_dependency_check()
        self.__DEF_registered_email = "*****@*****.**"
        self.__DEF_REGEX = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b'
        self.neos_registered_email = neos_registered_email
        self.neos_registered_email = self.__sg_neos_registered_email(
            defaults=False)

    def __sg_neos_registered_email(self, defaults=True):
        if self.neos_registered_email is None:
            if defaults:
                self.__msg(
                    "NB: An email address can be passed to 'neos_registered_email' instead of using defaults."
                )
            self.neos_registered_email = self.__DEF_registered_email
            return self.neos_registered_email
        else:
            if re.match(self.__DEF_REGEX, self.neos_registered_email):
                return self.neos_registered_email
            else:
                self.__msg(
                    "An invalid email address was passed. Resorting to default..."
                )
                self.neos_registered_email = None
                self.__sg_neos_registered_email(
                    defaults=False
                )  # Tiny way to avoid repeated warnings to users
                return self.neos_registered_email

    def __apattr(self, attrib, value):
        """
        Set value to an attrib
        :param attrib:
        :param value:
        :return: None
        """
        if attrib is None:
            return value
        else:
            return attrib

    def __chkattrt(self, attrib):
        """
        Check type of attrib against requirement and set to default else
        :param attrib:
        :return: None
        """

        # Get attrib name as string
        c_var_list = [vars for vars in locals().keys() if "_" not in vars[:2]]

        attrib_str = None
        for var_l in c_var_list:
            if id(attrib) == id(var_l):
                attrib_str = var_l
                break
            else:
                pass

        if attrib_str is not None and attrib_str in self.constants.var_types.keys(
        ):
            if type(attrib) in self.constants.var_types[attrib_str]:
                pass
            else:
                self.__psmsg(
                    'Value given to ' + attrib_str + ' is invalid',
                    'The following value types are acceptable: ' +
                    str(self.constants.var_types[attrib_str]))
                self.__psmsg('Setting default value. . .')
                setattr(self, attrib_str,
                        self.constants.var_defaults[attrib_str])
        else:
            pass

    def __msg(self, *msg, text_indent=4):
        text_indent = " " * int(text_indent)
        # Text wrapper function
        wrapper = textwrap.TextWrapper(width=60,
                                       initial_indent=text_indent,
                                       subsequent_indent=text_indent)
        # Print message
        print("\n")
        for message in msg:
            message = wrapper.wrap(text=str(message))
            for element in message:
                print(element)
        return text_indent

    def __pemsg(self, *msg, exit=True):
        """
        Custom error messages to print to stdout and stop execution
        :param message: Error message to be printed
        """

        if self.debug_mode:
            exit = self.debug_mode
        else:
            exit = exit

        text_indent = self.__msg(*msg, text_indent=4)

        if exit:  # Stop run
            print(text_indent + "Exiting . . .")
            sys.exit(1)
        else:
            pass

    def __psmsg(self, *msg):
        """
        Custom status messages to print to stdout and stop execution
        :param message: Error message to be printed
        """
        if self.verbosity:
            self.__msg("INFO:", *msg, text_indent=1)
        else:
            pass

    def __page_borders(self, bottom=False):
        if self.verbosity:
            if bottom:
                self.__msg("- - " * 15, "\n", text_indent=0)
            else:
                self.__msg("- - " * 15, text_indent=0)
        else:
            pass

    def __run_ext_command(self, cmd=[" "]):
        return subprocess.Popen(cmd, stdout=subprocess.PIPE).communicate()[0]

    def __get_solver_path(self, solver_exct):
        if self.constants.os_name == 'Windows':
            path = self.__run_ext_command(['where',
                                           solver_exct]).decode('utf-8')
        else:
            path = self.__run_ext_command(['which',
                                           solver_exct]).decode('utf-8')

        if path != '':
            return path, True
        else:
            return None, False

    def __get_pkg_version(self, pkg):
        parent_cmd = subprocess.Popen(['pip', 'freeze'],
                                      stdout=subprocess.PIPE)
        if self.constants.os_name == 'Windows':
            value = subprocess.check_output(
                ['findstr', str(pkg)], stdin=parent_cmd.stdout).decode('utf-8')
        else:
            value = subprocess.check_output(
                ['grep', str(pkg)], stdin=parent_cmd.stdout).decode('utf-8')

        if value == '':
            return value
        elif len(value) > len(pkg):
            value = value[len(pkg) + 2:]
            return value
        else:
            return None

    def __pyutilib_dependency_check(self):
        if self.__dependency_check_count <= 3:
            if self.__pyomo_version == '5.6.8':
                if '5.7.3' not in self.__pyutilib_version:
                    system('pip install pyutilib==5.7.3')
                    self.__pyutilib_version = self.__get_pkg_version(
                        "PyUtilib")
                    self.__dependency_check_count += 1
                    self.__pyutilib_dependency_check()
                else:
                    self.__dependency_check = True
            elif self.__pyomo_version == '5.6.9':
                if '5.8.0' not in self.__pyutilib_version:
                    system('pip install pyutilib==5.8.0')
                    self.__pyutilib_version = self.__get_pkg_version(
                        "PyUtilib")
                    self.__dependency_check_count += 1
                    self.__pyutilib_dependency_check()
                else:
                    self.__dependency_check = True
            elif self.__pyomo_version > '5.6.9':
                if '6.0.0' not in self.__pyutilib_version:
                    system('pip install pyutilib==6.0.0')
                    self.__pyutilib_version = self.__get_pkg_version(
                        "PyUtilib")
                    self.__dependency_check_count += 1
                    self.__pyutilib_dependency_check()
                else:
                    self.__dependency_check = True
        else:
            self.__pemsg(
                "The right version of pyutilib could not be installed.")

    def __set_tempdir(self, folder):
        """
        Set temporary solver folder
        :param folder: path to folder
        :return:
        """
        if self.__pyomo_version <= '5.7.1':
            from pyutilib.services import TempfileManager
            TempfileManager.tempdir = folder
        else:
            from pyomo.common.tempfiles import TempfileManager
            TempfileManager.tempdir = folder

    def __get_set_list(self, pyo_obj):
        if self.__pyomo_version < '5.7.0'[:len(self.__pyomo_version)]:
            return [set for set in pyo_obj._index.set_tuple]
        else:
            return [set.name for set in pyo_obj._index.subsets()]

    def __get_set_list_alt(self, pyo_obj):
        if self.__pyomo_version < '5.7.0'[:len(self.__pyomo_version)]:
            return [set for set in pyo_obj.domain.set_tuple]
        else:
            return [set.name for set in pyo_obj.domain.subsets()]

    def __solvers_compatibility_check(self):
        """
        NEOS vs local solvers: Check solvers are recognised/available
        :return:
        """
        if self.neos:  # using NEOS
            if self.solver_name not in self.solver_info.neos_compatible:
                self.__pemsg(
                    "NEOS server does not seem to be configure for " +
                    str(self.solver_name),
                    "If you must used this solver, install a local version and set option 'neos' to 'False'",
                    exit=False)
                self.__pemsg("Attempting to use a local solver instance . . .",
                             exit=False)
                self.neos = False
                self.__solvers_path_check()
                self.__solvers_compatibility_check()
            else:
                environ['NEOS_EMAIL'] = self.__sg_neos_registered_email()
                if self.verbosity:
                    self.__psmsg("Using NEOS server to solve model . . .")
                else:
                    pass
        else:  # using a locally installed solver
            if self.solver_name not in self.solver_info.configured_solvers.keys(
            ):
                self.__pemsg(
                    self.solver_name +
                    " is not amongst those currently configured by this package"
                )
            elif not self.solver_avail:
                if self.solver_path is False:
                    self.__pemsg(self.solver_name +
                                 " is not installed or at the path specified")
                else:
                    self.solver_path = False
                    self.__solvers_path_check()
                    self.__solvers_compatibility_check()
            else:
                if self.verbosity:
                    self.__psmsg("Solver located in {}".format(
                        self.solver_path))
                else:
                    pass

    def __solvers_path_check(self):
        """
        # Confirm solver paths and thus availability
        :return:
        """
        if not self.neos:
            if self.solver_path is False:
                if self.constants.os_name == 'Windows':
                    self.solver_path, self.solver_avail = \
                        self.__get_solver_path(self.solver_info.configured_solvers[self.solver_name][0])
                else:
                    self.solver_path, self.solver_avail = \
                        self.__get_solver_path(self.solver_info.configured_solvers[self.solver_name][1])
            else:
                self.solver_avail = path.exists(self.solver_path)
        else:
            self.solver_avail = False

    def solve_model(self, model):
        """
        Method to solve an optimization model using a specified solver
        Returns:
            :dict - solver statistics and model solution
        """

        # Set a few default values
        attr_to_check = [
            'solver_name', 'neos', 'write_solution', 'return_solution',
            'verbosity', 'solver_progress'
        ]
        for attr in attr_to_check:
            self.__chkattrt(attr)

        # Get model name
        model_name = model.name
        self.__model_name_str = str(re.sub(" ", "_", model_name))

        # Solver name to lower case characters
        self.solver_name = self.solver_name.lower()

        # Confirm solver paths and thus availability
        self.__solvers_path_check()

        # NEOS vs local solvers: check solvers are recognised/available
        self.__solvers_compatibility_check()  # Run solvers check

        # Call solver factory
        opt_solver = SolverFactory(self.solver_name)

        # Change solver temporary folder path
        log_folder = path.join('_log', '')
        if self.solver_name in ['gurobi', 'baron', 'cplex']:
            if not path.exists(log_folder):
                makedirs(log_folder)
            self.__set_tempdir(log_folder)
        else:
            pass

        # Include solver-compatible options
        if self.solver_name in ['cplex', 'gurobi']:
            opt_solver.options['threads'] = self.threads
            opt_solver.options['mipgap'] = self.rel_gap
            opt_solver.options['timelimit'] = self.time_limit
        elif self.solver_name in ['baron']:
            opt_solver.options['threads'] = self.threads
            opt_solver.options['LPSol'] = 3
            opt_solver.options['EpsR'] = self.rel_gap
            opt_solver.options['MaxTime'] = self.time_limit
            # For Unix systems ensure "libcplexxxxx.dylib" is in the system PATH for baron to use CPLEX for MIPs
        elif self.solver_name in ['cbc']:
            opt_solver.options['threads'] = self.threads
            opt_solver.options['ratio'] = self.rel_gap
            opt_solver.options['seconds'] = self.time_limit
            opt_solver.options['log'] = int(self.solver_progress) * 2
            opt_solver.options['mess'] = 'on'
            opt_solver.options['timeM'] = "elapsed"
            opt_solver.options['preprocess'] = "equal"
        elif self.solver_name in ['glpk']:
            opt_solver.options['mipgap'] = self.rel_gap
            opt_solver.options['tmlim'] = self.time_limit
        elif self.solver_name in ['ipopt']:
            opt_solver.options['max_wall_time'] = self.time_limit
        elif self.solver_name in ['bonmin']:
            opt_solver.options['time_limit'] = self.time_limit
            opt_solver.options['number_cpx_threads'] = self.threads
            opt_solver.options['allowable_fraction_gap'] = self.rel_gap
        elif self.solver_name in ['couenne']:
            opt_solver.options['time_limit'] = self.time_limit
            opt_solver.options['threads'] = self.threads
            opt_solver.options['ratio'] = self.rel_gap
            opt_solver.options['seconds'] = self.time_limit
            opt_solver.options['log'] = int(self.solver_progress) * 2
            opt_solver.options['mess'] = 'on'
            opt_solver.options['timeM'] = "elapsed"
            opt_solver.options['preprocess'] = "equal"
        else:
            pass

        # Write log to file named <model_name>/DD_MM_YY_HH_MM_xx.log
        # Create (if it does not exist) the '_log' folder
        log_store_folder = path.join(log_folder, self.__model_name_str, '')
        if not path.exists(log_store_folder):
            makedirs(log_store_folder)

        self.__current_datetime_str = datetime.now().strftime(
            "%d_%m_%y_%H_%M_")
        file_suffix = 0
        # Results filename
        if self.__model_name_str == 'Unknown' or len(
                self.__model_name_str) <= 10:
            log_filename = self.__model_name_str + self.__current_datetime_str + str(
                file_suffix) + ".log"
        else:
            log_filename = self.__model_name_str[:4] + '..' + self.__model_name_str[-4:] + \
                           self.__current_datetime_str + str(file_suffix) + ".log"
        while path.exists(log_store_folder + log_filename):
            file_suffix += 1
            log_filename = self.__current_datetime_str + str(
                file_suffix) + ".log"
        log_filename = self.__current_datetime_str + str(file_suffix) + ".log"

        # Solve <model> with/without writing final solution to stdout
        processed_results = None
        self.__page_borders()  # Headers for page
        try:
            if self.neos:
                self.solver_results = SolverManagerFactory('neos').solve(
                    model, opt=opt_solver, tee=self.solver_progress)
            else:
                self.solver_results = opt_solver.solve(
                    model,
                    tee=self.solver_progress,
                    logfile=log_store_folder + log_filename)

            # Process results obtained
            if self.neos:
                self.__msg(
                    "Currently, results are not post-processed for NEOS server runs"
                )  #FIXME Find a work around
            else:
                processed_results = self._process_solver_results(model)
        except ValueError:
            self.__psmsg("Something went wrong with the solver")

        # Return model solution and solver statistics
        self.final_results = processed_results

        self.__page_borders(bottom=True)  # Footer for page

    # Method for post processing solver results
    def _process_solver_results(self, model):
        """
        Method to post process results from 'solve_model' method
        :param model: solved model
        :return: dictionary of solver results
        """

        from pyomo.environ import Set, RealSet, RangeSet, Param, Var

        # Write solution to stdout/file
        if self.write_solution and (
                str(self.solver_results.solver.Status) in ['ok']
                or str(self.solver_results.solver.Termination_condition)
                in ['maxTimeLimit']):

            if self.write_solution_to_stdout:
                # Write solution to screen
                self.solver_results.write()
            else:
                pass

            # Write solution to file named <model_name>/DD_MM_YY_HH_MM_xx.json
            # Create (if it does not exist) the '_results_store' folder
            results_store_folder = path.join('_results_store',
                                             self.__model_name_str, '')
            if not path.exists(results_store_folder):
                makedirs(results_store_folder)

            if self.__pyomo_version <= '5.7.1':
                model.solutions.store_to(
                    self.solver_results)  # define solutions storage folder
            else:
                pass
            self.__current_datetime_str = datetime.now().strftime(
                "%d_%m_%y_%H_%M_")
            file_suffix = 0
            # Results filename
            if self.__model_name_str == 'Unknown' or len(
                    self.__model_name_str) <= 10:
                result_filename = self.__model_name_str + self.__current_datetime_str + str(
                    file_suffix) + ".json"
            else:
                result_filename = self.__model_name_str[:4] + '..' + self.__model_name_str[-4:] + \
                                  self.__current_datetime_str + str(file_suffix) + ".json"
            while path.exists(results_store_folder + result_filename):
                file_suffix += 1
                result_filename = self.__current_datetime_str + str(
                    file_suffix) + ".json"
            result_filename = self.__current_datetime_str + str(
                file_suffix) + ".json"
            self.solver_results.write(filename=results_store_folder +
                                      result_filename,
                                      format="json")
        else:
            pass

        # Create dictionary to for solver statistics and solution
        final_result = dict()
        # Include the default solver results from opt_solver.solve & current state of model
        final_result['solver_results_def'] = self.solver_results
        final_result[
            'model'] = model  # copy.deepcopy(model)   # include all model attributes

        # _include solver statistics
        acceptable_termination_conditions = [
            'maxTimeLimit', 'maxIterations', 'locallyOptimal',
            'globallyOptimal', 'optimal', 'other'
        ]
        if str(self.solver_results.solver.Status) == 'ok' or (
                str(self.solver_results.solver.Status) == 'aborted'
                and str(self.solver_results.solver.Termination_condition)
                in acceptable_termination_conditions):
            final_result['solver'] = dict(
            )  # Create dictionary for solver statistics
            final_result['solver'] = {
                'status':
                str(self.solver_results.solver.Status),
                'solver_message':
                str(self.solver_results.solver.Message),
                'termination_condition':
                str(self.solver_results.solver.Termination_condition)
            }
            try:
                final_result['solver'][
                    'wall_time'] = self.solver_results.solver.wall_time
            except AttributeError:
                final_result['solver']['wall_time'] = None

            try:
                final_result['solver'][
                    'wall_time'] = self.solver_results.solver.wall_time
            except AttributeError:
                final_result['solver']['wall_time'] = None

            try:
                final_result['solver'][
                    'cpu_time'] = self.solver_results.solver.time
            except AttributeError:
                final_result['solver']['cpu_time'] = None

            try:
                if self.solver_results.problem.Upper_bound == 0 and self.solver_results.problem.Lower_bound == 0:
                    final_result['solver']['gap'] = 0
                elif self.solver_results.problem.Upper_bound == 0:
                    final_result['solver']['gap'] = abs(
                        round(self.solver_results.problem.Lower_bound, 2))
                else:
                    final_result['solver']['gap'] = abs(round(
                        (self.solver_results.problem.Upper_bound - self.solver_results.problem.Lower_bound) \
                        * 100 / self.solver_results.problem.Upper_bound, 2))
            except AttributeError:
                final_result['solver']['gap'] = None

            # Check state of available solution
            if self.__pyomo_version < '5.7.1':
                try:
                    for key, value in final_result['solver_results_def'][
                            'Solution'][0]['Objective'].items():
                        objective_value = value['Value']
                    final_result['solution_status'] = True
                except:
                    final_result['solution_status'] = False
                    objective_value = 'Unk'
            else:
                try:
                    objective_value = model.solutions.solutions[0]._entry[
                        'objective'][list(
                            model.solutions.solutions[0]._entry['objective'].
                            keys())[0]][1]['Value']
                    final_result['solution_status'] = True
                except:
                    final_result['solution_status'] = False
                    objective_value = 'Unk'

            if self.return_solution and final_result['solution_status']:
                # True: include values of all model objects in 'final_result'
                # write list of sets, parameters and variables
                final_result['sets_list'] = [
                    str(i) for i in chain(model.component_objects(Set),
                                          model.component_objects(RealSet),
                                          model.component_objects(RangeSet))
                    if (re.split("_", str(i))[-1] != 'index')
                    if (re.split("_", str(i))[-1] != 'domain')
                ]
                final_result['parameters_list'] = [
                    str(i) for i in model.component_objects(Param)
                ]
                final_result['variables_list'] = [
                    str(i) for i in model.component_objects(Var)
                ]

                # Populate final results for sets, parameters and variables
                # Create method to return array
                def indexed_value_extract(index, object):
                    return array([value for value in object[index].value])

                # Sets
                final_result['sets'] = dict()
                for set in final_result['sets_list']:
                    set_object = getattr(model, str(set))
                    final_result['sets'][set] = array(
                        list(set_object))  # save array of set elements

                # Parameters
                final_result['parameters'] = dict()
                if self.verbosity:
                    print('\nProcessing parameters . . . ')
                else:
                    pass
                for par in final_result['parameters_list']:
                    if self.verbosity:
                        print(par, ' ', end="")
                    else:
                        pass
                    par_object = getattr(model, str(par))
                    par_object_dim = par_object.dim(
                    )  # get dimension of parameter
                    if par_object_dim == 0:
                        final_result['parameters'][par] = par_object.value
                    elif par_object_dim == 1:
                        final_result['parameters'][par] = array(
                            [value for value in par_object.values()])
                    else:
                        try:
                            par_set_list = self.__get_set_list(par_object)
                            par_set_lens = [
                                len(getattr(model, str(set)))
                                for set in par_set_list
                            ]
                        except AttributeError:
                            par_set_list = [str(par_object._index.name)]
                            temp_par_set = getattr(model, par_set_list[0])
                            if temp_par_set.dimen == 1:
                                par_set_lens = [len(temp_par_set)]
                            else:
                                par_set_lens = [
                                    len(set) for set in
                                    self.__get_set_list_alt(temp_par_set)
                                ]

                        # print(par_set_lens)
                        final_result['parameters'][par] = zeros(
                            shape=par_set_lens, dtype=float)
                        if par_object_dim == 2:
                            if len(par_set_list) == par_object_dim:
                                for ind_i, i in enumerate(
                                        getattr(model, str(par_set_list[0]))):
                                    for ind_j, j in enumerate(
                                            getattr(model,
                                                    str(par_set_list[1]))):
                                        final_result['parameters'][par][ind_i][
                                            ind_j] = par_object[i, j]
                            elif len(par_set_list) == 1:
                                for set in par_set_list:
                                    for ind, (i, j) in enumerate(
                                            getattr(model, str(set))):
                                        # print(type(final_result['parameters'][par]),final_result['parameters'][par])
                                        # print(i,j,final_result['parameters'][par][i-1][j-1])
                                        # print(par_set_lens)
                                        # print(par_set_list)
                                        # print(par_object_dim)
                                        if self.__pyomo_version < '5.7':  # FIXME: Better way to do this?
                                            final_result['parameters'][par][
                                                i - 1][j - 1] = par_object[i,
                                                                           j]
                                        else:
                                            final_result['parameters'][par][
                                                ind] = par_object[i, j]
                            else:
                                pass

                        else:
                            pass  # FIXME 3-dimensional variables are not considered yet

                # Variables
                final_result['variables'] = dict()
                # Include objective functionv value
                final_result['variables']['Objective'] = objective_value
                if self.verbosity:
                    print('\nProcessing results of variables . . . ')
                else:
                    pass
                for variable in final_result['variables_list']:
                    try:
                        if self.verbosity:
                            print(variable, ' ', end="")
                        else:
                            pass
                        variable_object = getattr(model, str(variable))
                        variable_object_dim = variable_object.dim(
                        )  # get dimension of variable
                        if variable_object_dim == 0:
                            final_result['variables'][
                                variable] = variable_object.value
                        elif variable_object_dim == 1:
                            final_result['variables'][variable] = array([
                                value.value
                                for value in variable_object.values()
                            ])
                        else:
                            try:
                                variable_set_list = self.__get_set_list(
                                    variable_object)
                                variable_set_lens = [
                                    len(getattr(model, str(set)))
                                    for set in variable_set_list
                                ]
                            except AttributeError:
                                variable_set_list = [
                                    str(variable_object._index.name)
                                ]
                                temp_variable_set = getattr(
                                    model, variable_set_list[0])
                                if temp_variable_set.dimen == 1:
                                    variable_set_lens = [
                                        len(temp_variable_set)
                                    ]
                                else:
                                    variable_set_lens = [
                                        len(set)
                                        for set in self.__get_set_list_alt(
                                            temp_variable_set)
                                    ]

                            # print(variable_set_lens)
                            final_result['variables'][variable] = zeros(
                                shape=variable_set_lens, dtype=float)
                            if variable_object_dim == 2:
                                if len(variable_set_list
                                       ) == variable_object_dim:
                                    for ind_i, i in enumerate(
                                            getattr(
                                                model,
                                                str(variable_set_list[0]))):
                                        for ind_j, j in enumerate(
                                                getattr(
                                                    model,
                                                    str(variable_set_list[1]))
                                        ):
                                            final_result['variables'][
                                                variable][ind_i][
                                                    ind_j] = variable_object[
                                                        i, j].value
                                elif len(variable_set_list) == 1:
                                    for set in variable_set_list:
                                        for ind, (i, j) in enumerate(
                                                getattr(model, str(set))):
                                            # print(type(final_result['variables'][variable]),final_result['variables'][variable])
                                            # print(i,j,final_result['variables'][variable][i-1][j-1])
                                            if self.__pyomo_version < '5.7':  # FIXME: Better way to do this?
                                                final_result['variables'][
                                                    variable][i - 1][
                                                        j -
                                                        1] = variable_object[
                                                            i, j].value
                                            else:
                                                final_result['variables'][
                                                    variable][
                                                        ind] = variable_object[
                                                            i, j].value
                                else:
                                    pass

                            else:
                                pass  # FIXME 3-dimensional variables are not considered yet

                    except AttributeError:
                        pass

                print('\n')

            else:  # if solver_status != 'ok' or amongst acceptable termination conditions
                if self.debug_mode:
                    if self.verbose_debug_mode:  # Print troublesome constraints
                        from pyomo.util.infeasible import log_infeasible_constraints
                        log_infeasible_constraints(model)
                    else:
                        pass
                    self.__psmsg('An optimal solution could not be processed'
                                 )  # leave program running to debug
                else:
                    self.__pemsg('An optimal solution could not be processed')

        else:  # if solver_status != ok
            self.__pemsg('An optimal solution was NOT found')

        return final_result
Exemplo n.º 11
0
from pyomo.core import *
from pyomo.opt import SolverFactory, SolverManagerFactory

from DiseaseEstimation import model

# create the instance
instance = model.create('DiseaseEstimation.dat')

# define the solver and its options
solver = 'ipopt'
opt = SolverFactory( solver )
if opt is None:
    raise ValueError, "Problem constructing solver `"+str(solver)
opt.set_options('max_iter=2')

# create the solver manager
solver_manager = SolverManagerFactory( 'serial' )

# solve
results = solver_manager.solve(instance, opt=opt, tee=True, timelimit=None)
instance.load(results)

# display results
display(instance)
Exemplo n.º 12
0
def run(args=None):
    ##########################================================#########
    # to import plugins
    import pyomo.environ
    import pysp.pyro.smanager_pyro
    import pysp.plugins.phpyro

    def partialLagrangeParametric(args=None):
        print("lagrangeParam begins ")
        blanks = "                          "  # used for formatting print statements

        class Object(object):
            pass

        Result = Object()

        # options used
        IndVarName = options.indicator_var_name
        CCStageNum = options.stage_num
        alphaTol = options.alpha_tol
        MaxMorePR = options.MaxMorePR  # option to include up to this many PR points above F^* with all delta fixed
        outputFilePrefix = options.outputFilePrefix

        # We write ScenarioList = name, probability
        #          PRoptimal    = probability, min-cost, [selections]
        #          PRmore       = probability, min-cost, [selections]
        # ================ sorted by probability ========================
        #
        # These can be read to avoid re-computing points

        ph = PHFromScratch(options)
        Result.ph = ph
        rootnode = ph._scenario_tree._stages[0]._tree_nodes[
            0]  # use rootnode to loop over scenarios

        if find_active_objective(ph._scenario_tree._scenarios[0]._instance,
                                 safety_checks=True).is_minimizing():
            print("We are solving a MINIMIZATION problem.\n")
        else:
            print("We are solving a MAXIMIZATION problem.\n")

# initialize
        ScenarioList = []
        lambdaval = 0.
        lagrUtil.Set_ParmValue(ph, options.lambda_parm_name, lambdaval)

        # IMPORTANT: Preprocess the scenario instances
        #            before fixing variables, otherwise they
        #            will be preprocessed out of the expressions
        #            and the output_fixed_variable_bounds option
        #            will have no effect when we update the
        #            fixed variable values (and then assume we
        #            do not need to preprocess again because
        #            of this option).
        ph._preprocess_scenario_instances()

        lagrUtil.FixAllIndicatorVariables(ph, IndVarName, 0)
        for scenario in rootnode._scenarios:
            ScenarioList.append((scenario._name, scenario._probability))

        # sorts from min to max probability
        ScenarioList.sort(key=operator.itemgetter(1))
        with open(outputFilePrefix + 'ScenarioList.csv', 'w') as outFile:
            for scenario in ScenarioList:
                outFile.write(scenario[0] + ", " + str(scenario[1]) + "\n")
        Result.ScenarioList = ScenarioList

        print("lambda= " + str(lambdaval) + " ...run begins " +
              str(len(ScenarioList)) + " scenarios")
        SolStat, zL = lagrUtil.solve_ph_code(ph, options)
        print("\t...ends")
        bL = Compute_ExpectationforVariable(ph, IndVarName, CCStageNum)
        if bL > 0:
            print("** bL = " + str(bL) + "  > 0")
            return Result

        print("Initial cost = " + str(zL) + "  for bL = " + str(bL))

        lagrUtil.FixAllIndicatorVariables(ph, IndVarName, 1)

        print("lambda= " + str(lambdaval) + " ...run begins")
        SolStat, zU = lagrUtil.solve_ph_code(ph, options)
        print("\t...ends")
        bU = Compute_ExpectationforVariable(ph, IndVarName, CCStageNum)
        if bU < 1:
            print("** bU = " + str(bU) + "  < 1")

        lagrUtil.FreeAllIndicatorVariables(ph, IndVarName)

        Result.lbz = [[0, bL, zL], [None, bU, zU]]
        Result.selections = [[], ScenarioList]
        NumIntervals = 1
        print("initial gap = " + str(1 - zL / zU) + " \n")
        print("End of test; this is only a test.")

        return Result
################################
# LagrangeParametric ends here
################################

#### start run ####

    AllInOne = False

    ##########################
    # options defined here
    ##########################
    try:
        conf_options_parser = construct_ph_options_parser("lagrange [options]")
        conf_options_parser.add_argument(
            "--alpha",
            help="The alpha level for the chance constraint. Default is 0.05",
            action="store",
            dest="alpha",
            type=float,
            default=0.05)
        conf_options_parser.add_argument(
            "--alpha-min",
            help=
            "The min alpha level for the chance constraint. Default is None",
            action="store",
            dest="alpha_min",
            type=float,
            default=None)
        conf_options_parser.add_argument(
            "--alpha-max",
            help="The alpha level for the chance constraint. Default is None",
            action="store",
            dest="alpha_max",
            type=float,
            default=None)
        conf_options_parser.add_argument(
            "--min-prob",
            help="Tolerance for testing probability > 0. Default is 1e-5",
            action="store",
            dest="min_prob",
            type=float,
            default=1e-5)
        conf_options_parser.add_argument(
            "--alpha-tol",
            help="Tolerance for testing equality to alpha. Default is 1e-5",
            action="store",
            dest="alpha_tol",
            type=float,
            default=1e-5)
        conf_options_parser.add_argument(
            "--MaxMorePR",
            help=
            "Generate up to this many additional PR points after response function. Default is 0",
            action="store",
            dest="MaxMorePR",
            type=int,
            default=0)
        conf_options_parser.add_argument(
            "--outputFilePrefix",
            help="Output file name.  Default is ''",
            action="store",
            dest="outputFilePrefix",
            type=str,
            default="")
        conf_options_parser.add_argument(
            "--stage-num",
            help=
            "The stage number of the CC indicator variable (number, not name). Default is 2",
            action="store",
            dest="stage_num",
            type=int,
            default=2)
        conf_options_parser.add_argument(
            "--lambda-parm-name",
            help=
            "The name of the lambda parameter in the model. Default is lambdaMult",
            action="store",
            dest="lambda_parm_name",
            type=str,
            default="lambdaMult")
        conf_options_parser.add_argument(
            "--indicator-var-name",
            help=
            "The name of the indicator variable for the chance constraint. The default is delta",
            action="store",
            dest="indicator_var_name",
            type=str,
            default="delta")
        conf_options_parser.add_argument(
            "--use-Loane-cuts",
            help="Add the Loane cuts if there is a gap. Default is False",
            action="store_true",
            dest="add_Loane_cuts",
            default=False)
        conf_options_parser.add_argument(
            "--fofx-var-name",
            help=
            "(Loane) The name of the model's auxiliary variable that is constrained to be f(x). Default is fofox",
            action="store",
            dest="fofx_var_name",
            type=str,
            default="fofx")
        conf_options_parser.add_argument(
            "--solve-with-ph",
            help=
            "Perform solves via PH rather than an EF solve. Default is False",
            action="store_true",
            dest="solve_with_ph",
            default=False)
        conf_options_parser.add_argument(
            "--skip-graph",
            help=
            "Do not show the graph at the end. Default is False (i.e. show the graph)",
            action="store_true",
            dest="skip_graph",
            default=False)
        conf_options_parser.add_argument(
            "--write-xls",
            help="Write results into a xls file. Default is False",
            action="store_true",
            dest="write_xls",
            default=False)
        conf_options_parser.add_argument(
            "--skip-ExpFlip",
            help=
            "Do not show the results for flipping the indicator variable for each scenario. Default is False (i.e. show the flipping-results)",
            action="store_true",
            dest="skip_ExpFlip",
            default=False)
        conf_options_parser.add_argument(
            "--HeurFlip",
            help=
            "The number of solutions to evaluate after the heuristic. Default is 3. For 0 the heuristic flip gets skipped.",
            action="store",
            type=int,
            dest="HeurFlip",
            default=3)
        conf_options_parser.add_argument(
            "--HeurMIP",
            help=
            "The mipgap for the scenariowise solves in the heuristic. Default is 0.0001",
            action="store",
            type=float,
            dest="HeurMIP",
            default=0.0001)
        conf_options_parser.add_argument(
            "--interactive",
            help="Enable interactive version of the code. Default is False.",
            action="store_true",
            dest="interactive",
            default=False)
        conf_options_parser.add_argument(
            "--Lgap",
            help=
            "The (relative) Lagrangian gap acceptable for the chance constraint. Default is 10^-4",
            action="store",
            type=float,
            dest="LagrangeGap",
            default=0.0001)
        conf_options_parser.add_argument(
            "--lagrange-method",
            help="The Lagrange multiplier search method",
            action="store",
            dest="lagrange_search_method",
            type=str,
            default="tangential")
        conf_options_parser.add_argument(
            "--max-lambda",
            help="The max value of the multiplier. Default=10^10",
            action="store",
            dest="max_lambda",
            type=float,
            default=10**10)
        conf_options_parser.add_argument(
            "--min-lambda",
            help="The min value of the multiplier. Default=0.0",
            action="store",
            dest="min_lambda",
            type=float,
            default=0)
        conf_options_parser.add_argument(
            "--min-probability",
            help="The min value of scenario probability. Default=10^-15",
            action="store",
            dest="min_probability",
            type=float,
            default=10**(-15))

        ################################################################

        options = conf_options_parser.parse_args(args=args)
        # temporary hack
        options._ef_options = conf_options_parser._ef_options
        options._ef_options.import_argparse(options)
    except SystemExit as _exc:
        # the parser throws a system exit if "-h" is specified - catch
        # it to exit gracefully.
        return _exc.code

    # load the reference model and create the scenario tree - no
    # scenario instances yet.
    if options.verbose:
        print("Loading reference model and scenario tree")
    #scenario_instance_factory, full_scenario_tree = load_models(options)
    scenario_instance_factory = \
         ScenarioTreeInstanceFactory(options.model_directory,
                                     options.instance_directory)

    full_scenario_tree = \
             GenerateScenarioTreeForPH(options,
                                       scenario_instance_factory)

    solver_manager = SolverManagerFactory(options.solver_manager_type)
    if solver_manager is None:
        raise ValueError("Failed to create solver manager of "
                         "type=" + options.solver_manager_type +
                         " specified in call to PH constructor")
    if isinstance(solver_manager, pysp.plugins.phpyro.SolverManager_PHPyro):
        raise ValueError("PHPyro can not be used as the solver manager")

    try:

        if (scenario_instance_factory is None) or (full_scenario_tree is None):
            raise RuntimeError(
                "***ERROR: Failed to initialize model and/or the scenario tree data."
            )

        # load_model gets called again, so lets make sure unarchived directories are used
        options.model_directory = scenario_instance_factory._model_filename
        options.instance_directory = scenario_instance_factory._scenario_tree_filename

        scenario_count = len(full_scenario_tree._stages[-1]._tree_nodes)

        # create ph objects for finding the solution. we do this even if
        # we're solving the extensive form

        if options.verbose:
            print(
                "Loading scenario instances and initializing scenario tree for full problem."
            )

########## Here is where multiplier search is called ############
        Result = partialLagrangeParametric()
#####################################################################################

    finally:
        # delete temporary unarchived directories
        scenario_instance_factory.close()

    print("\nreturned from partialLagrangeParametric")
Exemplo n.º 13
0
def run(args=None):
##########################================================#########
   # to import plugins
   import pyomo.environ
   import pyomo.solvers.plugins.smanager.phpyro
   import pyomo.solvers.plugins.smanager.pyro

   def partialLagrangeParametric(args=None):
      print("lagrangeParam begins ")
      blanks = "                          "  # used for formatting print statements
      class Object(object): pass
      Result = Object()

# options used
      IndVarName = options.indicator_var_name
      CCStageNum = options.stage_num
      alphaTol = options.alpha_tol
      MaxMorePR = options.MaxMorePR # option to include up to this many PR points above F^* with all delta fixed
      outputFilePrefix = options.outputFilePrefix

# We write ScenarioList = name, probability
#          PRoptimal    = probability, min-cost, [selections]
#          PRmore       = probability, min-cost, [selections]
# ================ sorted by probability ========================
#
# These can be read to avoid re-computing points

      ph = PHFromScratch(options)
      Result.ph = ph
      rootnode = ph._scenario_tree._stages[0]._tree_nodes[0]   # use rootnode to loop over scenarios

      if find_active_objective(ph._scenario_tree._scenarios[0]._instance,safety_checks=True).is_minimizing():
         print("We are solving a MINIMIZATION problem.\n")
      else:
         print("We are solving a MAXIMIZATION problem.\n")

# initialize
      ScenarioList = []
      lambdaval = 0.
      lagrUtil.Set_ParmValue(ph,
                             options.lambda_parm_name,
                             lambdaval)

      # IMPORTANT: Preprocess the scenario instances
      #            before fixing variables, otherwise they
      #            will be preprocessed out of the expressions
      #            and the output_fixed_variable_bounds option
      #            will have no effect when we update the
      #            fixed variable values (and then assume we
      #            do not need to preprocess again because
      #            of this option).
      ph._preprocess_scenario_instances()

      lagrUtil.FixAllIndicatorVariables(ph, IndVarName, 0)
      for scenario in rootnode._scenarios:
         ScenarioList.append((scenario._name,
                              scenario._probability))

      # sorts from min to max probability
      ScenarioList.sort(key=operator.itemgetter(1))
      with open(outputFilePrefix+'ScenarioList.csv','w') as outFile:
         for scenario in ScenarioList:
            outFile.write(scenario[0]+ ", " +str(scenario[1])+"\n")
      Result.ScenarioList = ScenarioList

      print("lambda= "+str(lambdaval)+" ...run begins "+str(len(ScenarioList))+" scenarios")
      SolStat, zL = lagrUtil.solve_ph_code(ph, options)
      print("\t...ends")
      bL = Compute_ExpectationforVariable(ph,
                                          IndVarName,
                                          CCStageNum)
      if bL > 0:
         print("** bL = "+str(bL)+"  > 0")
         return Result

      print("Initial cost = "+str(zL)+"  for bL = "+str(bL))

      lagrUtil.FixAllIndicatorVariables(ph, IndVarName, 1)

      print("lambda= "+str(lambdaval)+" ...run begins")
      SolStat, zU = lagrUtil.solve_ph_code(ph, options)
      print("\t...ends")
      bU = Compute_ExpectationforVariable(ph,
                                          IndVarName,
                                          CCStageNum)
      if bU < 1:
            print("** bU = "+str(bU)+"  < 1")

      lagrUtil.FreeAllIndicatorVariables(ph, IndVarName)

      Result.lbz = [ [0,bL,zL], [None,bU,zU] ]
      Result.selections = [[], ScenarioList]
      NumIntervals = 1
      print("initial gap = "+str(1-zL/zU)+" \n")
      print("End of test; this is only a test.")

      return Result
################################
# LagrangeParametric ends here
################################

#### start run ####

   AllInOne = False

##########################
# options defined here
##########################
   try:
      conf_options_parser = construct_ph_options_parser("lagrange [options]")
      conf_options_parser.add_argument("--alpha",
                                     help="The alpha level for the chance constraint. Default is 0.05",
                                     action="store",
                                     dest="alpha",
                                     type=float,
                                     default=0.05)
      conf_options_parser.add_argument("--alpha-min",
                                     help="The min alpha level for the chance constraint. Default is None",
                                     action="store",
                                     dest="alpha_min",
                                     type=float,
                                     default=None)
      conf_options_parser.add_argument("--alpha-max",
                                     help="The alpha level for the chance constraint. Default is None",
                                     action="store",
                                     dest="alpha_max",
                                     type=float,
                                     default=None)
      conf_options_parser.add_argument("--min-prob",
                                     help="Tolerance for testing probability > 0. Default is 1e-5",
                                     action="store",
                                     dest="min_prob",
                                     type=float,
                                     default=1e-5)
      conf_options_parser.add_argument("--alpha-tol",
                                     help="Tolerance for testing equality to alpha. Default is 1e-5",
                                     action="store",
                                     dest="alpha_tol",
                                     type=float,
                                     default=1e-5)
      conf_options_parser.add_argument("--MaxMorePR",
                                     help="Generate up to this many additional PR points after response function. Default is 0",
                                     action="store",
                                     dest="MaxMorePR",
                                     type=int,
                                     default=0)
      conf_options_parser.add_argument("--outputFilePrefix",
                                     help="Output file name.  Default is ''",
                                     action="store",
                                     dest="outputFilePrefix",
                                     type=str,
                                     default="")
      conf_options_parser.add_argument("--stage-num",
                                     help="The stage number of the CC indicator variable (number, not name). Default is 2",
                                     action="store",
                                     dest="stage_num",
                                     type=int,
                                     default=2)
      conf_options_parser.add_argument("--lambda-parm-name",
                                     help="The name of the lambda parameter in the model. Default is lambdaMult",
                                     action="store",
                                     dest="lambda_parm_name",
                                     type=str,
                                     default="lambdaMult")
      conf_options_parser.add_argument("--indicator-var-name",
                                     help="The name of the indicator variable for the chance constraint. The default is delta",
                                     action="store",
                                     dest="indicator_var_name",
                                     type=str,
                                     default="delta")
      conf_options_parser.add_argument("--use-Loane-cuts",
                                     help="Add the Loane cuts if there is a gap. Default is False",
                                     action="store_true",
                                     dest="add_Loane_cuts",
                                     default=False)
      conf_options_parser.add_argument("--fofx-var-name",
                                     help="(Loane) The name of the model's auxiliary variable that is constrained to be f(x). Default is fofox",
                                     action="store",
                                     dest="fofx_var_name",
                                     type=str,
                                     default="fofx")
      conf_options_parser.add_argument("--solve-with-ph",
                                     help="Perform solves via PH rather than an EF solve. Default is False",
                                     action="store_true",
                                     dest="solve_with_ph",
                                     default=False)
      conf_options_parser.add_argument("--skip-graph",
                                     help="Do not show the graph at the end. Default is False (i.e. show the graph)",
                                     action="store_true",
                                     dest="skip_graph",
                                     default=False)
      conf_options_parser.add_argument("--write-xls",
                                     help="Write results into a xls file. Default is False",
                                     action="store_true",
                                     dest="write_xls",
                                     default=False)
      conf_options_parser.add_argument("--skip-ExpFlip",
                                     help="Do not show the results for flipping the indicator variable for each scenario. Default is False (i.e. show the flipping-results)",
                                     action="store_true",
                                     dest="skip_ExpFlip",
                                     default=False)
      conf_options_parser.add_argument("--HeurFlip",
                                     help="The number of solutions to evaluate after the heuristic. Default is 3. For 0 the heuristic flip gets skipped.",
                                     action="store",
                                     type=int,
                                     dest="HeurFlip",
                                     default=3)
      conf_options_parser.add_argument("--HeurMIP",
                                     help="The mipgap for the scenariowise solves in the heuristic. Default is 0.0001",
                                     action="store",
                                     type=float,
                                     dest="HeurMIP",
                                     default=0.0001)
      conf_options_parser.add_argument("--interactive",
                                     help="Enable interactive version of the code. Default is False.",
                                     action="store_true",
                                     dest="interactive",
                                     default=False)
      conf_options_parser.add_argument("--Lgap",
                                     help="The (relative) Lagrangian gap acceptable for the chance constraint. Default is 10^-4",
                                     action="store",
                                     type=float,
                                     dest="LagrangeGap",
                                     default=0.0001)
      conf_options_parser.add_argument("--lagrange-method",
                                     help="The Lagrange multiplier search method",
                                     action="store",
                                     dest="lagrange_search_method",
                                     type=str,
                                     default="tangential")
      conf_options_parser.add_argument("--max-lambda",
                                     help="The max value of the multiplier. Default=10^10",
                                     action="store",
                                     dest="max_lambda",
                                     type=float,
                                     default=10**10)
      conf_options_parser.add_argument("--min-lambda",
                                     help="The min value of the multiplier. Default=0.0",
                                     action="store",
                                     dest="min_lambda",
                                     type=float,
                                     default=0)
      conf_options_parser.add_argument("--min-probability",
                                     help="The min value of scenario probability. Default=10^-15",
                                     action="store",
                                     dest="min_probability",
                                     type=float,
                                     default=10**(-15))

################################################################

      options = conf_options_parser.parse_args(args=args)
      # temporary hack
      options._ef_options = conf_options_parser._ef_options
      options._ef_options.import_argparse(options)
   except SystemExit as _exc:
      # the parser throws a system exit if "-h" is specified - catch
      # it to exit gracefully.
      return _exc.code

   # load the reference model and create the scenario tree - no
   # scenario instances yet.
   if options.verbose:
      print("Loading reference model and scenario tree")
   #scenario_instance_factory, full_scenario_tree = load_models(options)
   scenario_instance_factory = \
        ScenarioTreeInstanceFactory(options.model_directory,
                                    options.instance_directory,
                                    options.verbose)

   full_scenario_tree = \
            GenerateScenarioTreeForPH(options,
                                      scenario_instance_factory)

   solver_manager = SolverManagerFactory(options.solver_manager_type)
   if solver_manager is None:
      raise ValueError("Failed to create solver manager of "
                       "type="+options.solver_manager_type+
                       " specified in call to PH constructor")
   if isinstance(solver_manager,
                 pyomo.solvers.plugins.smanager.phpyro.SolverManager_PHPyro):
      solver_manager.deactivate()
      raise ValueError("PHPyro can not be used as the solver manager")

   try:

      if (scenario_instance_factory is None) or (full_scenario_tree is None):
         raise RuntimeError("***ERROR: Failed to initialize model and/or the scenario tree data.")

      # load_model gets called again, so lets make sure unarchived directories are used
      options.model_directory = scenario_instance_factory._model_filename
      options.instance_directory = scenario_instance_factory._scenario_tree_filename

      scenario_count = len(full_scenario_tree._stages[-1]._tree_nodes)

      # create ph objects for finding the solution. we do this even if
      # we're solving the extensive form

      if options.verbose:
         print("Loading scenario instances and initializing scenario tree for full problem.")

########## Here is where multiplier search is called ############
      Result = partialLagrangeParametric()
#####################################################################################

   finally:

      solver_manager.deactivate()
      # delete temporary unarchived directories
      scenario_instance_factory.close()

   print("\nreturned from partialLagrangeParametric")
Exemplo n.º 14
0
    return (
        sum(
            modelo.tiempo_produccion[planta, producto] *
            modelo.produccion[producto]
            for producto in modelo.productos
        ) <= modelo.tiempo_disponible[planta]
    )
modelo.disponibilidad_tiempo = Constraint(
    modelo.plantas, rule=funcion_disponibilidad_tiempo
)


def funcion_ganancias(modelo):
    return sum(
        modelo.ganancia_unitaria[producto] * modelo.produccion[producto]
        for producto in modelo.productos
    )
modelo.ganancias = Objective(rule=funcion_ganancias, sense=maximize)

instancia = modelo.create_instance("wyndor.dat")

opt = SolverFactory("cbc")

solver_manager = SolverManagerFactory('neos')

resultados = solver_manager.solve(instancia, opt=opt)  # resolver en la nube

# resultados = opt.solve(instancia)  # resolver localmente

instancia.display()
Exemplo n.º 15
0
def solve_model(model, p_summary=False, p_log=False):  # Custom Solve Method
    import datetime
    # Choose the best solution from the trial pool

    # trial_pool = {
    #                 'sample1':{'solution_file':None,'aspiration':None},
    #                 'sample2':{'solution_file':None,'aspiration':None},
    #                 'sample3':{'solution_file':None,'aspiration':None}
    #              }

    #model1 = copy.deepcopy(model)
    #model2 = copy.deepcopy(model)
    #model3 = copy.deepcopy(model)
    import configparser
    config = configparser.ConfigParser()
    config.read('../start_config.ini')

    #initialization Setting
    mip_gap = float(config['solver']['mip_gap'])
    solver_timeout = int(config['solver']['solver_timeout'])
    solver_sh = config['solver']['solver_sh']
    number_of_trials = int(config['solver']['number_of_trials'])
    engage_neos = bool(int(
        config['solver']['engage_neos']))  #initialization Setting
    threads = int(config['solver']['threads'])

    if solver_sh not in set(["cbc", "cplex"]):
        raise AssertionError("Invalid Solver!, Error Code : 200B")

    logger.info("success! \n loading solver......")

    j = 1
    timeout_arguments = {'cplex': 'timelimit', 'cbc': 'sec'}
    gap_arguments = {
        'cplex': 'mipgap',
        'cbc': 'ratio'
    }  # Cplex Local Executable will take : "mip_tolerance_mipgap", mipgap is for neos version

    # NEOS Server Library Dependency
    # pyro4
    # suds
    # openopt

    while j < number_of_trials + 1:
        from pyomo.opt import SolverFactory, SolverManagerFactory
        #model.pprint()
        opt = SolverFactory(solver_sh, solver_io='lp')
        # print ('\ninterfacing solver shell :',solver_sh)
        logger.debug('interfacing solver shell : %s' % (solver_sh))
        if engage_neos:
            solver_manager = SolverManagerFactory('neos')
        opt.options[timeout_arguments[solver_sh]] = solver_timeout
        opt.options[gap_arguments[solver_sh]] = mip_gap
        #opt.symbolic_solver_labels=True
        #
        #opt.enable = 'parallel'
        print(
            '\tsolver options >> \n\n\tTolerance Limits:\n\tmip_gap = %s \n\ttimeout = %s'
            % (str(mip_gap), str(solver_timeout)))
        # print ("\nProcessing Trial Number :",j)
        # print ("\nJob Triggered at :",str(datetime.datetime.now()))
        print(
            '\ngenerating solution ...... !! please wait !!    \n to interrupt press ctrl+C\n'
        )

        # logger.debug('\tsolver options >> \n\n\tTolerance Limits:\n\tmip_gap = %s \n\ttimeout = %s'%(str(mip_gap),str(solver_timeout)))
        logger.debug('Processing Trial Number :%d' % (j))
        logger.debug("Job Triggered")
        try:
            if engage_neos:
                p_log = False
                results = solver_manager.solve(model, opt=opt, tee=True)
            else:
                opt.options['threads'] = threads
                if p_log:
                    opt.options['slog'] = 1
                results = opt.solve(
                    model
                )  # Method Load Solutions is not available in pyomo versions less than 4.x
        except:
            j = j + 1
            mip_gap = (j - 1) * mip_gap
            solver_sh = 'cplex'
            engage_neos = True
            continue
        #results.write(filename='results'+str(datetime.date.today())+'.json',format = 'json')
        #print (results)
        if str(results['Solver'][0]['Termination condition']) in [
                'infeasible', 'maxTimeLimit', 'maxIterations',
                'intermediateNonInteger', 'unbounded'
        ]:
            j = j + 1
            mip_gap = (j - 1) * mip_gap
            solver_sh = 'cplex'
            engage_neos = True
            if j == number_of_trials + 1:
                #print (results['Problem'])
                #print (results['Solver'])
                raise AssertionError(
                    "Solver Failed with Termination Status : %s \nError Code : 200C"
                    % (str(results['Solver'][0]['Termination condition'])))
                exit(0)
            # print ('Terminated by:',str(results['Solver'][0]['Termination condition']))
            # print ("\n\nRetrying...\n\n")
            logger.info('Terminated by:',
                        str(results['Solver'][0]['Termination condition']))
            logger.info("\n\nRetrying...\n\n")
        else:
            # print ("SUCCESS: Solution Captured!")
            logger.info("Solution Captured!")
            model.solutions.store_to(results)
            #post_process_results()
            break

    if p_summary:
        print(results['Problem'])
        # print (results['Solver'])
    # print ("\nSolution Retrived at:",str(datetime.datetime.now()))
    # logger.info("Solution Retrived")
    return [model, results]
Exemplo n.º 16
0
modelo.ganancias = Objective(rule=funcion_ganancias, sense=maximize)


def funcion_capacidad_doug(modelo):
    return modelo.produccion["madera"] <= 6
modelo.capacidad_doug = Constraint(rule=funcion_capacidad_doug)


def funcion_capacidad_linda(modelo):
    return modelo.produccion["aluminio"] <= 4
modelo.capacidad_linda = Constraint(rule=funcion_capacidad_linda)


def funcion_capacidad_bob(modelo):
    return (
        modelo.produccion["madera"]*6 +
        modelo.produccion["aluminio"]*8 <= 48
    )
    
modelo.capacidad_bob = Constraint(rule=funcion_capacidad_bob)

opt = SolverFactory("cbc")

solver_manager = SolverManagerFactory('neos')

resultados = solver_manager.solve(modelo, opt=opt)  # resolver en la nube

# resultados = opt.solve(modelo)  # resolver localmente

modelo.display()
Exemplo n.º 17
0
def run(args=None):
###################################

   # to import plugins
   import pyomo.environ
   import pyomo.solvers.plugins.smanager.phpyro

   def LagrangeMorePR(args=None):
      print("lagrangeMorePR begins %s" % datetime_string())
      blanks = "                          "  # used for formatting print statements
      class Object(object): pass
      Result = Object()

# options used
      betaTol       = options.beta_tol          # tolerance used to separate b-values
      IndVarName    = options.indicator_var_name
      multName      = options.lambda_parm_name
      CCStageNum    = options.stage_num
      MaxMorePR     = options.max_number         # max PR points to be generated (above F^* with all delta fixed)
      MaxTime       = options.max_time           # max time before terminate
      csvPrefix = options.csvPrefix          # input filename prefix (eg, case name)
      probFileName  = options.probFileName       # name of file containing probabilities
##HG override
#      options.verbosity = 2
      verbosity     = options.verbosity

      Result.status = 'starting '+datetime_string()
      STARTTIME = time.time()

      ph = PHFromScratch(options)
      rootnode = ph._scenario_tree._stages[0]._tree_nodes[0]   # use rootnode to loop over scenarios

      if find_active_objective(ph._scenario_tree._scenarios[0]._instance,safety_checks=True).is_minimizing():
         print("We are solving a MINIMIZATION problem.")
      else:
         print("We are solving a MAXIMIZATION problem.")

# initialize
      ScenarioList = []
      with open(csvPrefix+"ScenarioList.csv",'r') as inputFile:
         for line in inputFile.readlines():
            L = line.split(',')
            ScenarioList.append([L[0],float(L[1])])

      addstatus = str(len(ScenarioList))+' scenarios read from file: ' + csvPrefix+'ScenarioList.csv'
      if verbosity > 0: print(addstatus)
      Result.status = Result.status + '\n' + addstatus

      PRoptimal = []
      with open(csvPrefix+"PRoptimal.csv",'r') as inputFile:
         for line in inputFile.readlines():
            bzS = line.split(',')
            PRoptimal.append( [None, float(bzS[0]), float(bzS[1])] )

      addstatus = str(len(PRoptimal))+' PR points read from file: '+ csvPrefix+'PRoptimal.csv (envelope function)'
      if verbosity > 0:
         print(addstatus)
      Result.status = Result.status + '\n' + addstatus
# ensure PR points on envelope function are sorted by probability
      PRoptimal.sort(key=operator.itemgetter(1))

      PRoptimal[0][0] = 0   # initial lambda (for b=0)
      for p in range(1,len(PRoptimal)):
         dz = PRoptimal[p][2] - PRoptimal[p-1][2]
         db = PRoptimal[p][1] - PRoptimal[p-1][1]
         PRoptimal[p][0] = dz/db
      if verbosity > 0:
         PrintPRpoints(PRoptimal)
      Result.PRoptimal = PRoptimal

      lambdaval = 0.
      lagrUtil.Set_ParmValue(ph, options.lambda_parm_name,lambdaval)

      # IMPORTANT: Preprocess the scenario instances
      #            before fixing variables, otherwise they
      #            will be preprocessed out of the expressions
      #            and the output_fixed_variable_bounds option
      #            will have no effect when we update the
      #            fixed variable values (and then assume we
      #            do not need to preprocess again because
      #            of this option).
      ph._preprocess_scenario_instances()

## read scenarios to select for each PR point on envelope function
      with open(csvPrefix+"OptimalSelections.csv",'r') as inputFile:
         OptimalSelections = []
         for line in inputFile.readlines():
            if len(line) == 0: break # eof
            selections = line.split(',')
            L = len(selections)
            Ls = len(selections[L-1])
            selections[L-1] = selections[L-1][0:Ls-1]
            if verbosity > 1:
               print(str(selections))
            OptimalSelections.append(selections)

      Result.OptimalSelections = OptimalSelections

      addstatus = str(len(OptimalSelections)) + ' Optimal selections read from file: ' \
            + csvPrefix + 'OptimalSelections.csv'
      Result.status = Result.status + '\n' + addstatus

      if len(OptimalSelections) == len(PRoptimal):
         if verbosity > 0:
            print(addstatus)
      else:
         addstatus = addstatus + '\n** Number of selections not equal to number of PR points'
         print(addstatus)
         Result.status = Result.status + '\n' + addstatus
         print(str(OptimalSelections))
         print((PRoptimal))
         return Result

#####################################################################################

# get probabilities
      if probFileName is None:
# ...generate from widest gap regions
         PRlist = FindPRpoints(options, PRoptimal)
      else:
# ...read probabilities
         probList = []
         with open(probFileName,'r') as inputFile:
            if verbosity > 0:
               print("reading from probList = "+probFileName)
            for line in inputFile.readlines():  # 1 probability per line
               if len(line) == 0:
                  break
               prob = float(line)
               probList.append(prob)

         if verbosity > 0:
            print("\t "+str(len(probList))+" probabilities")
         if verbosity > 1:
            print(str(probList))
         PRlist = GetPoints(options, PRoptimal, probList)
         if verbosity > 1:
            print("PRlist:")
            for interval in PRlist:
               print(str(interval))

# We now have PRlist = [[i, b], ...], where b is in PRoptimal interval (i-1,i)
      addstatus = str(len(PRlist)) + ' probabilities'
      if verbosity > 0:
         print(addstatus)
      Result.status = Result.status + '\n' + addstatus

#####################################################################################

      lapsedTime = time.time() - STARTTIME
      addstatus = 'Initialize complete...lapsed time = ' + str(lapsedTime)
      if verbosity > 1:
         print(addstatus)
      Result.status = Result.status + '\n' + addstatus

#####################################################################################

      if verbosity > 1:
        print("\nlooping over Intervals to generate PR points by flipping heuristic")
      Result.morePR = []
      for interval in PRlist:
         lapsedTime = time.time() - STARTTIME
         if lapsedTime > MaxTime:
            addstatus = '** lapsed time = ' + str(lapsedTime) + ' > max time = ' + str(MaxTime)
            if verbosity > 0: print(addstatus)
            Result.status = Result.status + '\n' + addstatus
            break

         i = interval[0] # = PR point index
         b = interval[1] # = target probability to reach by flipping from upper endpoint
         bU = PRoptimal[i][1]   # = upper endpoint
         bL = PRoptimal[i-1][1] # = lower endpoint
         if verbosity > 1:
            print( "target probability = "+str(b)+" < bU = PRoptimal[" + str(i) + "][1]" \
                 " and > bL = PRoptimal["+str(i-1)+"][1]")
         if b < bL or b > bU:
            addstatus = '** probability = '+str(b) + ', not in gap interval: (' \
                + str(bL) + ', ' + str(bU) + ')'
            print(addstatus)
            print(str(PRoptimal))
            print(str(PRlist))
            Result.status = Result.status + '\n' + addstatus
            return Result

         if verbosity > 1:
            print( "i = "+str(i)+" : Starting with bU = "+str(bU)+" having "+ \
                str(len(OptimalSelections[i]))+ " selections:")
            print(str(OptimalSelections[i]))

# first fix all scenarios = 0
         for sname, sprob in ScenarioList:
            scenario = ph._scenario_tree.get_scenario(sname)
            lagrUtil.FixIndicatorVariableOneScenario(ph,
                                                     scenario,
                                                     IndVarName,
                                                     0)

# now fix optimal selections = 1
         for sname in OptimalSelections[i]:
            scenario = ph._scenario_tree.get_scenario(sname)
            lagrUtil.FixIndicatorVariableOneScenario(ph,
                                                     scenario,
                                                     IndVarName,
                                                     1)

# flip scenario selections from bU until we reach b (target probability)
         bNew = bU
         for sname, sprob in ScenarioList:
            scenario = ph._scenario_tree.get_scenario(sname)
            if bNew - sprob < b:
               continue
            instance = ph._instances[sname]
            if getattr(instance, IndVarName).value == 0:
               continue
            bNew = bNew - sprob
            # flipped scenario selection
            lagrUtil.FixIndicatorVariableOneScenario(ph,
                                                     scenario,
                                                     IndVarName,
                                                     0)
            if verbosity > 1:
               print("\tflipped "+sname+" with prob = "+str(sprob)+" ...bNew = "+str(bNew))

         if verbosity > 1:
            print("\tflipped selections reach "+str(bNew)+" >= target = "+str(b)+" (bL = "+str(bL)+")")
         if bNew <= bL + betaTol or bNew >= bU - betaTol:
            if verbosity > 0:
               print("\tNot generating PR point...flipping from bU failed")
            continue # to next interval in list

 # ready to solve to get cost for fixed scenario selections associated with probability = bNew

         if verbosity > 1:
# check that scenarios are fixed as they should be
            totalprob = 0.
            for scenario in ScenarioList:
               sname = scenario[0]
               sprob = scenario[1]
               instance = ph._instances[sname]
               print("fix "+sname+" = "+str(getattr(instance,IndVarName).value)+\
                  " is "+str(getattr(instance,IndVarName).fixed)+" probability = "+str(sprob))
               if getattr(instance,IndVarName).value == 1:
                  totalprob = totalprob + sprob
               lambdaval = getattr(instance, multName).value
            print("\ttotal probability = %f" % totalprob)

# solve (all delta fixed); lambda=0, so z = Lagrangian
         if verbosity > 0:
            print("solve begins %s" % datetime_string())
            print("\t- lambda = %f" % lambdaval)
         SolStat, z = lagrUtil.solve_ph_code(ph, options)
         b = Compute_ExpectationforVariable(ph, IndVarName, CCStageNum)
         if verbosity > 0:
            print("solve ends %s" % datetime_string())
            print("\t- SolStat = %s" % str(SolStat))
            print("\t- b = %s" % str(b))
            print("\t- z = %s" % str(z))
            print("(adding to more PR points)")

         Result.morePR.append([None,b,z])
         if verbosity > 1:
            PrintPRpoints(Result.morePR)
      ######################################################
      # end loop over target probabilities

      with open(csvPrefix+"PRmore.csv",'w') as outFile:
         for point in Result.morePR:
            outFile.write(str(point[1])+','+str(point[2]))

      addstatus = str(len(Result.morePR)) + ' PR points written to file: '+ csvPrefix + 'PRmore.csv'
      if verbosity > 0: print(addstatus)
      Result.status = Result.status + '\n' + addstatus
      addstatus = 'lapsed time = ' + putcommas(time.time() - STARTTIME)
      if verbosity > 0: print(addstatus)
      Result.status = Result.status + '\n' + addstatus

      return Result
################################
# LagrangeMorePR ends here
################################

#### start run ####

   AllInOne = False
#   VERYSTARTTIME=time.time()
#   print "##############VERYSTARTTIME:",str(VERYSTARTTIME-VERYSTARTTIME)

##########################
# options defined here
##########################
   try:
      conf_options_parser = construct_ph_options_parser("lagrange [options]")
      conf_options_parser.add_argument("--beta-min",
                                     help="The min beta level for the chance constraint. Default is None",
                                     action="store",
                                     dest="beta_min",
                                     type=float,
                                     default=None)
      conf_options_parser.add_argument("--beta-max",
                                     help="The beta level for the chance constraint. Default is None",
                                     action="store",
                                     dest="beta_max",
                                     type=float,
                                     default=None)
      conf_options_parser.add_argument("--min-prob",
                                     help="Tolerance for testing probability > 0. Default is 1e-5",
                                     action="store",
                                     dest="min_prob",
                                     type=float,
                                     default=1e-5)
      conf_options_parser.add_argument("--beta-tol",
                                     help="Tolerance for testing equality to beta. Default is 10^-2",
                                     action="store",
                                     dest="beta_tol",
                                     type=float,
                                     default=1e-2)
      conf_options_parser.add_argument("--Lagrange-gap",
                                     help="The (relative) Lagrangian gap acceptable for the chance constraint. Default is 10^-4.",
                                     action="store",
                                     type=float,
                                     dest="Lagrange_gap",
                                     default=0.0001)
      conf_options_parser.add_argument("--max-number",
                                     help="The max number of PR points. Default = 10.",
                                     action="store",
                                     dest="max_number",
                                     type=int,
                                     default=10)
      conf_options_parser.add_argument("--max-time",
                                     help="Maximum time (seconds). Default is 3600.",
                                     action="store",
                                     dest="max_time",
                                     type=float,
                                     default=3600)
      conf_options_parser.add_argument("--csvPrefix",
                                     help="Input file name prefix.  Default is ''",
                                     action="store",
                                     dest="csvPrefix",
                                     type=str,
                                     default="")
      conf_options_parser.add_argument("--lambda-parm-name",
                                     help="The name of the lambda parameter in the model. Default is lambdaMult",
                                     action="store",
                                     dest="lambda_parm_name",
                                     type=str,
                                     default="lambdaMult")
      conf_options_parser.add_argument("--indicator-var-name",
                                     help="The name of the indicator variable for the chance constraint. The default is delta",
                                     action="store",
                                     dest="indicator_var_name",
                                     type=str,
                                     default="delta")
      conf_options_parser.add_argument("--stage-num",
                                     help="The stage number of the CC indicator variable (number, not name). Default is 2",
                                     action="store",
                                     dest="stage_num",
                                     type=int,
                                     default=2)
      conf_options_parser.add_argument("--verbosity",
                                     help="verbosity=0 is no extra output, =1 is medium, =2 is debug, =3 super-debug. Default is 1.",
                                     action="store",
                                     dest="verbosity",
                                     type=int,
                                     default=1)
      conf_options_parser.add_argument("--prob-file",
                                     help="file name specifiying probabilities",
                                     action="store",
                                     dest="probFileName",
                                     type=str,
                                     default=None)
# The following needed for solve_ph_code in lagrangeutils
      conf_options_parser.add_argument("--solve-with-ph",
                                     help="Perform solves via PH rather than an EF solve. Default is False",
                                     action="store_true",
                                     dest="solve_with_ph",
                                     default=False)

################################################################

      options = conf_options_parser.parse_args(args=args)
      # temporary hack
      options._ef_options = conf_options_parser._ef_options
      options._ef_options.import_argparse(options)
   except SystemExit as _exc:
      # the parser throws a system exit if "-h" is specified - catch
      # it to exit gracefully.
      return _exc.code

   if options.verbose is True:
      print("Loading reference model and scenario tree")

   scenario_instance_factory = \
        ScenarioTreeInstanceFactory(options.model_directory,
                                    options.instance_directory,
                                    options.verbose)

   full_scenario_tree = \
            GenerateScenarioTreeForPH(options,
                                      scenario_instance_factory)


   solver_manager = SolverManagerFactory(options.solver_manager_type)
   if solver_manager is None:
      raise ValueError("Failed to create solver manager of "
                       "type="+options.solver_manager_type+
                       " specified in call to PH constructor")
   if isinstance(solver_manager,
                 pyomo.solvers.plugins.smanager.phpyro.SolverManager_PHPyro):
      solver_manager.deactivate()
      raise ValueError("PHPyro can not be used as the solver manager")

   try:

      if (scenario_instance_factory is None) or (full_scenario_tree is None):
         raise RuntimeError("***ERROR: Failed to initialize the model and/or scenario tree data.")

      # load_model gets called again, so lets make sure unarchived directories are used
      options.model_directory = scenario_instance_factory._model_filename
      options.instance_directory = scenario_instance_factory._scenario_tree_filename

      scenario_count = len(full_scenario_tree._stages[-1]._tree_nodes)

      # create ph objects for finding the solution. we do this even if
      # we're solving the extensive form

      if options.verbose is True:
         print("Loading scenario instances and initializing scenario tree for full problem.")

########## Here is where multiplier search is called ############
      Result = LagrangeMorePR()
#####################################################################################
   finally:

      solver_manager.deactivate()
      # delete temporary unarchived directories
      scenario_instance_factory.close()

   print("\n====================  returned from LagrangeMorePR")
   print(str(Result.status))
   try:
     print("Envelope:")
     print(str(PrintPRpoints(Result.PRoptimal)))
     print("\nAdded:")
     PrintPRpoints(Result.morePR)
   except:
     print("from run:  PrintPRpoints failed")
     sys.exit()

# combine tables and sort by probability
   if len(Result.morePR) > 0:
     PRpoints = copy.deepcopy(Result.PRoptimal)
     for lbz in Result.morePR: PRpoints.append(lbz)
     print("Combined table of PR points (sorted):")
     PRpoints.sort(key=operator.itemgetter(1))
     print(str(PrintPRpoints(PRpoints)))
from pyomo.environ import *
from pyomo.opt import SolverFactory, SolverManagerFactory

from DiseaseEstimation import model

# create the instance
instance = model.create('DiseaseEstimation.dat')

# define the solver and its options
solver = 'ipopt'
opt = SolverFactory(solver)
if opt is None:
    raise ValueError, "Problem constructing solver `" + str(solver)
opt.set_options('max_iter=2')

# create the solver manager
solver_manager = SolverManagerFactory('serial')

# solve
results = solver_manager.solve(instance, opt=opt, tee=True, timelimit=None)
instance.load(results)

# display results
display(instance)
Exemplo n.º 19
0
    def solveGeneratedInstance(self, instance, inst_name):
        # Nutze Solver Manager None/string
        if self.solver_manager_name is not None:
            with SolverManagerFactory(self.solver_manager_name) as solver_manager:
                if self.EXE_path is None:
                    opt = SolverFactory(self.solver, solver_io=self.solver_io)
                else:
                    opt = SolverFactory(self.solver, solver_io=self.solver_io,
                                        executable=self.EXE_path)
                # Solve the instance :: Clean gets no Logs
                if not self.clean:
                    self.result = solver_manager.solve(instance, opt=opt,
                                                  tee=self.tee,
                                                  logfile=inst_name+".log")
                else:
                    self.result = solver_manager.solve(instance, opt=opt,
                                                  tee=self.tee,)
        else:
            path_log = ["logs", "logfiles", inst_name+".log"]
            if self.EXE_path is None:
                with SolverFactory(self.solver,
                                   solver_io=self.solver_io) as opt:

                    # Set Solver Options
                    try:
                        for key, value in self.solver_options.items():
                            opt.options[key] = value
                    except AttributeError:
                        pass

                    # Solve the instance :: Clean gets no Logs
                    if not self.clean:
                        self.result = opt.solve(instance, tee=self.tee,
                                           load_solutions=self.load_solutions,
                                           symbolic_solver_labels=
                                           self.symbolic_solver_labels,
                                           logfile=os.path.join(*path_log))
                    else:
                        self.result = opt.solve(instance, tee=self.tee,
                                           load_solutions=self.load_solutions,
                                           symbolic_solver_labels=
                                           self.symbolic_solver_labels)
            else:
                with SolverFactory(self.solver, solver_io=self.solver_io,
                                   executable=self.EXE_path) as opt:

                    # Set Solver Options
                    try:
                        for key, value in self.solver_options.items():
                            opt.options[key] = value
                    except AttributeError:
                        pass

                    # Solve the instance :: Clean gets no Logs
                    if not self.clean:
                        self.result = opt.solve(instance, tee=self.tee,
                                           load_solutions=self.load_solutions,
                                           symbolic_solver_labels=
                                           self.symbolic_solver_labels,
                                           logfile=os.path.join(*path_log))
                    else:
                        self.result = opt.solve(instance, tee=self.tee,
                                           load_solutions=self.load_solutions,
                                           symbolic_solver_labels=
                                           self.symbolic_solver_labels)
        
        if not self.load_solutions:
            if len(self.result.solution) > 0:
                # you may need to relax these checks in certain cases
                assert str(self.result.solver.status) == "ok"
                assert str(self.result.solver.termination_condition) == "optimal"
                self.absgap = self.result.solution(0).gap
                # now load the solution
                instance.solutions.load_from(self.result)
                
        self.updateResults({inst_name: self.result})

        return instance
Exemplo n.º 20
0
def solve_model(model):       # Custom Solve Method
    import datetime
    trial_pool = {
                    'sample1':{'solution_file':None,'aspiration':None},
                    'sample2':{'solution_file':None,'aspiration':None},
                    'sample3':{'solution_file':None,'aspiration':None}
                 }

    #model1 = copy.deepcopy(model)
    #model2 = copy.deepcopy(model)
    #model3 = copy.deepcopy(model)

    print ("success! \n loading solver......")

    mip_gap = 0.005
    solver_timeout = 300
    number_of_trials = 2
    solver_sh = 'cplex'     #initialization Setting
    engage_neos = True  #initialization Setting
    j = 1
    timeout_arguments = {'cplex':'timelimit','cbc':'sec'}
    gap_arguments = {'cplex':'mipgap','cbc':'ratio'}   # Cplex Local Executable Take : "mip_tolerance_mipgap", mipgap is for neos version

    # NEOS Server Library Dependency
    # pyro4
    # suds
    # openopt

    while j < number_of_trials + 1:
        from pyomo.opt import SolverFactory, SolverManagerFactory
        #model.pprint()
        opt = SolverFactory(solver_sh, solver_io = 'lp')
        print ('\ninterfacing solver shell :',solver_sh)
        if engage_neos:
            solver_manager = SolverManagerFactory('neos')
        opt.options[timeout_arguments[solver_sh]]= solver_timeout
        opt.options[gap_arguments[solver_sh]] = mip_gap
        #opt.symbolic_solver_labels=True
        #opt.options['slog'] = 1
        #opt.enable = 'parallel'
        print ('\tsolver options >> \n\n\tTolerance Limits:\n\tmip_gap = %s \n\ttimeout = %s'%(str(mip_gap),str(solver_timeout)))
        print ("\nProcessing Trial Number :",j)
        print ("\nJob Triggered at :",str(datetime.datetime.now()))
        print ('\ngenerating production plan...... !! please wait !!    \n to interrupt press ctrl+C\n')
        try:
            if engage_neos:
                results = solver_manager.solve(model,opt = opt, tee= True)
            else:
                opt.options['threads'] = 3
                results = opt.solve(model) #,tee=True) # Method Load Solutions is not available in pyomo versions less than 4.x
        except:
            j = j+1
            mip_gap = (j-1)*mip_gap
            solver_sh = 'cplex'
            engage_neos = True
            continue
        #results.write(filename='results'+str(datetime.date.today())+'.json',format = 'json')
        #print (results)
        if str(results['Solver'][0]['Termination condition']) in ['infeasible','maxTimeLimit','maxIterations','intermediateNonInteger']:
            j = j+1
            mip_gap = (j-1)*mip_gap
            solver_sh = 'cplex'
            engage_neos = True
            if j == number_of_trials + 1:
                #print (results['Problem'])
                #print (results['Solver'])
                raise AssertionError("Solver Failed with Termination Status : %s"%(str(results['Solver'][0]['Termination condition'])))
                exit(0)
            print ('Terminated by:',str(results['Solver'][0]['Termination condition']))
            print ("\n\nRetrying...\n\n")
        else:
            print ("solution captured")
            model.solutions.store_to(results)
            #post_process_results()
            break

    print (results['Problem'])
    print (results['Solver'])
    print ("\nSolution Retrived at:",str(datetime.datetime.now()))
    return [model,results]