コード例 #1
0
ファイル: solver1.py プロジェクト: Juanlu001/pyomo
    def _apply_solver(self):
        start_time = time.time()
        #
        # Transform instance
        #
        xfrm = TransformationFactory('mpec.simple_nonlinear')
        xfrm.apply_to(self._instance)
        #
        # Solve with a specified solver
        #
        solver = self.options.solver
        if not self.options.solver:                 #pragma:nocover
            self.options.solver = solver = 'ipopt'

        # use the with block here so that deactivation of the
        # solver plugin always occurs thereby avoiding memory
        # leaks caused by plugins!
        with pyomo.opt.SolverFactory(solver) as opt:
            self.results = []
            epsilon_final = self.options.get('epsilon_final', 1e-7)
            epsilon = self.options.get('epsilon_initial', epsilon_final)
            while (True):
                self._instance.mpec_bound.value = epsilon
                #
                # **NOTE: It would be better to override _presolve on the
                #         base class of this solver as you might be
                #         missing a number of keywords that were passed
                #         into the solve method (e.g., none of the
                #         io_options are getting relayed to the subsolver
                #         here).
                #
                res = opt.solve(self._instance,
                                tee=self._tee,
                                timelimit=self._timelimit)
                self.results.append(res)
                epsilon /= 10.0
                if epsilon < epsilon_final:
                    break
            #
            # Reclassify the Complementarity components
            #
            from pyomo.mpec import Complementarity
            for cuid in self._instance._transformation_data['mpec.simple_nonlinear'].compl_cuids:
                cobj = cuid.find_component(self._instance)
                cobj.parent_block().reclassify_component_type(cobj, Complementarity)
            #
            # Update timing
            #
            stop_time = time.time()
            self.wall_time = stop_time - start_time
            #
            # Return the sub-solver return condition value and log
            #
            return pyutilib.misc.Bunch(rc=getattr(opt,'_rc', None),
                                       log=getattr(opt,'_log',None))
コード例 #2
0
ファイル: solver2.py プロジェクト: Juanlu001/pyomo
    def _apply_solver(self):
        start_time = time.time()
        #
        # Transform instance
        #
        xfrm = TransformationFactory('mpec.simple_disjunction')
        xfrm.apply_to(self._instance)

        xfrm = TransformationFactory('gdp.bigm')
        xfrm.apply_to(self._instance, default_bigM=self.options.get('bigM',10**6))
        #
        # Solve with a specified solver
        #
        solver = self.options.solver
        if not self.options.solver:                     #pragma:nocover
            self.options.solver = solver = 'glpk'

        # use the with block here so that deactivation of the
        # solver plugin always occurs thereby avoiding memory
        # leaks caused by plugins!
        with pyomo.opt.SolverFactory(solver) as opt:
            #
            # **NOTE: It would be better to override _presolve on the
            #         base class of this solver as you might be
            #         missing a number of keywords that were passed
            #         into the solve method (e.g., none of the
            #         io_options are getting relayed to the subsolver
            #         here).
            #
            self.results = opt.solve(self._instance,
                                     tee=self._tee,
                                     timelimit=self._timelimit)
            #
            # Reclassify the Complementarity components
            #
            from pyomo.mpec import Complementarity
            for cuid in self._instance._transformation_data['mpec.simple_disjunction'].compl_cuids:
                cobj = cuid.find_component(self._instance)
                cobj.parent_block().reclassify_component_type(cobj, Complementarity)
            #
            # Transform the result back into the original model
            #
            ##self._instance.solutions.load_from(self.results, ignore_invalid_labels=True)
            #
            # Update timing
            #
            stop_time = time.time()
            self.wall_time = stop_time - start_time

            #
            # Return the sub-solver return condition value and log
            #
            return pyutilib.misc.Bunch(rc=getattr(opt,'_rc', None),
                                       log=getattr(opt,'_log',None))
コード例 #3
0
ファイル: solver3.py プロジェクト: SemanticBeeng/pyomo
    def _apply_solver(self):
        start_time = time.time()
        #
        # Transform the instance
        #
        xfrm = TransformationFactory('bilevel.linear_mpec')
        xfrm.apply_to(self._instance)
        xfrm = TransformationFactory('mpec.simple_nonlinear')
        xfrm.apply_to(self._instance, mpec_bound=self.options.get('mpec_bound',1e-7))
        #
        # Solve with a specified solver
        #
        solver = self.options.solver
        if not self.options.solver:
            solver = 'glpk'

        # use the with block here so that deactivation of the
        # solver plugin always occurs thereby avoiding memory
        # leaks caused by plugins!
        with pyomo.opt.SolverFactory(solver) as opt:
            #
            self.results = []
            #
            # **NOTE: It would be better to override _presolve on the
            #         base class of this solver as you might be
            #         missing a number of keywords that were passed
            #         into the solve method (e.g., none of the
            #         io_options are getting relayed to the subsolver
            #         here).
            #
            self.results.append(opt.solve(self._instance,
                                          tee=self._tee,
                                          timelimit=self._timelimit))
        #
        # Load the result back into the original model
        #
        ##self._instance.load(self.results[0], ignore_invalid_labels=True)
        #
        stop_time = time.time()
        self.wall_time = stop_time - start_time
        #
        # Deactivate the block that contains the optimality conditions,
        # and reactivate SubModel
        #
        submodel = self._instance._transformation_data['bilevel.linear_mpec'].submodel_cuid.find_component(self._instance)
        for (name, data) in submodel.component_map(active=False).items():
            if not isinstance(data,Var) and not isinstance(data,Set):
                data.activate()
        # TODO: delete this subblock
        self._instance._transformation_data['bilevel.linear_mpec'].block_cuid.find_component(self._instance).deactivate()
        #
        # Return the sub-solver return condition value and log
        #
        return pyutilib.misc.Bunch(rc=getattr(opt,'_rc', None), log=getattr(opt,'_log',None))
コード例 #4
0
ファイル: feedbackController.py プロジェクト: Pyomo/pyomo
def initialize_model(m,nfe):
    u_profile = {0:-0.06}
    
    m.u_input = Suffix(direction=Suffix.LOCAL)
    m.u_input[m.u]=u_profile
    
    sim = Simulator(m,package='scipy')
    tsim, profiles = sim.simulate(numpoints=100, varying_inputs=m.u_input)
    
    discretizer = TransformationFactory('dae.collocation')
    discretizer.apply_to(m, nfe=nfe, ncp=1, scheme='LAGRANGE-RADAU')
    
    sim.initialize_model()
コード例 #5
0
 def apply(self, **kwds):
     instance = kwds.pop('instance')
     # Not sure why the ModifyInstance callback started passing the
     # model along with the instance.  We will ignore it.
     model = kwds.pop('model', None)
     xform = TransformationFactory('gdp.chull')
     return xform.apply_to(instance, **kwds)
コード例 #6
0
ファイル: HIV_Transmission.py プロジェクト: Pyomo/pyomo
def initialize_model(m,n_sim,n_nfe,n_ncp):
    vp_profile = {0:0.75}
    vt_profile = {0:0.75}
    
    
    m.u_input = Suffix(direction=Suffix.LOCAL)
    m.u_input[m.vp] = vp_profile
    m.u_input[m.vt] = vt_profile
    
    sim = Simulator(m, package='scipy')
    tsim, profiles = sim.simulate(numpoints=n_sim, varying_inputs=m.u_input)
    
    
    discretizer = TransformationFactory('dae.collocation')
    discretizer.apply_to(m,nfe=n_nfe,ncp=n_ncp,scheme='LAGRANGE-RADAU')
    
    sim.initialize_model()
コード例 #7
0
ファイル: solver2.py プロジェクト: Juanlu001/pyomo
 def _apply_solver(self):
     start_time = time.time()
     #
     # Cache the instance
     #
     xfrm = TransformationFactory('bilevel.linear_mpec')
     xfrm.apply_to(self._instance)
     xfrm = TransformationFactory('mpec.simple_disjunction')
     xfrm.apply_to(self._instance)
     xfrm = TransformationFactory('gdp.bigm')
     xfrm.apply_to(self._instance, default_bigM=100000)
     #
     # Solve with a specified solver
     #
     solver = self.options.solver
     if not self.options.solver:
         solver = 'glpk'
     # use the with block here so that deactivation of the
     # solver plugin always occurs thereby avoiding memory
     # leaks caused by plugins!
     with pyomo.opt.SolverFactory(solver) as opt:
         #
         self.results = []
         #
         # **NOTE: It would be better to override _presolve on the
         #         base class of this solver as you might be
         #         missing a number of keywords that were passed
         #         into the solve method (e.g., none of the
         #         io_options are getting relayed to the subsolver
         #         here).
         #
         self.results.append(opt.solve(self._instance,
                                       tee=self._tee,
                                       timelimit=self._timelimit))
     #
     stop_time = time.time()
     self.wall_time = stop_time - start_time
     #
     # Deactivate the block that contains the optimality conditions,
     # and reactivate SubModel
     #
     self._instance._transformation_data['bilevel.linear_mpec'].submodel_cuid.find_component(self._instance).activate()
     self._instance._transformation_data['bilevel.linear_mpec'].block_cuid.find_component(self._instance).deactivate()
     #
     # Return the sub-solver return condition value and log
     #
     return pyutilib.misc.Bunch(rc=getattr(opt,'_rc', None),
                                log=getattr(opt,'_log',None))
コード例 #8
0
    def _apply_solver(self):
        start_time = time.time()
        if not self.options.bigM:
            self._bigM = 999
        else:
            self._bigM = self.options.bigM
        #
        # Cache the instance
        #
        xfrm = TransformationFactory('bilevel.linear_mpec')
        xfrm.apply_to(self._instance)
        xfrm = TransformationFactory('mpec.simple_disjunction')
        xfrm.apply_to(self._instance)
        xfrm = TransformationFactory('gdp.bigm')
        xfrm.apply_to(self._instance, bigM=self.options.get('bigM',self._bigM))
        #
        ##self._instance.pprint()

        xfrm = TransformationFactory('gdp.bilinear')
        xfrm.apply_to(self._instance)
        xfrm = TransformationFactory('gdp.bigm')
        #xfrm.apply_to(self._instance, bigM=self.options.get('bigM',self._bigM))
        xfrm.apply_to(self._instance, bigM=8888)

        ##self._instance.pprint()
        #
        # Solve with a specified solver
        #
        solver = self.options.solver
        if not solver:
            solver = 'glpk'
        # use the with block here so that deactivation of the
        # solver plugin always occurs thereby avoiding memory
        # leaks caused by plugins!
        with pyomo.opt.SolverFactory(solver) as opt:
            #
            self.results = []
            #
            # **NOTE: It would be better to override _presolve on the
            #         base class of this solver as you might be
            #         missing a number of keywords that were passed
            #         into the solve method (e.g., none of the
            #         io_options are getting relayed to the subsolver
            #         here).
            #
            self.results.append(opt.solve(self._instance,
                                          tee=self._tee,
                                          timelimit=self._timelimit,
                                          symbolic_solver_labels=False,
                                          keepfiles=False
                                          ))
        #
        stop_time = time.time()
        self.wall_time = stop_time - start_time
        #self._instance.pprint()
        #self._instance.display()
        #
        # Deactivate the block that contains the optimality conditions,
        # and reactivate SubModel
        #
        submodel = self._instance._transformation_data['bilevel.linear_mpec'].submodel_cuid.find_component(self._instance)
        for (name, data) in submodel.component_map(active=False).items():
            if not isinstance(data,Var) and not isinstance(data,Set):
                data.activate()
        #
        # TODO: delete this subblock
        # TODO: Remove bilinear and bigM blocks
        #
        self._instance._transformation_data['bilevel.linear_mpec'].block_cuid.find_component(self._instance).deactivate()
        #
        # Return the sub-solver return condition value and log
        #
        return Bunch(rc=getattr(opt,'_rc', None),
                                   log=getattr(opt,'_log',None))
コード例 #9
0
    def _setup_subproblems(self, instance, bigM):
        # create transformation block
        transBlockName, transBlock = self._add_relaxation_block(
            instance, '_pyomo_gdp_cuttingplane_relaxation')

        # We store a list of all vars so that we can efficiently
        # generate maps among the subproblems
        transBlock.all_vars = list(v for v in instance.component_data_objects(
            Var,
            descend_into=(Block, Disjunct),
            sort=SortComponents.deterministic) if not v.is_fixed())

        # we'll store all the cuts we add together
        transBlock.cuts = Constraint(Any)

        # get bigM and hull relaxations
        bigMRelaxation = TransformationFactory('gdp.bigm')
        hullRelaxation = TransformationFactory('gdp.hull')
        relaxIntegrality = TransformationFactory('core.relax_integrality')

        #
        # Generalte the Hull relaxation (used for the separation
        # problem to generate cutting planes
        #
        instance_rHull = hullRelaxation.create_using(instance)
        # This relies on relaxIntegrality relaxing variables on deactivated
        # blocks, which should be fine.
        relaxIntegrality.apply_to(instance_rHull)

        #
        # Reformulate the instance using the BigM relaxation (this will
        # be the final instance returned to the user)
        #
        bigMRelaxation.apply_to(instance, bigM=bigM)

        #
        # Generate the continuous relaxation of the BigM transformation
        #
        instance_rBigM = relaxIntegrality.create_using(instance)

        #
        # Add the xstar parameter for the Hull problem
        #
        transBlock_rHull = instance_rHull.component(transBlockName)
        #
        # this will hold the solution to rbigm each time we solve it. We
        # add it to the transformation block so that we don't have to
        # worry about name conflicts.
        transBlock_rHull.xstar = Param(range(len(transBlock.all_vars)),
                                       mutable=True,
                                       default=None)

        transBlock_rBigM = instance_rBigM.component(transBlockName)

        #
        # Generate the mapping between the variables on all the
        # instances and the xstar parameter
        #
        var_info = tuple(
            (v, transBlock_rBigM.all_vars[i], transBlock_rHull.all_vars[i],
             transBlock_rHull.xstar[i])
            for i, v in enumerate(transBlock.all_vars))

        #
        # Add the separation objective to the hull subproblem
        #
        self._add_separation_objective(var_info, transBlock_rHull)

        return instance_rBigM, instance_rHull, var_info, transBlockName
コード例 #10
0
    def _apply_solver(self):
        start_time = time.time()
        #
        # Cache the instance
        #
        xfrm = TransformationFactory('pao.bilevel.linear_dual')
        xfrm.apply_to(self._instance,
                      use_dual_objective=self.use_dual_objective)
        #
        # Verify whether the model is linear
        #
        nonlinear = False
        for odata in chain(self._instance.component_objects(Objective, active=True), \
                           self._instance.component_objects(Constraint, active=True, descend_into=True)):
            if type(odata) == IndexedConstraint:
                for _name, _odata in odata.items():
                    nonlinear = _odata.expr.polynomial_degree() != 1
                    if nonlinear:
                        break
            else:
                nonlinear = odata.expr.polynomial_degree() != 1
            if nonlinear:
                # Stop after the first occurrence in the objective or one of the constraints
                break
        #
        # Apply an additional transformation to remap bilinear terms
        #
        if nonlinear:
            gdp_xfrm = TransformationFactory("gdp.bilinear")
            gdp_xfrm.apply_to(self._instance)
            mip_xfrm = TransformationFactory("gdp.bigm")
            mip_xfrm.apply_to(self._instance,
                              bigM=self.options.get('bigM', 10))
        #
        # Solve with a specified solver
        #
        solver = self.options.solver
        if not self.options.solver:  #pragma:nocover
            solver = 'glpk'
        #
        with pyomo.opt.SolverFactory(solver) as opt:
            self.results = []
            #
            #
            #opt.options['mipgap'] = self.options.get('mipgap', 0.001)
            results = opt.solve(self._instance,
                                tee=self._tee,
                                timelimit=self._timelimit)
            self.results.append(results)

            if results.solver.termination_condition not in safe_termination_conditions:
                raise Exception(
                    'Problem encountered during solve, termination_condition {}'
                    .format(results.solver.termination_condition))
            #
            # If the problem was bilinear, then reactivate the original data
            #
            if nonlinear:
                i = 0
                for v in self._instance.bilinear_data_.vlist.itervalues():
                    if abs(v.value) <= 1e-7:
                        self._instance.bilinear_data_.vlist_boolean[i] = 0
                    else:
                        self._instance.bilinear_data_.vlist_boolean[i] = 1
                    i = i + 1
                #
                self._instance.bilinear_data_.deactivate()
            if self.resolve_subproblem:
                #
                # Transform the result back into the original model
                #
                tdata = self._instance._transformation_data[
                    'pao.bilevel.linear_dual']
                count = 0
                for name_ in tdata.submodel:
                    submodel = self._instance.find_component(name_)
                    if submodel.active:
                        count += 1
                if count > 1:
                    raise Exception(
                        'Problem encountered during solve, more than one subproblem provided.'
                    )

                unfixed_tdata = list()
                # Copy variable values and fix them
                for v in tdata.fixed:
                    if not v.fixed:
                        if v.is_binary():
                            v.value = round(
                                self._instance.find_component(v).value)
                        if v.is_integer():
                            v.value = round(
                                self._instance.find_component(v).value)
                        else:
                            v.value = self._instance.find_component(v).value
                        v.fixed = True
                        unfixed_tdata.append(v)
                # Reclassify the SubModel components and resolve

                for name_ in tdata.submodel:
                    submodel = self._instance.find_component(name_)
                    submodel.activate()
                    for data in submodel.component_map(active=False).values():
                        if not isinstance(data, Var) and not isinstance(
                                data, Set):
                            data.activate()
                    _dual_name = name_ + '_dual'
                    _parent = submodel.parent_block()
                    if type(_parent) == _BlockData:
                        _dual_name = _dual_name.replace(_parent.name + ".", "")
                        dual_submodel = getattr(_parent, _dual_name)
                        dual_submodel.deactivate()
                        pyomo.common.PyomoAPIFactory(
                            'pyomo.repn.compute_standard_repn')({},
                                                                model=submodel)
                        _submodel_name = name_.replace(_parent.name + ".", "")
                        _parent.reclassify_component_type(
                            _submodel_name, Block)
                    else:
                        dual_submodel = self._instance.find_component(
                            _dual_name)
                        dual_submodel.deactivate()
                        pyomo.common.PyomoAPIFactory(
                            'pyomo.repn.compute_standard_repn')({},
                                                                model=submodel)
                        self._instance.reclassify_component_type(name_, Block)
                    #
                    # Use the with block here so that deactivation of the
                    # solver plugin always occurs thereby avoiding memory
                    # leaks caused by plugins!
                    #

                with pyomo.opt.SolverFactory(solver) as opt_inner:
                    #
                    # **NOTE: It would be better to override _presolve on the
                    #         base class of this solver as you might be
                    #         missing a number of keywords that were passed
                    #         into the solve method (e.g., none of the
                    #         io_options are getting relayed to the subsolver
                    #         here).
                    #
                    #opt_inner.options['mipgap'] = self.options.get('mipgap', 0.001)
                    results = opt_inner.solve(self._instance,
                                              tee=self._tee,
                                              timelimit=self._timelimit)
                    self.results.append(results)

                # Unfix variables
                for v in tdata.fixed:
                    if v in unfixed_tdata:
                        v.fixed = False

            # check that the solutions list is not empty
            if self._instance.solutions.solutions:
                self._instance.solutions.select(0, ignore_fixed_vars=True)
            #
            stop_time = time.time()
            self.wall_time = stop_time - start_time
            self.results_obj = self._setup_results_obj()
            #
            # Reactivate top level objective
            # and reclassify the submodel
            #
            for odata in self._instance.component_map(Objective).values():
                odata.activate()
            #
            # Return the sub-solver return condition value and log
            #
            return pyutilib.misc.Bunch(rc=getattr(opt, '_rc', None),
                                       log=getattr(opt, '_log', None))
コード例 #11
0
ファイル: cuttingplane.py プロジェクト: Pyomo/pyomo
    def _setup_subproblems(self, instance, bigM):
        # create transformation block
        transBlockName, transBlock = self._add_relaxation_block(
            instance,
            '_pyomo_gdp_cuttingplane_relaxation')

        # We store a list of all vars so that we can efficiently
        # generate maps among the subproblems
        transBlock.all_vars = list(v for v in instance.component_data_objects(
            Var,
            descend_into=(Block, Disjunct),
            sort=SortComponents.deterministic) if not v.is_fixed())

        # we'll store all the cuts we add together
        transBlock.cuts = Constraint(Any)

        # get bigM and chull relaxations
        bigMRelaxation = TransformationFactory('gdp.bigm')
        chullRelaxation = TransformationFactory('gdp.chull')
        relaxIntegrality = TransformationFactory('core.relax_integrality')

        # HACK: for the current writers, we need to also apply gdp.reclassify so
        # that the indicator variables stay where they are in the big M model
        # (since that is what we are eventually going to solve after we add our
        # cuts).
        reclassify = TransformationFactory('gdp.reclassify')

        #
        # Generalte the CHull relaxation (used for the separation
        # problem to generate cutting planes
        #
        instance_rCHull = chullRelaxation.create_using(instance)
        # This relies on relaxIntegrality relaxing variables on deactivated
        # blocks, which should be fine.
        reclassify.apply_to(instance_rCHull)
        relaxIntegrality.apply_to(instance_rCHull)

        #
        # Reformulate the instance using the BigM relaxation (this will
        # be the final instance returned to the user)
        #
        bigMRelaxation.apply_to(instance, bigM=bigM)
        reclassify.apply_to(instance)

        #
        # Generate the continuous relaxation of the BigM transformation
        #
        instance_rBigM = relaxIntegrality.create_using(instance)

        #
        # Add the xstar parameter for the CHull problem
        #
        transBlock_rCHull = instance_rCHull.component(transBlockName)
        #
        # this will hold the solution to rbigm each time we solve it. We
        # add it to the transformation block so that we don't have to
        # worry about name conflicts.
        transBlock_rCHull.xstar = Param(
            range(len(transBlock.all_vars)), mutable=True, default=None)

        transBlock_rBigM = instance_rBigM.component(transBlockName)

        #
        # Generate the mapping between the variables on all the
        # instances and the xstar parameter
        #
        var_info = tuple(
            (v,
             transBlock_rBigM.all_vars[i],
             transBlock_rCHull.all_vars[i],
             transBlock_rCHull.xstar[i])
            for i,v in enumerate(transBlock.all_vars))

        #
        # Add the separation objective to the chull subproblem
        #
        self._add_separation_objective(var_info, transBlock_rCHull)

        return instance_rBigM, instance_rCHull, var_info, transBlockName
コード例 #12
0
def solve_linear_GDP(linear_GDP_model, solve_data, config):
    """Solves the linear GDP model and attempts to resolve solution issues."""
    m = linear_GDP_model
    GDPopt = m.GDPopt_utils
    # Transform disjunctions
    _bigm = TransformationFactory('gdp.bigm')
    _bigm.handlers[Port] = False
    _bigm.apply_to(m)

    preprocessing_transformations = [
        # # Propagate variable bounds
        # 'contrib.propagate_eq_var_bounds',
        # # Detect fixed variables
        # 'contrib.detect_fixed_vars',
        # # Propagate fixed variables
        # 'contrib.propagate_fixed_vars',
        # # Remove zero terms in linear expressions
        # 'contrib.remove_zero_terms',
        # # Remove terms in equal to zero summations
        # 'contrib.propagate_zero_sum',
        # # Transform bound constraints
        # 'contrib.constraints_to_var_bounds',
        # # Detect fixed variables
        # 'contrib.detect_fixed_vars',
        # # Remove terms in equal to zero summations
        # 'contrib.propagate_zero_sum',
        # Remove trivial constraints
        'contrib.deactivate_trivial_constraints',
    ]
    if config.mip_presolve:
        try:
            fbbt(m, integer_tol=config.integer_tolerance)
            for xfrm in preprocessing_transformations:
                TransformationFactory(xfrm).apply_to(m)
        except InfeasibleConstraintException:
            config.logger.debug("MIP preprocessing detected infeasibility.")
            mip_result = MasterProblemResult()
            mip_result.feasible = False
            mip_result.var_values = list(v.value for v in GDPopt.variable_list)
            mip_result.pyomo_results = SolverResults()
            mip_result.pyomo_results.solver.termination_condition = tc.error
            mip_result.disjunct_values = list(disj.indicator_var.value
                                              for disj in GDPopt.disjunct_list)
            return mip_result

    # Deactivate extraneous IMPORT/EXPORT suffixes
    getattr(m, 'ipopt_zL_out', _DoNothing()).deactivate()
    getattr(m, 'ipopt_zU_out', _DoNothing()).deactivate()

    # Create solver, check availability
    if not SolverFactory(config.mip_solver).available():
        raise RuntimeError("MIP solver %s is not available." %
                           config.mip_solver)

    # Callback immediately before solving MIP master problem
    config.call_before_master_solve(m, solve_data)

    try:
        with SuppressInfeasibleWarning():
            mip_args = dict(config.mip_solver_args)
            elapsed = get_main_elapsed_time(solve_data.timing)
            remaining = max(config.time_limit - elapsed, 1)
            if config.mip_solver == 'gams':
                mip_args['add_options'] = mip_args.get('add_options', [])
                mip_args['add_options'].append('option reslim=%s;' % remaining)
            elif config.mip_solver == 'multisolve':
                mip_args['time_limit'] = min(
                    mip_args.get('time_limit', float('inf')), remaining)
            results = SolverFactory(config.mip_solver).solve(m, **mip_args)
    except RuntimeError as e:
        if 'GAMS encountered an error during solve.' in str(e):
            config.logger.warning(
                "GAMS encountered an error in solve. Treating as infeasible.")
            mip_result = MasterProblemResult()
            mip_result.feasible = False
            mip_result.var_values = list(v.value for v in GDPopt.variable_list)
            mip_result.pyomo_results = SolverResults()
            mip_result.pyomo_results.solver.termination_condition = tc.error
            mip_result.disjunct_values = list(disj.indicator_var.value
                                              for disj in GDPopt.disjunct_list)
            return mip_result
        else:
            raise
    terminate_cond = results.solver.termination_condition
    if terminate_cond is tc.infeasibleOrUnbounded:
        # Linear solvers will sometimes tell me that it's infeasible or
        # unbounded during presolve, but fails to distinguish. We need to
        # resolve with a solver option flag on.
        results, terminate_cond = distinguish_mip_infeasible_or_unbounded(
            m, config)
    if terminate_cond is tc.unbounded:
        # Solution is unbounded. Add an arbitrary bound to the objective and resolve.
        # This occurs when the objective is nonlinear. The nonlinear objective is moved
        # to the constraints, and deactivated for the linear master problem.
        obj_bound = 1E15
        config.logger.warning(
            'Linear GDP was unbounded. '
            'Resolving with arbitrary bound values of (-{0:.10g}, {0:.10g}) on the objective. '
            'Check your initialization routine.'.format(obj_bound))
        main_objective = next(m.component_data_objects(Objective, active=True))
        GDPopt.objective_bound = Constraint(expr=(-obj_bound,
                                                  main_objective.expr,
                                                  obj_bound))
        with SuppressInfeasibleWarning():
            results = SolverFactory(config.mip_solver).solve(
                m, **config.mip_solver_args)
        terminate_cond = results.solver.termination_condition

    # Build and return results object
    mip_result = MasterProblemResult()
    mip_result.feasible = True
    mip_result.var_values = list(v.value for v in GDPopt.variable_list)
    mip_result.pyomo_results = results
    mip_result.disjunct_values = list(disj.indicator_var.value
                                      for disj in GDPopt.disjunct_list)

    if terminate_cond is tc.optimal or terminate_cond is tc.locallyOptimal:
        pass
    elif terminate_cond is tc.infeasible:
        config.logger.info(
            'Linear GDP is now infeasible. '
            'GDPopt has finished exploring feasible discrete configurations.')
        mip_result.feasible = False
    elif terminate_cond is tc.maxTimeLimit:
        # TODO check that status is actually ok and everything is feasible
        config.logger.info(
            'Unable to optimize linear GDP problem within time limit. '
            'Using current solver feasible solution.')
    elif (terminate_cond is tc.other
          and results.solution.status is SolutionStatus.feasible):
        # load the solution and suppress the warning message by setting
        # solver status to ok.
        config.logger.info('Linear GDP solver reported feasible solution, '
                           'but not guaranteed to be optimal.')
    else:
        raise ValueError('GDPopt unable to handle linear GDP '
                         'termination condition '
                         'of %s. Solver message: %s' %
                         (terminate_cond, results.solver.message))

    return mip_result
コード例 #13
0
    def _apply_solver(self):
        start_time = time.time()
        #
        # Cache the instance
        #
        xfrm = TransformationFactory('bilevel.linear_dual')
        xfrm.apply_to(self._instance)
        #
        # Verify whether the objective is linear
        #
        nonlinear = False
        for odata in self._instance.component_objects(Objective, active=True):
            nonlinear = odata.expr.polynomial_degree() != 1
            # Stop after the first objective
            break
        #
        # Apply an additional transformation to remap bilinear terms
        #
        if nonlinear:
            gdp_xfrm = TransformationFactory("gdp.bilinear")
            gdp_xfrm.apply_to(self._instance)
            mip_xfrm = TransformationFactory("gdp.bigm")
            mip_xfrm.apply_to(self._instance,
                              bigM=self.options.get('bigM', 100000))
        #
        # Solve with a specified solver
        #
        solver = self.options.solver
        if not self.options.solver:
            solver = 'glpk'

        # use the with block here so that deactivation of the
        # solver plugin always occurs thereby avoiding memory
        # leaks caused by plugins!
        with pyomo.opt.SolverFactory(solver) as opt:
            self.results = []
            #
            # **NOTE: It would be better to override _presolve on the
            #         base class of this solver as you might be
            #         missing a number of keywords that were passed
            #         into the solve method (e.g., none of the
            #         io_options are getting relayed to the subsolver
            #         here).
            #
            self.results.append(
                opt.solve(self._instance,
                          tee=self._tee,
                          timelimit=self._timelimit))
            #print("POST-SOLVE - BEGIN")
            #self._instance.write("tmp.lp", io_options={"symbolic_solver_labels":True})
            #self._instance.pprint()
            #self._instance.display()
            #print("POST-SOLVE - END")
            #
            # If the problem was bilinear, then reactivate the original data
            #
            if nonlinear:
                i = 0
                for v in self._instance.bilinear_data_.vlist.itervalues():
                    #print(v)
                    #print(v.name)
                    #print(type(v))
                    #print(v.value)
                    if abs(v.value) <= 1e-7:
                        self._instance.bilinear_data_.vlist_boolean[i] = 0
                    else:
                        self._instance.bilinear_data_.vlist_boolean[i] = 1
                    i = i + 1
                #
                self._instance.bilinear_data_.deactivate()
            #
            # Transform the result back into the original model
            #
            tdata = self._instance._transformation_data['bilevel.linear_dual']
            unfixed_cuids = set()
            # Copy variable values and fix them
            for vuid in tdata.fixed:
                for index_, data_ in vuid.find_component_on(
                        self._instance).iteritems():
                    if not data_.fixed:
                        data_.value = self._instance.find_component(
                            data_).value
                        data_.fixed = True
                        unfixed_cuids.add(ComponentUID(data_))
            # Reclassify the SubModel components and resolve
            for name_ in tdata.submodel:
                submodel = getattr(self._instance, name_)
                submodel.activate()
                for (name,
                     data) in submodel.component_map(active=False).items():
                    if not isinstance(data, Var) and not isinstance(data, Set):
                        data.activate()
                dual_submodel = getattr(self._instance, name_ + '_dual')
                dual_submodel.deactivate()
                pyomo.common.PyomoAPIFactory(
                    'pyomo.repn.compute_standard_repn')({}, model=submodel)
                self._instance.reclassify_component_type(name_, Block)
                # use the with block here so that deactivation of the
                # solver plugin always occurs thereby avoiding memory
                # leaks caused by plugins!
                with pyomo.opt.SolverFactory(solver) as opt_inner:
                    #
                    # **NOTE: It would be better to override _presolve on the
                    #         base class of this solver as you might be
                    #         missing a number of keywords that were passed
                    #         into the solve method (e.g., none of the
                    #         io_options are getting relayed to the subsolver
                    #         here).
                    #
                    results = opt_inner.solve(self._instance,
                                              tee=self._tee,
                                              timelimit=self._timelimit)
                    #select=None)
            # Unfix variables
            for vuid in tdata.fixed:
                for index_, data_ in vuid.find_component_on(
                        self._instance).iteritems():
                    if ComponentUID(data_) in unfixed_cuids:
                        data_.fixed = False
            #
            self._instance.solutions.select(0, ignore_fixed_vars=True)
            self.results.append(results)
            #
            stop_time = time.time()
            self.wall_time = stop_time - start_time
            self.results_obj = self._setup_results_obj()
            #
            # Reactivate top level objective
            # and reclassify the submodel
            #
            for oname, odata in self._instance.component_map(
                    Objective).items():
                odata.activate()
            # TODO: rework the Block logic to allow for searching SubModel objects for variables, etc.
            #data_.parent_component().parent_block().reclassify_component_type(name_, SubModel)
            #
            # Return the sub-solver return condition value and log
            #
            return pyutilib.misc.Bunch(rc=getattr(opt, '_rc', None),
                                       log=getattr(opt, '_log', None))
コード例 #14
0
ファイル: interscenario.py プロジェクト: Pyomo/pyomo
def get_dual_values(solver, model):
    if id(model) not in get_dual_values.discrete_stage2_vars:
        # 1st attempt to get duals: we need to see if the model has
        # discrete variables (solvers won't give duals if there are
        # still active discrete variables)
        try:
            get_dual_values.discrete_stage2_vars[id(model)] = False
            return get_dual_values(solver, model)
        except:
            get_dual_values.discrete_stage2_vars[id(model)] = True
            # Find the discrete variables to populate the list
            return get_dual_values(solver, model)

    duals = {}
    _con = model._interscenario_plugin.fixed_variables_constraint

    if get_dual_values.discrete_stage2_vars[id(model)]:
        # Fix all discrete variables
        xfrm = TransformationFactory('core.relax_discrete')
        if PYOMO_4_0:
            xfrm.apply(model, inplace=True)
        else:
            xfrm.apply_to(model)

        # Note: preprocessing is only necessary if we are changing a
        # fixed/freed variable.
        if FALLBACK_ON_BRUTE_FORCE_PREPROCESS:
            model.preprocess()
        else:
            _map = {}
            preprocess_block_constraints(
                model._interscenario_plugin, idMap=_map)

        #SOLVE
        results = solver.solve(model, warmstart=True)
        ss = results.solver.status
        tc = results.solver.termination_condition
        #self.timeInSolver += results['Solver'][0]['Time']
        if ss == SolverStatus.ok and tc in _acceptable_termination_conditions:
            state = ''
        elif tc in _infeasible_termination_conditions:
            state = 'INFEASIBLE'
        else:
            state = 'NONOPTIMAL'
        if state:
            logger.warning(
                "Resolving subproblem model with relaxed second-stage "
                "discrete variables failed (%s).  "
                "Dual values not available." % (state,) )
        else:
            # Get the duals
            if PYOMO_4_0:
                model.load(results)
            else:
                model.solutions.load_from(results)
            #model.dual.pprint()
            for varid in model._interscenario_plugin.STAGE1VAR:
                duals[varid] = model.dual[_con[varid]]
        # Free the discrete second-stage variables
        if PYOMO_4_0:
            xfrm.apply(model, inplace=True, undo=True)
        else:
            xfrm.apply_to(model, undo=True)

    else:
        # return the duals
        for varid in model._interscenario_plugin.STAGE1VAR:
            duals[varid] = model.dual[_con[varid]]

    return duals
コード例 #15
0
ファイル: solver1.py プロジェクト: SemanticBeeng/pyomo
    def _apply_solver(self):
        start_time = time.time()
        #
        # Cache the instance
        #
        xfrm = TransformationFactory('bilevel.linear_dual')
        xfrm.apply_to(self._instance)
        #
        # Verify whether the objective is linear
        #
        nonlinear=False
        for odata in self._instance.component_objects(Objective, active=True):
            nonlinear = odata.expr.polynomial_degree() != 1
            # Stop after the first objective
            break
        #
        # Apply an additional transformation to remap bilinear terms
        #
        if nonlinear:
            gdp_xfrm = TransformationFactory("gdp.bilinear")
            gdp_xfrm.apply_to(self._instance)
            mip_xfrm = TransformationFactory("gdp.bigm")
            mip_xfrm.apply_to(self._instance, default_bigM=self.options.get('bigM',100000))
        #
        # Solve with a specified solver
        #
        solver = self.options.solver
        if not self.options.solver:
            solver = 'glpk'

        # use the with block here so that deactivation of the
        # solver plugin always occurs thereby avoiding memory
        # leaks caused by plugins!
        with pyomo.opt.SolverFactory(solver) as opt:
            self.results = []
            #
            # **NOTE: It would be better to override _presolve on the
            #         base class of this solver as you might be
            #         missing a number of keywords that were passed
            #         into the solve method (e.g., none of the
            #         io_options are getting relayed to the subsolver
            #         here).
            #
            self.results.append(opt.solve(self._instance,
                                          tee=self._tee,
                                          timelimit=self._timelimit))
            #print("POST-SOLVE - BEGIN")
            #self._instance.write("tmp.lp", io_options={"symbolic_solver_labels":True})
            #self._instance.pprint()
            #self._instance.display()
            #print("POST-SOLVE - END")
            #
            # If the problem was bilinear, then reactivate the original data
            #
            if nonlinear:
                i = 0
                for v in self._instance.bilinear_data_.vlist.itervalues():
                    #print(v)
                    #print(v.cname())
                    #print(type(v))
                    #print(v.value)
                    if abs(v.value) <= 1e-7:
                        self._instance.bilinear_data_.vlist_boolean[i] = 0
                    else:
                        self._instance.bilinear_data_.vlist_boolean[i] = 1
                    i = i + 1
                #
                self._instance.bilinear_data_.deactivate()
            #
            # Transform the result back into the original model
            #
            tdata = self._instance._transformation_data['bilevel.linear_dual']
            unfixed_cuids = set()
            # Copy variable values and fix them
            for vuid in tdata.fixed:
                for index_, data_ in vuid.find_component_on(self._instance).iteritems():
                    if not data_.fixed:
                        data_.value = self._instance.find_component(data_).value
                        data_.fixed = True
                        unfixed_cuids.add(ComponentUID(data_))
            # Reclassify the SubModel components and resolve
            for name_ in tdata.submodel:
                submodel = getattr(self._instance, name_)
                submodel.activate()
                for (name, data) in submodel.component_map(active=False).items():
                    if not isinstance(data,Var) and not isinstance(data,Set):
                        data.activate()
                dual_submodel = getattr(self._instance, name_+'_dual')
                dual_submodel.deactivate()
                pyomo.util.PyomoAPIFactory('pyomo.repn.compute_canonical_repn')({}, model=submodel)
                self._instance.reclassify_component_type(name_, Block)
                # use the with block here so that deactivation of the
                # solver plugin always occurs thereby avoiding memory
                # leaks caused by plugins!
                with pyomo.opt.SolverFactory(solver) as opt_inner:
                    #
                    # **NOTE: It would be better to override _presolve on the
                    #         base class of this solver as you might be
                    #         missing a number of keywords that were passed
                    #         into the solve method (e.g., none of the
                    #         io_options are getting relayed to the subsolver
                    #         here).
                    #
                    results = opt_inner.solve(self._instance, tee=self._tee, timelimit=self._timelimit)
                                                        #select=None)
            # Unfix variables
            for vuid in tdata.fixed:
                for index_, data_ in vuid.find_component_on(self._instance).iteritems():
                    if ComponentUID(data_) in unfixed_cuids:
                        data_.fixed = False
            #
            self._instance.solutions.select(0, ignore_fixed_vars=True)
            self.results.append(results)
            #
            stop_time = time.time()
            self.wall_time = stop_time - start_time
            self.results_obj = self._setup_results_obj()
            #
            # Reactivate top level objective
            # and reclassify the submodel
            #
            for oname, odata in self._instance.component_map(Objective).items():
                odata.activate()
            # TODO: rework the Block logic to allow for searching SubModel objects for variables, etc.
            #data_.parent_component().parent_block().reclassify_component_type(name_, SubModel)
            #
            # Return the sub-solver return condition value and log
            #
            return pyutilib.misc.Bunch(rc=getattr(opt,'_rc', None),
                                       log=getattr(opt,'_log',None))
コード例 #16
0
def solve_NLP_subproblem(solve_data, config):
    m = solve_data.working_model.clone()
    MindtPy = m.MindtPy_utils
    main_objective = next(m.component_data_objects(Objective, active=True))
    solve_data.nlp_iter += 1
    config.logger.info('NLP %s: Solve subproblem for fixed binaries.' %
                       (solve_data.nlp_iter, ))
    # Set up NLP
    for v in MindtPy.variable_list:
        if v.is_binary():
            v.fix(int(round(value(v))))

    # restore original variable values
    for nlp_var, orig_val in zip(MindtPy.variable_list,
                                 solve_data.initial_var_values):
        if not nlp_var.fixed and not nlp_var.is_binary():
            nlp_var.value = orig_val

    MindtPy.MindtPy_linear_cuts.deactivate()
    m.tmp_duals = ComponentMap()
    for c in m.component_data_objects(ctype=Constraint,
                                      active=True,
                                      descend_into=True):
        rhs = ((0 if c.upper is None else c.upper) +
               (0 if c.lower is None else c.lower))
        sign_adjust = 1 if value(c.upper) is None else -1
        m.tmp_duals[c] = sign_adjust * max(0,
                                           sign_adjust * (rhs - value(c.body)))
        # TODO check sign_adjust
    t = TransformationFactory('contrib.deactivate_trivial_constraints')
    t.apply_to(m, tmp=True, ignore_infeasible=True)
    # Solve the NLP
    # m.pprint() # print nlp problem for debugging
    with SuppressInfeasibleWarning():
        results = SolverFactory(config.nlp_solver).solve(
            m, **config.nlp_solver_args)
    var_values = list(v.value for v in MindtPy.variable_list)
    subprob_terminate_cond = results.solver.termination_condition
    if subprob_terminate_cond is tc.optimal:
        copy_var_list_values(
            m.MindtPy_utils.variable_list,
            solve_data.working_model.MindtPy_utils.variable_list, config)
        for c in m.tmp_duals:
            if m.dual.get(c, None) is None:
                m.dual[c] = m.tmp_duals[c]
        duals = list(m.dual[c] for c in MindtPy.constraint_list)
        if main_objective.sense == minimize:
            solve_data.UB = min(value(main_objective.expr), solve_data.UB)
            solve_data.solution_improved = solve_data.UB < solve_data.UB_progress[
                -1]
            solve_data.UB_progress.append(solve_data.UB)
        else:
            solve_data.LB = max(value(main_objective.expr), solve_data.LB)
            solve_data.solution_improved = solve_data.LB > solve_data.LB_progress[
                -1]
            solve_data.LB_progress.append(solve_data.LB)
        config.logger.info('NLP {}: OBJ: {}  LB: {}  UB: {}'.format(
            solve_data.nlp_iter, value(main_objective.expr), solve_data.LB,
            solve_data.UB))
        if solve_data.solution_improved:
            solve_data.best_solution_found = m.clone()
        # Add the linear cut
        if config.strategy == 'OA':
            add_oa_cut(var_values, duals, solve_data, config)
        elif config.strategy == 'PSC':
            add_psc_cut(solve_data, config)
        elif config.strategy == 'GBD':
            add_gbd_cut(solve_data, config)

        # This adds an integer cut to the feasible_integer_cuts
        # ConstraintList, which is not activated by default. However, it
        # may be activated as needed in certain situations or for certain
        # values of option flags.
        add_int_cut(var_values, solve_data, config, feasible=True)

        config.call_after_subproblem_feasible(m, solve_data)
    elif subprob_terminate_cond is tc.infeasible:
        # TODO try something else? Reinitialize with different initial
        # value?
        config.logger.info('NLP subproblem was locally infeasible.')
        for c in m.component_data_objects(ctype=Constraint,
                                          active=True,
                                          descend_into=True):
            rhs = ((0 if c.upper is None else c.upper) +
                   (0 if c.lower is None else c.lower))
            sign_adjust = 1 if value(c.upper) is None else -1
            m.dual[c] = sign_adjust * max(0, sign_adjust *
                                          (rhs - value(c.body)))
        for var in m.component_data_objects(ctype=Var, descend_into=True):

            if config.strategy == 'PSC' or config.strategy == 'GBD':
                m.ipopt_zL_out[var] = 0
                m.ipopt_zU_out[var] = 0
                if var.ub is not None and abs(
                        var.ub - value(var)) < config.bound_tolerance:
                    m.ipopt_zL_out[var] = 1
                elif var.lb is not None and abs(
                        value(var) - var.lb) < config.bound_tolerance:
                    m.ipopt_zU_out[var] = -1
        # m.pprint() #print infeasible nlp problem for debugging
        if config.strategy == 'OA':
            config.logger.info('Solving feasibility problem')
            if config.initial_feas:
                # add_feas_slacks(m, solve_data)
                # config.initial_feas = False
                var_values, duals = solve_NLP_feas(solve_data, config)
                add_oa_cut(var_values, duals, solve_data, config)
        # Add an integer cut to exclude this discrete option
        add_int_cut(var_values, solve_data, config)
    elif subprob_terminate_cond is tc.maxIterations:
        # TODO try something else? Reinitialize with different initial
        # value?
        config.logger.info(
            'NLP subproblem failed to converge within iteration limit.')
        # Add an integer cut to exclude this discrete option
        add_int_cut(solve_data, config)
    else:
        raise ValueError('MindtPy unable to handle NLP subproblem termination '
                         'condition of {}'.format(subprob_terminate_cond))

    # Call the NLP post-solve callback
    config.call_after_subproblem_solve(m, solve_data)
コード例 #17
0
    def _apply_solver(self):
        self.results = []
        start_time = time.time()
        #
        # Solve with a specified solver
        #
        solver = self.options.solver
        if not self.options.solver:
            solver = 'gurobi'

        bigm = TransformationFactory('gdp.bigm')

        # Step 1. Initialization
        LB = -inf
        UB = inf
        theta = 0.
        xi = 10e-3
        k = 0
        epsilon = 1e-4
        M = 1e6

        # matrix representation for bilevel problem
        matrix_repn = BilevelMatrixRepn(self._instance)

        # each lower-level problem
        submodel = [
            block for block in self._instance.component_objects(SubModel)
        ][0]
        if len(submodel) != 1:
            raise Exception(
                'Problem encountered, this is not a valid bilevel model for the solver.'
            )
        self._instance.reclassify_component_type(submodel, Block)
        varref(submodel)
        dataref(submodel)

        # all algorithm blocks
        algorithm_blocks = list()
        algorithm_blocks.append(submodel)

        all_vars = {key: var for (key, var) in matrix_repn._all_vars.items()}
        # for k,v in all_vars.items():
        #     if v.ub is None:
        #         v.setub(M)
        #     if v.lb is None:
        #         v.setlb(-M)

        # get the variables that are fixed for the submodel (lower-level block)
        fixed_vars = {
            key: var
            for (key, var) in matrix_repn._all_vars.items()
            if key in matrix_repn._fixed_var_ids[submodel.name]
        }

        # continuous variables in SubModel
        c_vars = {
            key: var
            for (key, var) in matrix_repn._all_vars.items()
            if key in matrix_repn._c_var_ids - fixed_vars.keys()
        }

        # binary variables in SubModel
        b_vars = {
            key: var
            for (key, var) in matrix_repn._all_vars.items()
            if key in matrix_repn._b_var_ids - fixed_vars.keys()
        }

        # integer variables in SubModel
        i_vars = {
            key: var
            for (key, var) in matrix_repn._all_vars.items()
            if key in matrix_repn._i_var_ids - fixed_vars.keys()
        }

        # get constraint information related to constraint id, sign, and rhs value
        sub_cons = matrix_repn._cons_sense_rhs[submodel.name]

        # lower bounding block name -- unique naming convention
        _lower_model_name = '_p9'
        _lower_model_name = unique_component_name(self._instance,
                                                  _lower_model_name)

        # upper bounding block name -- unique naming convention
        _upper_model_name = '_p7'
        _upper_model_name = unique_component_name(self._instance,
                                                  _upper_model_name)

        while k <= self._k_max_iter:
            # Step 2. Lower Bounding
            # Solve problem (P5) master problem.
            # This includes equations (53), (12), (13), (15), and (54)
            # On iteration k = 0, (54) does not exist. Instead of implementing (54),
            # this approach applies problem (P9) which incorporates KKT-based tightening
            # constraints, and a projection and indicator constraint set.
            lower_bounding_master = getattr(self._instance, _lower_model_name,
                                            None)
            if lower_bounding_master is None:
                xfrm = TransformationFactory('pao.bilevel.highpoint')
                kwds = {'submodel_name': _lower_model_name}
                xfrm.apply_to(self._instance, **kwds)
                lower_bounding_master = getattr(self._instance,
                                                _lower_model_name)
                algorithm_blocks.append(lower_bounding_master)

                _c_var_bounds_rule = lambda m, k: c_vars[k].bounds
                _c_var_init_rule = lambda m, k: (c_vars[k].lb + c_vars[k].ub
                                                 ) / 2
                lower_bounding_master._iter_c = Var(
                    Any, bounds=(0, M), within=Reals,
                    dense=False)  # set (iter k, c_var_ids)
                lower_bounding_master._iter_c_tilde = Var(
                    c_vars.keys(),
                    bounds=_c_var_bounds_rule,
                    initialize=_c_var_init_rule,
                    within=Reals)  # set (iter k, c_var_ids)
                lower_bounding_master._iter_b = Var(
                    Any, within=Binary, bounds=(0, M),
                    dense=False)  # set (iter k, b_var_ids)
                lower_bounding_master._iter_i = Var(
                    Any, within=Integers, bounds=(0, M),
                    dense=False)  # set (iter k, i_var_ids)

                lower_bounding_master._iter_pi_tilde = Var(
                    sub_cons.keys(),
                    bounds=(0, M))  # set (iter k, sub_cons_ids)
                lower_bounding_master._iter_pi = Var(
                    Any, bounds=(0, M),
                    dense=False)  # set (iter k, sub_cons_ids)
                lower_bounding_master._iter_t = Var(
                    Any, bounds=(0, M),
                    dense=False)  # set (iter k, sub_cons_ids)
                lower_bounding_master._iter_lambda = Var(
                    Any, bounds=(0, M),
                    dense=False)  # set (iter k, sub_cons_ids)
                m = lower_bounding_master  # shorthand reference to model

            if k == 0:
                # constraint (74)
                lhs_expr = 0.
                rhs_expr = 0.
                for _vid, var in c_vars.items():
                    (C, C_q,
                     C_constant) = matrix_repn.cost_vectors(submodel, var)
                    coef = float(C)  # + dot(C_q,_fixed))
                    ref = m._map[var]
                    lhs_expr += coef * ref
                    rhs_expr += coef * m._iter_c_tilde[_vid]
                expr = lhs_expr >= rhs_expr
                if not type(expr) is bool:
                    lower_bounding_master.KKT_tight1 = Constraint(
                        expr=lhs_expr >= rhs_expr)

                # constraint (75a)
                lower_bounding_master.KKT_tight2a = Constraint(sub_cons.keys())
                lhs_expr_a = {key: 0. for key in sub_cons.keys()}
                rhs_expr_a = {key: 0. for key in sub_cons.keys()}
                for _vid, var in c_vars.items():
                    (A, A_q, sign,
                     b) = matrix_repn.coef_matrices(submodel, var)
                    coef = A  #+ dot(A_q.toarray(), _fixed)
                    for _cid in sub_cons.keys():
                        idx = list(sub_cons.keys()).index(_cid)
                        lhs_expr_a[_cid] += float(
                            coef[idx]) * m._iter_c_tilde[_vid]

                for var in {**b_vars, **i_vars, **fixed_vars}.values():
                    (A, A_q, sign,
                     b) = matrix_repn.coef_matrices(submodel, var)
                    coef = A  #+ dot(A_q.toarray(), _fixed)
                    for _cid in sub_cons.keys():
                        idx = list(sub_cons.keys()).index(_cid)
                        ref = m._map[var]
                        rhs_expr_a[_cid] += -float(coef[idx]) * ref

                for _cid, b in sub_cons.items():
                    (_, sign) = _cid
                    rhs_expr_a[_cid] += b
                    if sign == 'l' or sign == 'g->l':
                        expr = lhs_expr_a[_cid] <= rhs_expr_a[_cid]
                    if sign == 'e' or sign == 'g':
                        raise Exception(
                            'Problem encountered, this problem is not in standard form.'
                        )
                    if not type(expr) is bool:
                        lower_bounding_master.KKT_tight2a[_cid] = expr
                    else:
                        lower_bounding_master.KKT_tight2a[
                            _cid] = Constraint.Skip

                # constraint (75b)
                lower_bounding_master.KKT_tight2b = Constraint(c_vars.keys())
                lhs_expr_b = {key: 0. for key in c_vars.keys()}
                rhs_expr_b = {key: 0. for key in c_vars.keys()}
                for _vid, var in c_vars.items():
                    (A, A_q, sign,
                     b) = matrix_repn.coef_matrices(submodel, var)
                    coef = A  #+ dot(A_q.toarray(), _fixed)
                    for _cid in sub_cons.keys():
                        idx = list(sub_cons.keys()).index(_cid)
                        lhs_expr_b[_vid] += float(
                            coef[idx]) * m._iter_pi_tilde[_cid]

                    (C, C_q,
                     C_constant) = matrix_repn.cost_vectors(submodel, var)
                    rhs_expr_b[_vid] = float(C)  #+ dot(C_q,_fixed))

                    expr = lhs_expr_b[_vid] >= rhs_expr_b[_vid]
                    if not type(expr) is bool:
                        lower_bounding_master.KKT_tight2b[_vid] = expr
                    else:
                        lower_bounding_master.KKT_tight2b[
                            _vid] = Constraint.Skip

                # constraint (76a)
                lower_bounding_master.KKT_tight3a = ComplementarityList()
                for _vid in c_vars.keys():
                    lower_bounding_master.KKT_tight3a.add(
                        complements(m._iter_c_tilde[_vid] >= 0,
                                    lhs_expr_b[_vid] - rhs_expr_b[_vid] >= 0))

                # constraint (76b)
                lower_bounding_master.KKT_tight3b = ComplementarityList()
                for _cid in sub_cons.keys():
                    lower_bounding_master.KKT_tight3b.add(
                        complements(m._iter_pi_tilde[_cid] >= 0,
                                    rhs_expr_a[_cid] - lhs_expr_a[_cid] >= 0))

                # constraint (77a)
                lower_bounding_master.KKT_tight4a = Constraint(c_vars.keys())
                for _vid in c_vars.keys():
                    lower_bounding_master.KKT_tight4a[
                        _vid] = m._iter_c_tilde[_vid] >= 0

                # constraint (77b)
                lower_bounding_master.KKT_tight4b = Constraint(sub_cons.keys())
                for _cid in sub_cons.keys():
                    lower_bounding_master.KKT_tight4b[
                        _cid] = m._iter_pi_tilde[_cid] >= 0

            # solve the HPR and check the termination condition
            lower_bounding_master.activate()
            TransformationFactory('mpec.simple_disjunction').apply_to(
                lower_bounding_master)
            bigm.apply_to(lower_bounding_master)

            with pyomo.opt.SolverFactory(solver) as opt:
                self.results.append(
                    opt.solve(lower_bounding_master,
                              tee=self._tee,
                              timelimit=self._timelimit))
            if not _check_termination_condition(self.results[-1]):
                raise Exception(
                    'The lower-bounding master is infeasible or sub-optimal.')

            # the LB should be a sequence of non-decreasing lower-bounds
            _lb = [
                value(odata)
                for odata in self._instance.component_objects(Objective)
                if odata.parent_block() == self._instance
            ][0]
            if _lb < LB:
                raise Exception(
                    'The lower-bound should be non-decreasing; a decreasing lower-bound indicates an algorithm issue.'
                )
            LB = max(LB, _lb)
            lower_bounding_master.deactivate()

            # Step 3. Termination
            if UB - LB < xi:
                # print(UB)
                # print(LB)
                if self._instance.solutions.solutions:
                    self._instance.solutions.select(0, ignore_fixed_vars=True)
                stop_time = time.time()
                self.wall_time = stop_time - start_time
                self.results_obj = self._setup_results_obj()
                return pyutilib.misc.Bunch(rc=getattr(opt, '_rc', None),
                                           log=getattr(opt, '_log', None))

            # fix the upper-level (master) variables to solve (P6) and (P7)
            for key, var in fixed_vars.items():
                var.fix(var.value)

            # Step 4. Subproblem 1
            # Solve problem (P6) lower-level problem for fixed upper-level optimal vars.
            # In iteration k=0, this first subproblem is always feasible; furthermore, the
            # optimal solution to (P5), alternatively (P9), will also be feasible to (P6).
            with pyomo.opt.SolverFactory(solver) as _opt:
                _results = _opt.solve(submodel,
                                      tee=self._tee,
                                      timelimit=self._timelimit)
            if not _check_termination_condition(_results):
                raise Exception(
                    'The lower-level subproblem with fixed upper-level variables is infeasible or sub-optimal.'
                )

            theta = [
                value(odata) for odata in submodel.component_objects(Objective)
            ][0]

            # solution for all variable values
            _fixed = array(
                [var.value for (key, var) in matrix_repn._all_vars.items()])

            # temporary dictionary for b_vars
            _b_vars_subproblem1 = dict()
            for _vid, var in b_vars.items():
                _b_vars_subproblem1[_vid] = var.value

            # temporary dictionary for i_vars
            _i_vars_subproblem1 = dict()
            for _vid, var in i_vars.items():
                _i_vars_subproblem1[_vid] = var.value

            # Step 5. Subproblem 2
            # Solve problem (P7) upper bounding problem for fixed upper-level optimal vars.
            upper_bounding_subproblem = getattr(self._instance,
                                                _upper_model_name, None)
            if upper_bounding_subproblem is None:
                xfrm = TransformationFactory('pao.bilevel.highpoint')
                kwds = {'submodel_name': _upper_model_name}
                xfrm.apply_to(self._instance, **kwds)
                upper_bounding_subproblem = getattr(self._instance,
                                                    _upper_model_name)
                algorithm_blocks.append(upper_bounding_subproblem)

                for odata in upper_bounding_subproblem.component_objects(
                        Objective):
                    upper_bounding_subproblem.del_component(odata)

            # solve for the master problem objective value for just the lower level variables
            upper_bounding_subproblem.del_component('objective')
            obj_constant = 0.
            obj_expr = 0.
            for var in {**c_vars, **b_vars, **i_vars}.values():
                (C, C_q,
                 C_constant) = matrix_repn.cost_vectors(self._instance, var)
                if obj_constant == 0. and C_constant != 0.:
                    obj_constant += C_constant  # only add the constant once
                obj_expr += float(C + dot(C_q, _fixed)) * var
            upper_bounding_subproblem.objective = Objective(expr=obj_expr +
                                                            obj_constant)

            # include lower bound constraint on the subproblem objective
            upper_bounding_subproblem.del_component('theta_pareto')
            sub_constant = 0.
            sub_expr = 0.
            for var in all_vars.values():
                (C, C_q, C_constant) = matrix_repn.cost_vectors(submodel, var)
                if sub_constant == 0. and C_constant != 0.:
                    sub_constant += C_constant  # only add the constant once
                sub_expr += float(C + dot(C_q, _fixed)) * var
            upper_bounding_subproblem.theta_pareto = Constraint(
                expr=sub_expr + sub_constant >= theta)

            with pyomo.opt.SolverFactory(solver) as opt:
                self.results.append(
                    opt.solve(upper_bounding_subproblem,
                              tee=self._tee,
                              timelimit=self._timelimit))
            if _check_termination_condition(self.results[-1]):
                # calculate new upper bound
                obj_constant = 0.
                obj_expr = 0.
                for var in fixed_vars.values():
                    (C, C_q, C_constant) = matrix_repn.cost_vectors(
                        self._instance, var)
                    if obj_constant == 0. and C_constant != 0.:
                        obj_constant += C_constant  # only add the constant once
                    obj_expr += float(C + dot(C_q, _fixed)) * var.value
                # line 16 of decomposition algorithm
                _ub = obj_expr + obj_constant + [
                    value(odata) for odata in
                    upper_bounding_subproblem.component_objects(Objective)
                ][0]
                UB = min(UB, _ub)

                # unfix the upper-level variables
                for var in fixed_vars.values():
                    var.unfix()

                # fix the solution for submodel binary variables
                for _vid, var in b_vars.items():
                    m._iter_b[(k, _vid)].fix(var.value)

                # fix the solution for submodel integer variables
                for _vid, var in i_vars.items():
                    m._iter_i[(k, _vid)].fix(var.value)
            else:  # infeasible problem
                # unfix the upper-level variables
                for var in fixed_vars.values():
                    var.unfix()

                # retrieve b_vars from temporary dictionary for subproblem1
                for _vid, var in b_vars.items():
                    m._iter_b[(k, _vid)].fix(_b_vars_subproblem1[_vid])

                # retrieve i_vars from temporary dictionary for subproblem1
                for _vid, var in i_vars.items():
                    m._iter_i[(k, _vid)].fix(_i_vars_subproblem1[_vid])

            # Step 6. Tightening the Master Problem
            projections = getattr(lower_bounding_master, 'projections', None)
            if projections is None:
                lower_bounding_master.projections = Block(Any)
                projections = lower_bounding_master.projections

            # constraint (79)
            projections[k].projection1 = Constraint(sub_cons.keys())
            lhs_expr_proj = {key: 0. for key in sub_cons.keys()}
            rhs_expr_proj = {key: 0. for key in sub_cons.keys()}
            for _vid, var in c_vars.items():
                (A, A_q, sign, b) = matrix_repn.coef_matrices(submodel, var)
                coef = A + dot(A_q.toarray(), _fixed)
                for _cid in sub_cons.keys():
                    idx = list(sub_cons.keys()).index(_cid)
                    lhs_expr_proj[_cid] += float(
                        coef[idx]) * m._iter_c[(k, _vid)]

            for _vid, var in b_vars.items():
                (A, A_q, sign, b) = matrix_repn.coef_matrices(submodel, var)
                coef = A + dot(A_q.toarray(), _fixed)
                for _cid in sub_cons.keys():
                    idx = list(sub_cons.keys()).index(_cid)
                    rhs_expr_proj[_cid] += -float(coef[idx]) * m._iter_b[
                        (k, _vid)]

            for _vid, var in i_vars.items():
                (A, A_q, sign, b) = matrix_repn.coef_matrices(submodel, var)
                coef = A + dot(A_q.toarray(), _fixed)
                for _cid in sub_cons.keys():
                    idx = list(sub_cons.keys()).index(_cid)
                    rhs_expr_proj[_cid] += -float(coef[idx]) * m._iter_i[
                        (k, _vid)]

            for _vid, var in fixed_vars.items():
                (A, A_q, sign, b) = matrix_repn.coef_matrices(submodel, var)
                coef = A + dot(A_q.toarray(), _fixed)
                for _cid in sub_cons.keys():
                    idx = list(sub_cons.keys()).index(_cid)
                    rhs_expr_proj[_cid] += -float(coef[idx]) * var

            for _cid, b in sub_cons.items():
                (id, sign) = _cid
                rhs_expr_proj[_cid] += b
                if sign == 'l' or sign == 'g->l':
                    projections[k].projection1[
                        _cid] = lhs_expr_proj[_cid] - m._iter_t[
                            (k, _cid)] <= rhs_expr_proj[_cid]
                if sign == 'e' or sign == 'g':
                    raise Exception(
                        'Problem encountered, this problem is not in standard form.'
                    )

            # constraint (80a)
            projections[k].projection2a = Constraint(c_vars.keys())
            for _vid in c_vars.keys():
                projections[k].projection2a[_vid] = m._iter_c[(k, _vid)] >= 0

            # constraint (80b)
            projections[k].projection2b = Constraint(sub_cons.keys())
            for _cid in sub_cons.keys():
                projections[k].projection2b[_cid] = m._iter_t[(k, _cid)] >= 0

            # constraint (82)
            projections[k].projection3 = Block()
            projections[k].projection3.indicator = Disjunct()
            projections[k].projection3.block = Disjunct()
            projections[k].projection3.disjunct = Disjunction(expr=[
                projections[k].projection3.indicator,
                projections[k].projection3.block
            ])

            projections[k].projection3.indicator.cons_feas = Constraint(
                expr=sum(m._iter_t[(k, _cid)]
                         for _cid in sub_cons.keys()) >= epsilon)

            disjunction = projections[k].projection3.block

            # constraint (82a)
            lhs_constant = 0.
            lhs_expr = 0.
            rhs_constant = 0.
            rhs_expr = 0.
            for _vid, var in {**c_vars, **b_vars, **i_vars}.items():
                (C, C_q, C_constant) = matrix_repn.cost_vectors(submodel, var)
                lhs_expr += float(C + dot(C_q, _fixed)) * var
                if var.is_continuous():
                    rhs_expr += float(C + dot(C_q, _fixed)) * m._iter_c[(k,
                                                                         _vid)]
                if var.is_binary():
                    rhs_expr += float(C + dot(C_q, _fixed)) * m._iter_b[(k,
                                                                         _vid)]
                if var.is_integer():
                    rhs_expr += float(C + dot(C_q, _fixed)) * m._iter_i[(k,
                                                                         _vid)]
            disjunction.projection3a = Constraint(
                expr=lhs_expr + lhs_constant >= rhs_expr + rhs_constant)

            # constraint (82b)
            disjunction.projection3b = Constraint(sub_cons.keys())
            for _cid in sub_cons.keys():
                (_, sign) = _cid
                if sign == 'l' or sign == 'g->l':
                    expr = lhs_expr_proj[_cid] <= rhs_expr_proj[_cid]
                if sign == 'e' or sign == 'g':
                    raise Exception(
                        'Problem encountered, this problem is not in standard form.'
                    )
                if not type(expr) is bool:
                    disjunction.projection3b[_cid] = expr
                else:
                    disjunction.projection3b[_cid] = Constraint.Skip

            # constraint (82c)
            disjunction.projection3c = Constraint(c_vars.keys())
            lhs_expr = {key: 0. for key in c_vars.keys()}
            rhs_expr = {key: 0. for key in c_vars.keys()}
            for _vid, var in c_vars.items():
                (A, A_q, sign, b) = matrix_repn.coef_matrices(submodel, var)
                coef = A + dot(A_q.toarray(), _fixed)
                idx = list(sub_cons.keys()).index(_cid)
                lhs_expr[_vid] += float(coef[idx]) * m._iter_pi[(k, _cid)]

                (C, C_q, C_constant) = matrix_repn.cost_vectors(submodel, var)
                rhs_expr[_vid] = float(C + dot(C_q, _fixed))

                expr = lhs_expr[_vid] >= rhs_expr[_vid]
                if not type(expr) is bool:
                    disjunction.projection3c[_vid] = expr
                else:
                    disjunction.projection3c[_vid] = Constraint.Skip

            # constraint (82d)
            disjunction.projection3d = ComplementarityList()
            for _vid in c_vars.keys():
                disjunction.projection3d.add(
                    complements(m._iter_c[(k, _vid)] >= 0,
                                lhs_expr[_vid] - rhs_expr[_vid] >= 0))

            # constraint (82e)
            disjunction.projection3e = ComplementarityList()
            for _cid in sub_cons.keys():
                disjunction.projection3e.add(
                    complements(
                        m._iter_pi[(k, _cid)] >= 0,
                        rhs_expr_proj[_cid] - lhs_expr_proj[_cid] >= 0))

            # constraint (82f)
            disjunction.projection3f = Constraint(c_vars.keys())
            for _vid in c_vars.keys():
                disjunction.projection3f[_vid] = m._iter_c[(k, _vid)] >= 0

            # constraint (82g)
            disjunction.projection3g = Constraint(sub_cons.keys())
            for _cid in sub_cons.keys():
                disjunction.projection3g[_cid] = m._iter_pi[(k, _cid)] >= 0

            # constraint (83a)
            projections[k].projection4a = Constraint(c_vars.keys())
            lhs_expr = {key: 0. for key in c_vars.keys()}
            for _vid, var in c_vars.items():
                (A, A_q, sign, b) = matrix_repn.coef_matrices(submodel, var)
                coef = A + dot(A_q.toarray(), _fixed)
                for _cid in sub_cons.keys():
                    idx = list(sub_cons.keys()).index(_cid)
                    lhs_expr[_vid] += float(
                        coef[idx]) * m._iter_lambda[(k, _cid)]

                expr = lhs_expr[_vid] >= 0
                if not type(expr) is bool:
                    projections[k].projection4a[_vid] = expr
                else:
                    projections[k].projection4a[_vid] = Constraint.Skip

            # constraint (83b)
            projections[k].projection4b = ComplementarityList()
            for _vid in c_vars.keys():
                projections[k].projection4b.add(
                    complements(m._iter_c[(k, _vid)] >= 0,
                                lhs_expr[_vid] >= 0))

            # constraint (84a)
            projections[k].projection5a = Constraint(sub_cons.keys())
            for _cid in sub_cons.keys():
                projections[k].projection5a[_cid] = 1 - m._iter_lambda[
                    (k, _cid)] >= 0

            # constraint (84b)
            projections[k].projection5b = ComplementarityList()
            for _cid in sub_cons.keys():
                projections[k].projection5b.add(
                    complements(m._iter_t[(k, _cid)] >= 0,
                                1 - m._iter_lambda[(k, _cid)] >= 0))

            # constraint (85)
            projections[k].projection6 = ComplementarityList()
            for _cid in sub_cons.keys():
                projections[k].projection6.add(
                    complements(
                        m._iter_lambda[(k, _cid)] >= 0, rhs_expr_proj[_cid] -
                        lhs_expr_proj[_cid] + m._iter_t[(k, _cid)] >= 0))

            k = k + 1
            # Step 7. Loop
            if UB - LB < xi:
                # print(UB)
                # print(LB)
                if self._instance.solutions.solutions:
                    self._instance.solutions.select(0, ignore_fixed_vars=True)
                stop_time = time.time()
                self.wall_time = stop_time - start_time
                self.results_obj = self._setup_results_obj()
                return pyutilib.misc.Bunch(rc=getattr(opt, '_rc', None),
                                           log=getattr(opt, '_log', None))
コード例 #18
0
ファイル: nlp_solve.py プロジェクト: mskarha/pyomo
def solve_NLP_subproblem(solve_data, config):
    m = solve_data.working_model.clone()
    MindtPy = m.MindtPy_utils
    main_objective = next(m.component_data_objects(Objective, active=True))
    solve_data.nlp_iter += 1
    config.logger.info('NLP %s: Solve subproblem for fixed binaries.'
                       % (solve_data.nlp_iter,))
    # Set up NLP
    for v in MindtPy.variable_list:
        if v.is_binary():
            v.fix(int(round(value(v))))

    # restore original variable values
    for nlp_var, orig_val in zip(
            MindtPy.variable_list,
            solve_data.initial_var_values):
        if not nlp_var.fixed and not nlp_var.is_binary():
            nlp_var.value = orig_val

    MindtPy.MindtPy_linear_cuts.deactivate()
    m.tmp_duals = ComponentMap()
    for c in m.component_data_objects(ctype=Constraint, active=True,
                                      descend_into=True):
        rhs = ((0 if c.upper is None else c.upper) +
               (0 if c.lower is None else c.lower))
        sign_adjust = 1 if value(c.upper) is None else -1
        m.tmp_duals[c] = sign_adjust * max(0,
                                           sign_adjust * (rhs - value(c.body)))
        # TODO check sign_adjust
    t = TransformationFactory('contrib.deactivate_trivial_constraints')
    t.apply_to(m, tmp=True, ignore_infeasible=True)
    # Solve the NLP
    # m.pprint() # print nlp problem for debugging
    with SuppressInfeasibleWarning():
        results = SolverFactory(config.nlp_solver).solve(
            m, **config.nlp_solver_args)
    var_values = list(v.value for v in MindtPy.variable_list)
    subprob_terminate_cond = results.solver.termination_condition
    if subprob_terminate_cond is tc.optimal:
        copy_var_list_values(
            m.MindtPy_utils.variable_list,
            solve_data.working_model.MindtPy_utils.variable_list,
            config)
        for c in m.tmp_duals:
            if m.dual.get(c, None) is None:
                m.dual[c] = m.tmp_duals[c]
        duals = list(m.dual[c] for c in MindtPy.constraint_list)
        if main_objective.sense == minimize:
            solve_data.UB = min(value(main_objective.expr), solve_data.UB)
            solve_data.solution_improved = solve_data.UB < solve_data.UB_progress[-1]
            solve_data.UB_progress.append(solve_data.UB)
        else:
            solve_data.LB = max(value(main_objective.expr), solve_data.LB)
            solve_data.solution_improved = solve_data.LB > solve_data.LB_progress[-1]
            solve_data.LB_progress.append(solve_data.LB)
        config.logger.info(
            'NLP {}: OBJ: {}  LB: {}  UB: {}'
            .format(solve_data.nlp_iter, value(main_objective.expr), solve_data.LB, solve_data.UB))
        if solve_data.solution_improved:
            solve_data.best_solution_found = m.clone()
        # Add the linear cut
        if config.strategy == 'OA':
            add_oa_cut(var_values, duals, solve_data, config)
        elif config.strategy == 'PSC':
            add_psc_cut(solve_data, config)
        elif config.strategy == 'GBD':
            add_gbd_cut(solve_data, config)

        # This adds an integer cut to the feasible_integer_cuts
        # ConstraintList, which is not activated by default. However, it
        # may be activated as needed in certain situations or for certain
        # values of option flags.
        add_int_cut(var_values, solve_data, config, feasible=True)

        config.call_after_subproblem_feasible(m, solve_data)
    elif subprob_terminate_cond is tc.infeasible:
        # TODO try something else? Reinitialize with different initial
        # value?
        config.logger.info('NLP subproblem was locally infeasible.')
        for c in m.component_data_objects(ctype=Constraint, active=True,
                                          descend_into=True):
            rhs = ((0 if c.upper is None else c.upper) +
                   (0 if c.lower is None else c.lower))
            sign_adjust = 1 if value(c.upper) is None else -1
            m.dual[c] = sign_adjust * max(0,
                                          sign_adjust * (rhs - value(c.body)))
        for var in m.component_data_objects(ctype=Var,
                                            descend_into=True):

            if config.strategy == 'PSC' or config.strategy == 'GBD':
                m.ipopt_zL_out[var] = 0
                m.ipopt_zU_out[var] = 0
                if var.ub is not None and abs(var.ub - value(var)) < config.bound_tolerance:
                    m.ipopt_zL_out[var] = 1
                elif var.lb is not None and abs(value(var) - var.lb) < config.bound_tolerance:
                    m.ipopt_zU_out[var] = -1
        # m.pprint() #print infeasible nlp problem for debugging
        if config.strategy == 'OA':
            config.logger.info('Solving feasibility problem')
            if config.initial_feas:
                # add_feas_slacks(m, solve_data)
                # config.initial_feas = False
                var_values, duals = solve_NLP_feas(solve_data, config)
                add_oa_cut(var_values, duals, solve_data, config)
        # Add an integer cut to exclude this discrete option
        add_int_cut(var_values, solve_data, config)
    elif subprob_terminate_cond is tc.maxIterations:
        # TODO try something else? Reinitialize with different initial
        # value?
        config.logger.info('NLP subproblem failed to converge within iteration limit.')
        # Add an integer cut to exclude this discrete option
        add_int_cut(solve_data, config)
    else:
        raise ValueError(
            'MindtPy unable to handle NLP subproblem termination '
            'condition of {}'.format(subprob_terminate_cond))

    # Call the NLP post-solve callback
    config.call_after_subproblem_solve(m, solve_data)
コード例 #19
0
def get_dual_values(solver, model):
    if id(model) not in get_dual_values.discrete_stage2_vars:
        # 1st attempt to get duals: we need to see if the model has
        # discrete variables (solvers won't give duals if there are
        # still active discrete variables)
        try:
            get_dual_values.discrete_stage2_vars[id(model)] = False
            return get_dual_values(solver, model)
        except:
            get_dual_values.discrete_stage2_vars[id(model)] = True
            # Find the discrete variables to populate the list
            return get_dual_values(solver, model)

    duals = {}
    _con = model._interscenario_plugin.fixed_variables_constraint

    if get_dual_values.discrete_stage2_vars[id(model)]:
        # Fix all discrete variables
        xfrm = TransformationFactory('core.relax_discrete')
        if PYOMO_4_0:
            xfrm.apply(model, inplace=True)
        else:
            xfrm.apply_to(model)

        # Note: preprocessing is only necessary if we are changing a
        # fixed/freed variable.
        if FALLBACK_ON_BRUTE_FORCE_PREPROCESS:
            model.preprocess()
        else:
            _map = {}
            preprocess_block_constraints(model._interscenario_plugin,
                                         idMap=_map)

        #SOLVE
        results = solver.solve(model, warmstart=True)
        ss = results.solver.status
        tc = results.solver.termination_condition
        #self.timeInSolver += results['Solver'][0]['Time']
        if ss == SolverStatus.ok and tc in _acceptable_termination_conditions:
            state = ''
        elif tc in _infeasible_termination_conditions:
            state = 'INFEASIBLE'
        else:
            state = 'NONOPTIMAL'
        if state:
            logger.warning(
                "Resolving subproblem model with relaxed second-stage "
                "discrete variables failed (%s).  "
                "Dual values not available." % (state, ))
        else:
            # Get the duals
            if PYOMO_4_0:
                model.load(results)
            else:
                model.solutions.load_from(results)
            #model.dual.pprint()
            for varid in model._interscenario_plugin.STAGE1VAR:
                duals[varid] = model.dual[_con[varid]]
        # Free the discrete second-stage variables
        if PYOMO_4_0:
            xfrm.apply(model, inplace=True, undo=True)
        else:
            xfrm.apply_to(model, undo=True)

    else:
        # return the duals
        for varid in model._interscenario_plugin.STAGE1VAR:
            duals[varid] = model.dual[_con[varid]]

    return duals
コード例 #20
0
ファイル: interscenario.py プロジェクト: Pyomo/pyomo
def solve_separation_problem(solver, model, fallback):
    xfrm = TransformationFactory('core.relax_discrete')
    if PYOMO_4_0:
        xfrm.apply(model, inplace=True)
    else:
        xfrm.apply_to(model)

    _block = model._interscenario_plugin

    # Switch objectives
    _block.original_obj().deactivate()
    _block.separation_obj.activate()

    #_block.separation_variables.unfix()
    _par = _block.fixed_variable_values
    _sep = _block.separation_variables
    allow_slack = _block.allow_slack
    if allow_slack:
        epsilon = _block.epsilon
        for idx in _sep:
            _sep[idx].setlb(None)
            _sep[idx].setub(None)
    else:
        _sep.unfix()

    # Note: preprocessing is only necessary if we are changing a
    # fixed/freed variable.
    if FALLBACK_ON_BRUTE_FORCE_PREPROCESS:
        model.preprocess()
    else:
        _map = {}
        preprocess_block_objectives(_block, idMap=_map)
        preprocess_block_constraints(_block, idMap=_map)

    #SOLVE
    output_buffer = StringIO()
    pyutilib.misc.setup_redirect(output_buffer)
    try:
        results = solver.solve(model, tee=True)
    except:
        logger.warning("Exception raised solving the interscenario "
                       "evaluation subproblem")
        logger.warning("Solver log:\n%s" % output_buffer.getvalue())
        raise
    finally:
        pyutilib.misc.reset_redirect()

    ss = results.solver.status
    tc = results.solver.termination_condition
    #self.timeInSolver += results['Solver'][0]['Time']
    if ss == SolverStatus.ok and tc in _acceptable_termination_conditions:
        state = ''
        if PYOMO_4_0:
            model.load(results)
        else:
            model.solutions.load_from(results)
    elif tc in _infeasible_termination_conditions:
        state = 'INFEASIBLE'
        ans = "!!!!"
    else:
        state = 'NONOPTIMAL'
        ans = "????"
    if state:
        if fallback:
            #logger.warning("Initial attempt to solve the interscenario cut "
            #               "separation subproblem failed with the default "
            #               "solver (%s)." % (state,) )
            pass
        else:
            logger.warning("Solving the interscenario cut separation "
                           "subproblem failed (%s)." % (state,) )
            logger.warning("Solver log:\n%s" % output_buffer.getvalue())
    else:
        cut = dict((vid, (value(_sep[vid]), value(_par[vid])))
                   for vid in _block.STAGE1VAR)
        obj = value(_block.separation_obj)
        ans = (math.sqrt(obj), cut)

    output_buffer.close()

    # Restore the objective
    _block.original_obj().activate()
    _block.separation_obj.deactivate()

    # Turn off the separation variables
    if allow_slack:
        for idx in _sep:
            _sep[idx].setlb(-epsilon)
            _sep[idx].setub(epsilon)
    else:
        _sep.fix(0)

    if PYOMO_4_0:
        xfrm.apply(model, inplace=True, undo=True)
    else:
        xfrm.apply_to(model, undo=True)

    if FALLBACK_ON_BRUTE_FORCE_PREPROCESS:
        pass
    else:
        _map = {}
        preprocess_block_objectives(_block, idMap=_map)
    return ans
コード例 #21
0
def solve_separation_problem(solver, model, fallback):
    xfrm = TransformationFactory('core.relax_discrete')
    if PYOMO_4_0:
        xfrm.apply(model, inplace=True)
    else:
        xfrm.apply_to(model)

    _block = model._interscenario_plugin

    # Switch objectives
    _block.original_obj().deactivate()
    _block.separation_obj.activate()

    #_block.separation_variables.unfix()
    _par = _block.fixed_variable_values
    _sep = _block.separation_variables
    allow_slack = _block.allow_slack
    if allow_slack:
        epsilon = _block.epsilon
        for idx in _sep:
            _sep[idx].setlb(None)
            _sep[idx].setub(None)
    else:
        _sep.unfix()

    # Note: preprocessing is only necessary if we are changing a
    # fixed/freed variable.
    if FALLBACK_ON_BRUTE_FORCE_PREPROCESS:
        model.preprocess()
    else:
        _map = {}
        preprocess_block_objectives(_block, idMap=_map)
        preprocess_block_constraints(_block, idMap=_map)

    #SOLVE
    output_buffer = StringIO()
    setup_redirect(output_buffer)
    try:
        results = solver.solve(model, tee=True)
    except:
        logger.warning("Exception raised solving the interscenario "
                       "evaluation subproblem")
        logger.warning("Solver log:\n%s" % output_buffer.getvalue())
        raise
    finally:
        reset_redirect()

    ss = results.solver.status
    tc = results.solver.termination_condition
    #self.timeInSolver += results['Solver'][0]['Time']
    if ss == SolverStatus.ok and tc in _acceptable_termination_conditions:
        state = ''
        if PYOMO_4_0:
            model.load(results)
        else:
            model.solutions.load_from(results)
    elif tc in _infeasible_termination_conditions:
        state = 'INFEASIBLE'
        ans = "!!!!"
    else:
        state = 'NONOPTIMAL'
        ans = "????"
    if state:
        if fallback:
            #logger.warning("Initial attempt to solve the interscenario cut "
            #               "separation subproblem failed with the default "
            #               "solver (%s)." % (state,) )
            pass
        else:
            logger.warning("Solving the interscenario cut separation "
                           "subproblem failed (%s)." % (state, ))
            logger.warning("Solver log:\n%s" % output_buffer.getvalue())
    else:
        cut = dict((vid, (value(_sep[vid]), value(_par[vid])))
                   for vid in _block.STAGE1VAR)
        obj = value(_block.separation_obj)
        ans = (math.sqrt(obj), cut)

    output_buffer.close()

    # Restore the objective
    _block.original_obj().activate()
    _block.separation_obj.deactivate()

    # Turn off the separation variables
    if allow_slack:
        for idx in _sep:
            _sep[idx].setlb(-epsilon)
            _sep[idx].setub(epsilon)
    else:
        _sep.fix(0)

    if PYOMO_4_0:
        xfrm.apply(model, inplace=True, undo=True)
    else:
        xfrm.apply_to(model, undo=True)

    if FALLBACK_ON_BRUTE_FORCE_PREPROCESS:
        pass
    else:
        _map = {}
        preprocess_block_objectives(_block, idMap=_map)
    return ans
コード例 #22
0
ファイル: solver1.py プロジェクト: Juanlu001/pyomo
    def _apply_solver(self):
        start_time = time.time()
        #
        # Cache the instance
        #
        xfrm = TransformationFactory('bilevel.linear_dual')
        xfrm.apply_to(self._instance)
        #
        # Apply an additional transformation to remap bilinear terms
        #
        if self.options.transform is None:
            xfrm = None
        else:
            xfrm = TransformationFactory(self.options.transform)
            xfrm.apply_to(self._instance)
        #
        # Solve with a specified solver
        #
        solver = self.options.solver
        if not self.options.solver:
            solver = 'glpk'

        # use the with block here so that deactivation of the
        # solver plugin always occurs thereby avoiding memory
        # leaks caused by plugins!
        with pyomo.opt.SolverFactory(solver) as opt:
            self.results = []
            #
            # **NOTE: It would be better to override _presolve on the
            #         base class of this solver as you might be
            #         missing a number of keywords that were passed
            #         into the solve method (e.g., none of the
            #         io_options are getting relayed to the subsolver
            #         here).
            #
            self.results.append(opt.solve(self._instance,
                                          tee=self._tee,
                                          timelimit=self._timelimit))
            #
            # Transform the result back into the original model
            #
            tdata = self._instance._transformation_data['bilevel.linear_dual']
            unfixed_cuids = set()
            # Copy variable values and fix them
            for vuid in tdata.fixed:
                for index_, data_ in vuid.find_component_on(self._instance).iteritems():
                    if not data_.fixed:
                        data_.value = self._instance.find_component(data_).value
                        data_.fixed = True
                        unfixed_cuids.add(ComponentUID(data_))
            # Reclassify the SubModel components and resolve
            for name_ in tdata.submodel:
                submodel = getattr(self._instance, name_)
                submodel.activate()
                dual_submodel = getattr(self._instance, name_+'_dual')
                dual_submodel.deactivate()
                pyomo.util.PyomoAPIFactory('pyomo.repn.compute_canonical_repn')({}, model=submodel)
                self._instance.reclassify_component_type(name_, Block)
                # use the with block here so that deactivation of the
                # solver plugin always occurs thereby avoiding memory
                # leaks caused by plugins!
                with pyomo.opt.SolverFactory(solver) as opt_inner:
                    #
                    # **NOTE: It would be better to override _presolve on the
                    #         base class of this solver as you might be
                    #         missing a number of keywords that were passed
                    #         into the solve method (e.g., none of the
                    #         io_options are getting relayed to the subsolver
                    #         here).
                    #
                    self.results.append(opt_inner.solve(self._instance,
                                                        tee=self._tee,
                                                        timelimit=self._timelimit,
                                                        select=None))
                    self._instance.solutions.select(0, ignore_fixed_vars=True)
                    data_.parent_component().parent_block().reclassify_component_type(name_, SubModel)
            # Unfix variables
            for vuid in tdata.fixed:
                for index_, data_ in vuid.find_component_on(self._instance).iteritems():
                    if ComponentUID(data_) in unfixed_cuids:
                        data_.fixed = False
            stop_time = time.time()
            self.wall_time = stop_time - start_time
            # Reactivate top level objective
            for oname, odata in self._instance.component_map(Objective).items():
                odata.activate()
            #
            # Return the sub-solver return condition value and log
            #
            return pyutilib.misc.Bunch(rc=getattr(opt,'_rc', None),
                                       log=getattr(opt,'_log',None))
コード例 #23
0
ファイル: cuts.py プロジェクト: cog-imperial/romodel
    def _apply_solver(self):
        start_time = time.time()
        instance = self._instance

        # Reformulate adjustable variables
        if not self.options.adjustable:
            adjustable = 'romodel.adjustable.ldr'
        else:
            adjustable = self.options.adjustable

        xfrm = TransformationFactory(adjustable)
        xfrm.apply_to(instance)

        # Add cutting plane generators
        xfrm = TransformationFactory('romodel.generators')
        xfrm.apply_to(instance)
        tdata = instance._transformation_data['romodel.generators']
        generators = tdata.generators
        print("Adding {} cutting plane generators.".format(len(generators)))

        instance.transformation_time = time.time() - start_time

        # Need to set this up for main and sub solver
        if not self.options.solver:
            # Use glpk instead
            solver = 'gurobi'
        else:
            solver = self.options.solver

        if not self.options.max_iter:
            max_iter = 300
        else:
            max_iter = self.options.max_iter

        if not self.options.subsolver:
            subsolver = solver
        else:
            subsolver = self.options.subsolver

        self.options.setdefault('subsolver_options', self.options)
        subsolver_options = self.options.pop('subsolver_options')

        print("Using solver {}\n".format(solver))

        with SolverFactory(solver) as opt:
            self.results = []
            feasible = {}
            # Solve nominal problem
            print("Solving nominal problem.\n")
            opt.options = self.options
            results = opt.solve(instance,
                                tee=self._tee,
                                timelimit=self._timelimit)
            # Add initial cut to check feasibility
            for g in generators:
                feasible[g.name] = g.add_cut(solver=subsolver,
                                             options=subsolver_options)
            feas, total = sum(feasible.values()), len(feasible)
            print("{0}/{1} constraints robustly feasible. "
                  "Add cuts and resolve.".format(feas, total))
            # Keep adding cuts until feasible
            n_iter = 1
            while (not all(feasible.values())) and (n_iter < max_iter):
                if (results.solver.termination_condition
                        is not TerminationCondition.optimal):
                    break
                results = opt.solve(instance,
                                    tee=self._tee,
                                    timelimit=self._timelimit)
                for g in generators:
                    feasible[g.name] = g.add_cut(solver=subsolver,
                                                 options=subsolver_options)
                self.results.append(results)

                n_iter += 1
                feas, total = sum(feasible.values()), len(feasible)
                print("{0}/{1} constraints robustly feasible. "
                      "Add cuts and resolve.".format(feas, total))

            if all(feasible.values()):
                print("\nAll constraints robustly feasible after {} "
                      "iterations.".format(n_iter))
            else:
                print("\nEnding after reaching max_iter={} iterations. "
                      "Solution is not robustly feasible".format(max_iter))

        self.termination_condition = results.solver.termination_condition
        stop_time = time.time()
        self.wall_time = stop_time - start_time
        self.results_obj = self._setup_results_obj()
        #
        # Return the sub-solver return condition value and log
        #
        return pyutilib.misc.Bunch(rc=getattr(opt, '_rc', None),
                                   log=getattr(opt, '_log', None))