def test_find_badly_scaled_vars():
    m = pyo.ConcreteModel()
    m.x = pyo.Var(initialize=1e6)
    m.y = pyo.Var(initialize=1e-8)
    m.z = pyo.Var(initialize=1e-20)
    m.b = pyo.Block()
    m.b.w = pyo.Var(initialize=1e10)

    a = [id(v) for v, sv in sc.badly_scaled_var_generator(m)]
    assert id(m.x) in a
    assert id(m.y) in a
    assert id(m.b.w) in a
    assert id(m.z) not in a

    m.scaling_factor = pyo.Suffix(direction=pyo.Suffix.EXPORT)
    m.b.scaling_factor = pyo.Suffix(direction=pyo.Suffix.EXPORT)
    m.scaling_factor[m.x] = 1e-6
    m.scaling_factor[m.y] = 1e6
    m.scaling_factor[m.z] = 1
    m.b.scaling_factor[m.b.w] = 1e-5

    a = [id(v) for v, sv in sc.badly_scaled_var_generator(m)]
    assert id(m.x) not in a
    assert id(m.y) not in a
    assert id(m.b.w) in a
    assert id(m.z) not in a
Exemple #2
0
def subSolve(cap, PF,PTDF,line):

    # initialize sub
    sub = pyo.ConcreteModel()
    sub.N = pyo.Set(ordered=True, initialize=[0, 1, 2, 3])  # Set of the 4 nodes in our system
    sub.Pup = pyo.Var(sub.N,domain=pyo.NonNegativeReals)  # Make 4 P-variables that represent increased power generation at each node
    sub.Pdown = pyo.Var(sub.N, domain=pyo.NonNegativeReals)  # Make 4 P-variables that represent decreased power generation at each node
    sub.constraints = pyo.ConstraintList()  # Define the list of all constraints

    # Define the objective function to be the sum of change in power production
    def ObjectiveFunction(sub):
        return sum(sub.Pup[i] + sub.Pdown[i] for i in sub.N)

    sub.obj = pyo.Objective(rule=ObjectiveFunction, sense=pyo.minimize)
    # Load balance constraint
    sub.constraints.add(sum(sub.Pup[i]-sub.Pdown[i] for i in sub.N) == 0)

    # Constraint for not violation of line 0-2
    lhs=-cap - PF[0, 2]
    mid= sum((sub.Pup[i] - sub.Pdown[i])*PTDF[line,i] for i in sub.N)
    rhs= cap - PF[0, 2]
    sub.constraints.add(pyo.inequality(lhs,mid,rhs))

    # Solve model
    opt = SolverFactory("gurobi")
    sub.dual = pyo.Suffix(direction=pyo.Suffix.IMPORT)
    sub.rc = pyo.Suffix(direction=pyo.Suffix.IMPORT)
    results = opt.solve(sub, load_solutions=True)
    return sub
Exemple #3
0
    def receive_duals(self):
        """ Method sets solver suffix to extract information about dual
        variables from solver. Shadow prices (duals) and reduced costs (rc) are
        set as attributes of the model.

        """
        # shadow prices
        self.dual = po.Suffix(direction=po.Suffix.IMPORT)
        # reduced costs
        self.rc = po.Suffix(direction=po.Suffix.IMPORT)
Exemple #4
0
def _set_dae_suffixes_from_variables(m, variables, deriv_diff_map):
    """Write suffixes used by the solver to identify different variable types
    and associated derivative and differential variables.

    Args:
        m: model to search for variables and write suffixes to
        variables (list): List of time indexed variables at a specific time
            point
        deriv_diff_map (ComponentMap): Maps DerivativeVar data objects to
            differential variable data objects

    Returns:
        None
    """
    # The dae_suffix provides the solver information about variables types
    # algebraic, differential, derivative, or time, see DaeVarTypes
    m.dae_suffix = pyo.Suffix(
        direction=pyo.Suffix.EXPORT,
        datatype=pyo.Suffix.INT,
    )
    # The dae_link suffix provides the solver a link between the differential
    # and derivative variable, by assigning the pair a unique integer index.
    m.dae_link = pyo.Suffix(
        direction=pyo.Suffix.EXPORT,
        datatype=pyo.Suffix.INT,
    )
    dae_var_link_index = 1
    differential_vars = []
    i = 0
    for var in variables:
        if var in deriv_diff_map:
            deriv = var
            diffvar = deriv_diff_map[deriv]
            m.dae_suffix[diffvar] = int(DaeVarTypes.DIFFERENTIAL)
            m.dae_suffix[deriv] = int(DaeVarTypes.DERIVATIVE)
            m.dae_link[diffvar] = dae_var_link_index
            m.dae_link[deriv] = dae_var_link_index
            i += 1
            dae_var_link_index += 1
            if not diffvar.fixed:
                differential_vars.append(diffvar)
            else:
                raise RuntimeError(
                    f"Problem cannot contain a fixed differential variable and "
                    f"unfixed derivative. Consider either fixing the "
                    f"corresponding derivative or adding a constraint for the "
                    f"differential variable {diffvar} possibly using an "
                    f"explicit time variable.")
    return differential_vars
Exemple #5
0
def create_pyomo_model1():
    m = pyo.ConcreteModel()
    m.dual = pyo.Suffix(direction=pyo.Suffix.IMPORT_EXPORT)

    m.S = pyo.Set(initialize=[i + 1 for i in range(9)])

    xb = dict()
    xb[1] = (-1, 1)
    xb[2] = (-np.inf, 2)
    xb[3] = (-3, np.inf)
    xb[4] = (-np.inf, np.inf)
    xb[5] = (-5, 5)
    xb[6] = (-np.inf, 6)
    xb[7] = (-7, np.inf)
    xb[8] = (-np.inf, np.inf)
    xb[9] = (-9, 9)
    m.x = pyo.Var(m.S, initialize=1.0, bounds=lambda m, i: xb[i])

    cb = dict()
    cb[1] = (-1, 1)
    cb[2] = (2, 2)
    cb[3] = (-3, np.inf)
    cb[4] = (-np.inf, 4)
    cb[5] = (-5, 5)
    cb[6] = (-6, -6)
    cb[7] = (-7, np.inf)
    cb[8] = (-np.inf, 8)
    cb[9] = (-9, 9)

    def c_rule(m, i):
        return (cb[i][0], sum(i * j * m.x[j] for j in m.S), cb[i][1])

    m.c = pyo.Constraint(m.S, rule=c_rule)
    for i in m.S:
        m.dual.set_value(m.c[i], i)

    m.obj = pyo.Objective(expr=sum(i * j * m.x[i] * m.x[j] for i in m.S
                                   for j in m.S))

    # add scaling parameters for testing
    m.scaling_factor = pyo.Suffix(direction=pyo.Suffix.EXPORT)
    m.scaling_factor[m.obj] = 5
    for i in m.S:
        m.scaling_factor[m.x[i]] = 2 * float(i)
    for i in m.S:
        m.scaling_factor[m.c[i]] = 3 * float(i)

    return m
    def createPrimal(self):
        """Create the primal pyomo model.  
        
        This is used to compute flows after interdiction.  The interdiction is stored in arc_data.xbar."""

        model = pe.ConcreteModel()
        # Tell pyomo to read in dual-variable information from the solver
        model.dual = pe.Suffix(direction=pe.Suffix.IMPORT)

        # Add the sets
        model.node_set = pe.Set(initialize=self.node_set)
        model.edge_set = pe.Set(initialize=self.arc_set, dimen=2)

        # Create the variables
        model.y = pe.Var(model.edge_set, domain=pe.NonNegativeReals)
        model.UnsatSupply = pe.Var(model.node_set, domain=pe.NonNegativeReals)
        model.UnsatDemand = pe.Var(model.node_set, domain=pe.NonNegativeReals)

        # Create the objective
        def obj_rule(model):
            return sum(
                (data['Cost'] + data['xbar'] *
                 (2 * self.nCmax + 1)) * model.y[e]
                for e, data in self.arc_data.iterrows()) + sum(
                    self.nCmax * (model.UnsatSupply[n] + model.UnsatDemand[n])
                    for n, data in self.node_data.iterrows())

        model.OBJ = pe.Objective(rule=obj_rule, sense=pe.minimize)

        # Create the constraints, one for each node
        def flow_bal_rule(model, n):
            tmp = self.arc_data.reset_index()
            successors = tmp.ix[tmp.StartNode == n, 'EndNode'].values
            predecessors = tmp.ix[tmp.EndNode == n, 'StartNode'].values
            lhs = sum(model.y[(i, n)]
                      for i in predecessors) - sum(model.y[(n, i)]
                                                   for i in successors)
            imbalance = self.node_data['SupplyDemand'].get(n, 0)
            supply_node = int(imbalance < 0)
            demand_node = int(imbalance > 0)
            rhs = (imbalance + model.UnsatSupply[n] * (supply_node) -
                   model.UnsatDemand[n] * (demand_node))
            constr = (lhs == rhs)
            if isinstance(constr, bool):
                return pe.Constraint.Skip
            return constr

        model.FlowBalance = pe.Constraint(model.node_set, rule=flow_bal_rule)

        # Capacity constraints, one for each edge
        def capacity_rule(model, i, j):
            capacity = self.arc_data['Capacity'].get((i, j), -1)
            if capacity < 0:
                return pe.Constraint.Skip
            return model.y[(i, j)] <= capacity

        model.Capacity = pe.Constraint(model.edge_set, rule=capacity_rule)

        # Store the model
        self.primal = model
Exemple #7
0
    def __init__(self):

        # Initialize Model
        self.model = pyo.AbstractModel()
        self.model.dual = pyo.Suffix(direction=pyo.Suffix.IMPORT)

        # Declare Parameters
        self.model.users = pyo.Param(within=pyo.NonNegativeIntegers)
        self.model.nodes = pyo.Param(within=pyo.NonNegativeIntegers)
        self.model.links = pyo.Param(within=pyo.NonNegativeIntegers)
        self.model.nodes_idx = pyo.Param(within=pyo.NonNegativeIntegers)
        self.model.operators = pyo.Param(within=pyo.NonNegativeIntegers)

        # Set initialization
        self.model.u = pyo.RangeSet(1, self.model.users)
        self.model.n = pyo.RangeSet(1, self.model.nodes)
        self.model.l = pyo.RangeSet(1, self.model.links)
        self.model.i = pyo.RangeSet(1, self.model.nodes_idx)
        self.model.o = pyo.RangeSet(1, self.model.operators)

        # Parameters
        self.model.origin = pyo.Param(self.model.l)
        self.model.destination = pyo.Param(self.model.l)
        self.model.t = pyo.Param(self.model.l)
        self.model.c = pyo.Param(self.model.l)
        self.model.w = pyo.Param(self.model.l)
        self.model.link_oper = pyo.Param(self.model.l)
        self.model.d = pyo.Param(self.model.u)
        self.model.O = pyo.Param(self.model.u)
        self.model.D = pyo.Param(self.model.u)
        self.model.utility = pyo.Param(self.model.u)
        self.model.N = pyo.Param(self.model.n)
        self.model.heads = pyo.Param(self.model.i, self.model.i, default=0)
        self.model.tails = pyo.Param(self.model.i, self.model.i, default=0)
Exemple #8
0
def solve_with_gdp_opt():
    m = MethanolModel().model
    for _d in m.component_data_objects(gdp.Disjunct,
                                       descend_into=True,
                                       active=True,
                                       sort=True):
        _d.BigM = pe.Suffix()
        for _c in _d.component_data_objects(pe.Constraint,
                                            descend_into=True,
                                            active=True,
                                            sort=True):
            lb, ub = compute_bounds_on_expr(_c.body)
            _d.BigM[_c] = max(abs(lb), abs(ub))
    opt = pe.SolverFactory('gdpopt')
    opt.CONFIG.strategy = 'LOA'
    opt.CONFIG.mip_solver = 'gams'
    opt.CONFIG.nlp_solver = 'gams'
    opt.CONFIG.tee = True
    res = opt.solve(m)
    for d in m.component_data_objects(ctype=gdp.Disjunct,
                                      active=True,
                                      sort=True,
                                      descend_into=True):
        if d.indicator_var.value == 1:
            print(d.name)
    print(res)

    return m
    def before_start_at_node(self, problem, relaxed_problem):
        # We need duals for this, so ask pyomo to import them.
        if not hasattr(relaxed_problem, 'dual'):
            relaxed_problem.dual = pe.Suffix(direction=pe.Suffix.IMPORT)

        lower_bounds = np.zeros(self._num_vars)
        upper_bounds = np.zeros(self._num_vars)
        domains = np.zeros(self._num_vars)
        var_idx_map = self._var_idx_map
        for var in self._variables:
            var_idx = var_idx_map[var]
            lower_bounds[var_idx] = var.lb
            upper_bounds[var_idx] = var.ub
            if var.has_lb() and var.has_ub():
                domains[var_idx] = var.ub - var.lb
            else:
                domains[var_idx] = np.inf

        self._lower_bounds = lower_bounds
        self._upper_bounds = upper_bounds
        self._domains = domains

        self._agg_list_rescaled = self._rescale_coeffs_for_cut_selection(
        ) if self._nn_used else self._agg_list

        self._cut_round = 0
Exemple #10
0
 def createInstance(self, data):
   """
     This method is used to instantiate the pyomo model
     @ In, data, dict, dictionary to initialize pyomo abstract model
     @ Out, model, pyomo.instance, instance of pyomo model
   """
   model = self.createModel()
   if not model.is_constructed():
     model = model.create_instance(data)
     # model.pprint()
   if self.externalConstraints:
     model = self.addExternalConstraints(model)
   model.dual = pyomo.Suffix(direction=pyomo.Suffix.IMPORT)
   # Default to disable some optional constraints
   if len(self.optionalConstraints) > 0 and self.uncertainties is not None:
     # if 'consistentConstraintI' in self.optionalConstraints:
     #   model.consistentConstraint.deactivate()
     if 'consistentConstraintII' in self.optionalConstraints:
       model.consistentConstraintII.deactivate()
       logger.debug('Default to deactivate consistent constraint II')
     for optCon, decision in self.optionalConstraints.items():
       if optCon == 'consistentConstraintI' and not decision:
         model.consistentConstraintI.deactivate()
         logger.debug('Deactivate consistent constraint I')
       if optCon == 'consistentConstraintII' and decision:
         model.consistentConstraintII.activate()
         logger.debug('Activate consistent constraint II')
   return model
Exemple #11
0
    def finalize_block_construction(self, pyomo_block):
        # set lower bounds on the variables
        pyomo_block.inputs['sv'].setlb(0)
        pyomo_block.inputs['ca'].setlb(0)
        pyomo_block.inputs['cb'].setlb(0)
        pyomo_block.inputs['cc'].setlb(0)
        pyomo_block.inputs['cd'].setlb(0)

        # initialize the variables
        pyomo_block.inputs['sv'].value = 1
        pyomo_block.inputs['caf'].value = 1
        pyomo_block.inputs['ca'].value = 1
        pyomo_block.inputs['cb'].value = 1
        pyomo_block.inputs['cc'].value = 1
        pyomo_block.inputs['cd'].value = 1
        pyomo_block.outputs['cb_ratio'].value = 1

        m = pyomo_block.model()
        if not hasattr(m, 'scaling_factor'):
            # add the scaling factor suffix to the model if it is not already declared
            m.scaling_factor = pyo.Suffix(direction=pyo.Suffix.EXPORT)

        m.scaling_factor[pyomo_block.inputs['sv']] = 1.1
        m.scaling_factor[pyomo_block.inputs['caf']] = 1.2
        m.scaling_factor[pyomo_block.inputs['ca']] = 1.3
        m.scaling_factor[pyomo_block.inputs['cb']] = 1.4
        m.scaling_factor[pyomo_block.inputs['cc']] = 1.5
        m.scaling_factor[pyomo_block.inputs['cd']] = 1.6
        m.scaling_factor[pyomo_block.outputs['cb_ratio']] = 1.7
    def test_scale_with_ignore_var_scale_constraint_scale(self):
        """Make sure the Jacobian from Pynumero matches expectation.  This is
        mostly to ensure we understand the interface and catch if things change.
        """
        m = self.model()
        m.scaling_factor = pyo.Suffix(direction=pyo.Suffix.EXPORT)
        m.scaling_factor[m.c1] = 1e-6
        m.scaling_factor[m.x] = 1e-3
        m.scaling_factor[m.y] = 1e-6
        m.scaling_factor[m.z] = 1e-4

        jac, jac_scaled, nlp = sc.constraint_autoscale_large_jac(
            m, ignore_variable_scaling=True)

        c1_row = nlp._condata_to_idx[m.c1]
        c2_row = nlp._condata_to_idx[m.c2]
        c3_row = nlp._condata_to_idx[m.c3]
        x_col = nlp._vardata_to_idx[m.x]
        y_col = nlp._vardata_to_idx[m.y]
        z_col = nlp._vardata_to_idx[m.z]

        assert jac_scaled[c1_row, x_col] == pytest.approx(-1)
        assert jac_scaled[c1_row, y_col] == pytest.approx(-1e-3)
        assert jac_scaled[c1_row, z_col] == pytest.approx(1e-6)
        assert m.scaling_factor[m.c1] == pytest.approx(1e-6)

        assert jac_scaled[c2_row, x_col] == pytest.approx(3)
        assert jac_scaled[c2_row, y_col] == pytest.approx(4)
        assert jac_scaled[c2_row, z_col] == pytest.approx(2)
        assert m.scaling_factor[m.c2] == pytest.approx(1)

        assert jac_scaled[c3_row, z_col] == pytest.approx(3e2)
        assert m.scaling_factor[m.c1] == pytest.approx(1e-6)
def set_scaling_factor(c, v, data_objects=True):
    """Set a scaling factor for a model component. This function creates the
    scaling_factor suffix if needed.

    Args:
        c: component to supply scaling factor for
        v: scaling factor
    Returns:
        None
    """
    if isinstance(c, (float, int)):
        # property packages can return 0 for material balance terms on components
        # doesn't exist.  This handles the case where you get a constant 0 and
        # need it's scale factor to scale the mass balance.
        return 1
    try:
        suf = c.parent_block().scaling_factor
    except AttributeError:
        c.parent_block().scaling_factor = pyo.Suffix(
            direction=pyo.Suffix.EXPORT)
        suf = c.parent_block().scaling_factor

    suf[c] = v
    if data_objects and c.is_indexed():
        for cdat in c.values():
            suf[cdat] = v
Exemple #14
0
def constraint_fd_autoscale(c, min_scale=1e-6, max_grad=100):
    """Autoscale constraints so that if there maximum partial derivative with
    respect to any variable is greater than max_grad at the current variable
    values, the method will attempt to assign a scaling factor to the constraint
    that makes the maximum derivative max_grad.  The min_scale value provides a
    lower limit allowed for constraint scaling factors.  If the caclulated
    scaling factor to make the maxium derivative max_grad is less than min_scale,
    min_scale is used instead.  Derivatives are approximated using finite
    differnce.

    Args:
        c: constraint object
        max_grad: the largest derivative after scaling subject to min_scale
        min_scale: the minimum scale factor allowed

    Returns:
        None
    """
    g, v = grad_fd(c, scaled=True)
    if not hasattr(c.parent_block(), "scaling_factor"):
        c.parent_block().scaling_factor = pyo.Suffix(direction=pyo.Suffix.EXPORT)
    s0 = c.parent_block().scaling_factor.get(c, 1)
    maxg = max(map(abs,g))
    ming = min(map(abs,g))
    if maxg > max_grad:
        c.parent_block().scaling_factor[c] = s0*max_grad/maxg
        if c.parent_block().scaling_factor[c] < min_scale:
            c.parent_block().scaling_factor[c] = min_scale
Exemple #15
0
 def __init__(self, initial_variables_by_commodity, scheduled_trips):
     logging.getLogger('pyomo.core').setLevel(logging.ERROR)
     self.solver = pyo.opt.SolverFactory('cbc')
     self.results = "NotExecuted"
     self.model = pe.ConcreteModel('master_problem')
     indexes = []
     self.cost_vector = {}
     for commodity in initial_variables_by_commodity.keys():
         for index, var in enumerate(
                 initial_variables_by_commodity[commodity]):
             var.index = (commodity, str(index))
             indexes.append(var.index)
             self.cost_vector[var.index] = var.cost
     self.model.DK = indexes
     self.model.var_lambda = pe.Var(self.model.DK,
                                    domain=pe.NonNegativeReals)
     self.model.obj = pe.Objective(expr=sum(self.cost_vector[dk] *
                                            self.model.var_lambda[dk]
                                            for dk in self.model.DK),
                                   sense=pe.minimize)
     self.model.dual = pe.Suffix(direction=pe.Suffix.IMPORT)
     # self.model.rc = pe.Suffix(direction=pe.Suffix.IMPORT_EXPORT)
     self.set_partitioning_constraints(scheduled_trips,
                                       initial_variables_by_commodity)
     self.set_convexity_constraints(initial_variables_by_commodity)
Exemple #16
0
 def build_function_with_BM_suffix():
     pyomo_model = build_function()
     bm_suffix = pyomo_model.component("BigM")
     if bm_suffix is None:
         bm_suffix = pyomo_model.BigM = pyo.Suffix()
     bm_suffix[None] = bigM
     return pyomo_model
Exemple #17
0
def _calculate_scale_factors_from_nominal(m):
    """PRIVATE FUNCTION
    For variables and expressions, if a nominal value is provided calculate the
    scaling factor.

    Args:
        m (Block): a pyomo block to calculate scaling factors for

    Returns:
        None
    """

    for c in m.component_data_objects((pyo.Var, pyo.Expression)):
        # Check for a scaling expression.  If there is one, use it to calculate
        # a scaling factor otherwise use autoscaling.
        if not hasattr(c.parent_block(), "nominal_value"):
            continue # no scaling expression supplied
        elif c not in c.parent_block().nominal_value:
            continue # no scaling expression supplied

        if not hasattr(c.parent_block(), "scaling_factor"):
            # if there is no scaling_factor Suffix yet make one
            c.parent_block().scaling_factor = pyo.Suffix(direction=pyo.Suffix.EXPORT)

        # Add scaling factor from nominal value of variables or expressions
        c.parent_block().scaling_factor[c] = 1/c.parent_block().nominal_value[c]
Exemple #18
0
def test_duals_mip():
    model = pyo.ConcreteModel()
    model.dual = pyo.Suffix(direction=pyo.Suffix.IMPORT)

    model.x = pyo.Var([1, 2], domain=pyo.Boolean)
    model.y = pyo.Var([1, 2], domain=pyo.NonNegativeReals)
    # this problem is basically just two generators:
    # gen1 is cheap, but limited output
    # gen2 is more expensive
    model.OBJ = pyo.Objective(expr=2 * model.y[1] + 3 * model.y[2])
    model.Constraint1 = pyo.Constraint(expr=model.y[1] <= 50 * model.x[1])
    model.Constraint2 = pyo.Constraint(expr=model.y[2] <= 80 * model.x[2])
    model.Constraint3 = pyo.Constraint(expr=model.y[1] + model.y[2] == 100)

    opt = SolverFactory("glpk")
    opt.solve(model)

    # make sure the solution is what we'd expect (both gen need to run)
    assert model.x[1].value == True
    assert model.x[2].value == True

    # fix binary variables
    model.x[1].fixed = True
    model.x[2].fixed = True
    opt.solve(model)
    # make sure the dual is non-zero (constraint is binding)
    assert model.dual[model.Constraint3] != 0
Exemple #19
0
def create_and_solve_simple_model_with_battery(a, d, c_u, q_u, P_max):
    model = pyo.ConcreteModel(name="with battery")
    model.productors_index = range(len(a))
    model.q = pyo.Var(model.productors_index, domain=pyo.NonNegativeReals)
    model.u = pyo.Var(domain=pyo.NonNegativeReals)

    obj_func = lambda model : (pyo.summation(a, model.q) + c_u*model.u)

    def equality(model, d):
        return pyo.summation(model.q) + model.u - d == 0

    def prod_constraint(model, i):
        return model.q[i] <= P_max[i]

    def battery_constraint(model):
        return model.u <= q_u

    model.balance_constraint = pyo.Constraint(rule=lambda model : equality(model, d))
    model.production_constraint = pyo.Constraint(model.productors_index, rule=prod_constraint)
    model.battery = pyo.Constraint(rule=battery_constraint)
    model.obj = pyo.Objective(rule=obj_func)
    # Export and import floating point data
    model.dual = pyo.Suffix(direction=pyo.Suffix.IMPORT_EXPORT)

    solver = pyo.SolverFactory('gurobi')
    solver.solve(model, tee=True)
    results = [pyo.value(model.q[i]) for i in model.productors_index]
    return model
    def test_param_updates(self, name: str, opt_class: Type[PersistentSolver]):
        opt = pe.SolverFactory('appsi_' + name)
        if not opt.available(exception_flag=False):
            raise unittest.SkipTest
        m = pe.ConcreteModel()
        m.x = pe.Var()
        m.y = pe.Var()
        m.a1 = pe.Param(mutable=True)
        m.a2 = pe.Param(mutable=True)
        m.b1 = pe.Param(mutable=True)
        m.b2 = pe.Param(mutable=True)
        m.obj = pe.Objective(expr=m.y)
        m.c1 = pe.Constraint(expr=(0, m.y - m.a1 * m.x - m.b1, None))
        m.c2 = pe.Constraint(expr=(None, -m.y + m.a2 * m.x + m.b2, 0))
        m.dual = pe.Suffix(direction=pe.Suffix.IMPORT)

        params_to_test = [(1, -1, 2, 1), (1, -2, 2, 1), (1, -1, 3, 1)]
        for (a1, a2, b1, b2) in params_to_test:
            m.a1.value = a1
            m.a2.value = a2
            m.b1.value = b1
            m.b2.value = b2
            res = opt.solve(m)
            pe.assert_optimal_termination(res)
            self.assertAlmostEqual(m.x.value, (b2 - b1) / (a1 - a2))
            self.assertAlmostEqual(m.y.value, a1 * (b2 - b1) / (a1 - a2) + b1)
            self.assertAlmostEqual(m.dual[m.c1], (1 + a1 / (a2 - a1)))
            self.assertAlmostEqual(m.dual[m.c2], a1 / (a2 - a1))
Exemple #21
0
    def test_model1_with_scaling(self):
        m = create_model1()
        m.scaling_factor = pyo.Suffix(direction=pyo.Suffix.EXPORT)
        m.scaling_factor[m.o] = 1e-6 # scale the objective
        m.scaling_factor[m.c] = 2.0  # scale the equality constraint
        m.scaling_factor[m.d] = 3.0  # scale the inequality constraint
        m.scaling_factor[m.x[1]] = 4.0  # scale one of the x variables

        cynlp = CyIpoptNLP(PyomoNLP(m))
        options={'nlp_scaling_method': 'user-scaling',
                 'output_file': '_cyipopt-scaling.log',
                 'file_print_level':10,
                 'max_iter': 0}
        solver = CyIpoptSolver(cynlp, options=options)
        x, info = solver.solve()

        with open('_cyipopt-scaling.log', 'r') as fd:
            solver_trace = fd.read()
        os.remove('_cyipopt-scaling.log')

        # check for the following strings in the log and then delete the log
        self.assertIn('nlp_scaling_method = user-scaling', solver_trace)
        self.assertIn('output_file = _cyipopt-scaling.log', solver_trace)
        self.assertIn('objective scaling factor = 1e-06', solver_trace)
        self.assertIn('x scaling provided', solver_trace)
        self.assertIn('c scaling provided', solver_trace)
        self.assertIn('d scaling provided', solver_trace)
        self.assertIn('DenseVector "x scaling vector" with 3 elements:', solver_trace)
        self.assertIn('x scaling vector[    1]= 1.0000000000000000e+00', solver_trace)
        self.assertIn('x scaling vector[    2]= 1.0000000000000000e+00', solver_trace)
        self.assertIn('x scaling vector[    3]= 4.0000000000000000e+00', solver_trace)
        self.assertIn('DenseVector "c scaling vector" with 1 elements:', solver_trace)
        self.assertIn('c scaling vector[    1]= 2.0000000000000000e+00', solver_trace)
        self.assertIn('DenseVector "d scaling vector" with 1 elements:', solver_trace)
        self.assertIn('d scaling vector[    1]= 3.0000000000000000e+00', solver_trace)
def solve(n, B, F, costs, loads, transCap, P=[], dk_dp=[]):
    # initialize model
    model = pyo.ConcreteModel()
    model.N = pyo.Set(ordered=True,
                      initialize=[i for i in range(n)
                                  ])  # Set of the n nodes in our system
    model.P = pyo.Var(
        model.N, domain=pyo.NonNegativeReals
    )  # Make 4 P-variables that represent power generated at each node
    model.delta = pyo.Var(
        model.N
    )  # Make 4 variables that represent the voltage angles at each node
    model.constraints = pyo.ConstraintList(
    )  # Define the list of all constraints

    # Define the objective function to be the sum of the costs of the generators times their respective power production
    def ObjectiveFunction(model):
        return sum(model.P[i] * costs[i] for i in model.N)

    model.obj = pyo.Objective(rule=ObjectiveFunction, sense=pyo.minimize)

    # Set slack bus angle to zero
    model.constraints.add(model.delta[3] == 0)

    # Define constraint P+L=B*Delta
    for i in model.N:
        lhs = model.P[i] + loads[i]
        rhs = sum(B[i][c] * model.delta[c] for c in model.N)
        model.constraints.add(lhs == rhs)

    # Define constraint -FLmax <= F*Delta <= FLmax
    for i in model.N:
        rhs = transCap[2 - i]
        lhs = -rhs
        mid = sum(F[i][c] * model.delta[c] for c in model.N)
        model.constraints.add(pyo.inequality(lhs, mid, rhs))

    if len(P):
        model.constraints.add(
            sum((model.P[i] - P[i]) * dk_dp[i] for i in model.N) <= 0)

    # Solve model
    opt = SolverFactory("gurobi")
    model.dual = pyo.Suffix(direction=pyo.Suffix.IMPORT)
    model.rc = pyo.Suffix(direction=pyo.Suffix.IMPORT)
    opt.solve(model, load_solutions=True)
    return model
Exemple #23
0
def LPQPkkta():
    KKTsat = False
    Threshold = 1e-5

    m = pyo.ConcreteModel()
    m.z1 = pyo.Var()
    m.z2 = pyo.Var()
    m.obj = pyo.Objective(expr=m.z1**2 + m.z2**2)
    m.c1 = pyo.Constraint(expr=m.z1 <= -3)
    m.c2 = pyo.Constraint(expr=m.z2 <= 4)
    m.c3 = pyo.Constraint(expr=4 * m.z1 + 3 * m.z2 <= 0)

    m.dual = pyo.Suffix(direction=pyo.Suffix.IMPORT)

    res = pyo.SolverFactory('ipopt').solve(m)
    if res.solver.termination_condition is not TerminationCondition.optimal:
        KKTsat = False
    else:
        zOpt = np.array([m.z1(), m.z2()])
        A = np.array([1, 0, 0, 1, 4, 3]).reshape((3, 2))
        b = np.array([-3, 4, 0])
        # ---------------------don't reshape here ---------------------

        u = []
        for c in m.component_objects(pyo.Constraint, active=True):
            print("Constraint", c)
            for index in c:
                print(m.dual[c[index]])
                u.append(m.dual[c[index]])

        u = np.asarray(u)

        for i in range(len(u)):
            if u[i] < Threshold and u[i] > -Threshold:
                u[i] = 0

        x = A @ zOpt - b
        flag_ineq = np.any(np.all(x <= Threshold) or np.all(x <= -Threshold))
        # flag_ineq = np.any(np.all(A @ zOpt <= b + Threshold) or np.all(A@zOpt <= b -Threshold))
        flag_dual = np.all(u >= 0)
        # flag_cs = np.all(np.multiply(u,x) < Threshold and np.all(np.multiply(u,x) > -Threshold))
        flag_cs = np.all(np.multiply(u, x) < Threshold) and np.all(
            np.multiply(u, x) > -Threshold)
        # ------------------- pay attention here ---------------------

        grad_lagrangian = [2 * zOpt[0], 2 * zOpt[1]] + u.T @ A
        for i, y in enumerate(grad_lagrangian):
            if y < Threshold and y > -Threshold:
                grad_lagrangian[i] = 0

        flag_grad = np.all(grad_lagrangian == 0)
        flags = [flag_ineq, flag_dual, flag_cs, flag_grad]
        flags = np.array(flags)
        if all(flags == 1):
            KKTsat = True
        else:
            KKTsat = False

        return KKTsat
Exemple #24
0
    def _create_primal(self):
        # Create the primal pyomo model.
        #
        # This is used to compute flows after interdiction. The interdiction
        # is stored in arc_data.xbar.
        model = pe.ConcreteModel()

        # Tell pyomo to read in dual-variable information from the solver:
        model.dual = pe.Suffix(direction=pe.Suffix.IMPORT)

        # Add the sets:
        model.node_set = pe.Set(initialize=self._topology.node_set)
        model.edge_set = pe.Set(initialize=self._topology.link_set, dimen=2)

        # Create the variables:
        model.y = pe.Var(model.edge_set, domain=pe.NonNegativeReals)
        model.UnsatSupply = pe.Var(model.node_set, domain=pe.NonNegativeReals)
        model.UnsatDemand = pe.Var(model.node_set, domain=pe.NonNegativeReals)

        # Create the objective:
        def obj_rule(model):
            return sum((data["risk"] + data["xbar"] * (2 * self._nCmax + 1))
                       * model.y[e] for e, data in self._topology.link_data.iterrows()) \
                + sum(self._nCmax * (model.UnsatSupply[n] + model.UnsatDemand[n])
                      for n, data in self._topology.node_data.iterrows())

        model.OBJ = pe.Objective(rule=obj_rule, sense=pe.minimize)

        # Create the constraints, one for each node:
        def flow_bal_rule(model, n):
            tmp = self._topology.link_data.reset_index()
            successors = tmp.loc[tmp.start_node == n, "end_node"].values
            predecessors = tmp.loc[tmp.end_node == n, "start_node"].values
            lhs = sum(model.y[(i, n)] for i in predecessors) \
                - sum(model.y[(n, i)] for i in successors)
            imbalance = self._topology.node_data["supply_demand"].get(n, 0)
            supply_node = int(imbalance < 0)
            demand_node = int(imbalance > 0)
            rhs = (imbalance + model.UnsatSupply[n] * supply_node -
                   model.UnsatDemand[n] * demand_node)
            constr = (lhs == rhs)
            if isinstance(constr, bool):
                return pe.Constraint.Skip
            return constr

        model.FlowBalance = pe.Constraint(model.node_set, rule=flow_bal_rule)

        # Capacity constraints, one for each edge:
        def capacity_rule(model, i, j):
            capacity = self._topology.link_data["capacity"].get((i, j), -1)
            if capacity < 0:
                return pe.Constraint.Skip
            return model.y[(i, j)] <= capacity

        model.Capacity = pe.Constraint(model.edge_set, rule=capacity_rule)

        # Return the model
        return model
Exemple #25
0
def multicommodity_minimum_cost_flow(graphs: list, common_arcs: list, integer: bool):
    modelo = pe.ConcreteModel(name="MCFP")

    modelo.dual = pe.Suffix(direction=pe.Suffix.IMPORT)

    commodities_arcs = {(graph_k.commodity_name, str(arc[0])):
                            arc for graph_k in graphs for arc in graph_k.arcs_cost_cap.items()}
    modelo.var_indexes = commodities_arcs.keys()
    modelo.var = pe.Var(modelo.var_indexes, within=pe.NonNegativeIntegers if integer else pe.NonNegativeReals)

    def objetivo(m):
        return sum(commodities_arcs[index][1][0] * m.var[index] for index in modelo.var_indexes)

    modelo.obj = pe.Objective(rule=objetivo, sense=pe.minimize)

    commodities_nodes = [(commodity, node) for commodity in graphs for node in commodity.nodes_demands.items()]

    def conserva_fluxo(m, index):
        commodity, node = commodities_nodes[index]
        from_i = [str(arc) for arc in commodity.arcs_cost_cap.keys() if arc.origin == node[0]]
        to_i = [str(arc) for arc in commodity.arcs_cost_cap.keys() if arc.destination == node[0]]
        return sum(m.var[(commodity.commodity_name, v)] for v in from_i) - sum(
            m.var[(commodity.commodity_name, v)] for v in to_i) == node[1]

    modelo.commodities_nodes_indexes = range(len(commodities_nodes))
    modelo.flow_conservation = pe.Constraint(modelo.commodities_nodes_indexes, rule=conserva_fluxo)

    def capacidades_conjuntas(m, index):
        soma = sum(m.var[(commodity.commodity_name, str(common_arcs[index]))] for commodity in graphs
                   if (commodity.commodity_name, str(common_arcs[index])) in modelo.var_indexes)
        return soma <= common_arcs[index].capacity

    modelo.capacidade_conjunta_arco = pe.Constraint(range(len(common_arcs)), rule=capacidades_conjuntas)

    def lower_bound_conjuntas(m, index):
        soma = sum(m.var[(commodity.commodity_name, str(common_arcs[index]))] for commodity in graphs
                   if (commodity.commodity_name, str(common_arcs[index])) in modelo.var_indexes)
        return common_arcs[index].lower_bound <= soma

    modelo.lower_bound_conjunta_arco = pe.Constraint(range(len(common_arcs)), rule=lower_bound_conjuntas)

    def capacidades(m, commodity, arc):
        var_index = (commodity, arc)
        return m.var[var_index] <= commodities_arcs.get(var_index)[1][1]

    modelo.capacidade = pe.Constraint(modelo.var_indexes, rule=capacidades)

    solver = pyomo.opt.SolverFactory('cbc')
    results = solver.solve(modelo)
    modelo.display()
    # modelo.pprint()

    print(results.solver.status)
    for dk in modelo.var_indexes:
        if modelo.var[dk].value > 0:
            print(dk, modelo.var[dk].value)

    print(modelo.obj())
    def create_and_solve_lmp(
        self,
        options: Options,
        sced_instance: OperationsModel,
    ) -> OperationsModel:

        lmp_sced_instance = sced_instance.clone()

        # In case of demand shortfall, the price skyrockets, so we threshold the value.
        system = lmp_sced_instance.data['system']
        for system_key, threshold_value in self._p.get_attrs_to_price_option(
                options):
            if threshold_value is not None and (
                (system_key not in system) or
                (system[system_key] > threshold_value)):
                system[system_key] = threshold_value

        if self._last_sced_pyo_model is None:
            self._ptdf_manager.mark_active(lmp_sced_instance)

            slack_type = _slack_type_to_egret_slack_type[
                options.sced_slack_type]
            network_type = _network_type_to_egret_network_constraints[
                options.sced_network_type]

            pyo_model = create_sced_uc_model(
                lmp_sced_instance,
                relaxed=True,
                ptdf_options=self._ptdf_manager.lmpsced_ptdf_options,
                PTDF_matrix_dict=self._ptdf_manager.PTDF_matrix_dict,
                slack_type=slack_type,
                network_constraints=network_type)
            pyo_solver = self._sced_solver
            self._p._zero_out_costs(pyo_model, self._hours_in_objective)
        else:
            pyo_model = self._last_sced_pyo_model
            pyo_solver = self._last_sced_pyo_solver
            self._transform_for_lmp(pyo_model, pyo_solver, lmp_sced_instance)

        pyo_model.dual = pe.Suffix(direction=pe.Suffix.IMPORT)

        try:
            lmp_sced_results, _, _ = self._p.call_solver(
                pyo_solver,
                pyo_model,
                options,
                options.sced_solver_options,
                relaxed=True,
                set_instance=(self._last_sced_pyo_model is None))
        except:
            print("Some issue with LMP SCED, writing instance")
            quickstart_uc_filename = options.output_directory + os.sep + "FAILED_LMP_SCED.json"
            lmp_sced_instance.write(quickstart_uc_filename)
            print(f"Problematic LMP SCED written to {quickstart_uc_filename}")
            raise

        return lmp_sced_results
Exemple #27
0
 def m2(self):
     m = pyo.ConcreteModel()
     m.factor = pyo.Param(initialize=1.0e-16, mutable=True)
     m.x = pyo.Var(bounds=(0.5 * m.factor, 1.5 * m.factor),
                   initialize=m.factor)
     m.scaling_factor = pyo.Suffix(direction=pyo.Suffix.EXPORT)
     m.scaling_factor[m.x] = pyo.value(1. / m.factor)
     m.o = pyo.Objective(expr=m.x / m.factor)
     return m
Exemple #28
0
    def create_and_solve_lmp(
        self,
        sced_instance: OperationsModel,
        options: Options,
    ) -> OperationsModel:

        lmp_sced_instance = sced_instance.clone()

        # In case of demand shortfall, the price skyrockets, so we threshold the value.
        if 'load_mismatch_cost' not in lmp_sced_instance.data['system'] or \
                lmp_sced_instance.data['system']['load_mismatch_cost'] > \
                    options.price_threshold:
            lmp_sced_instance.data['system'][
                'load_mismatch_cost'] = options.price_threshold

        # In case of reserve shortfall, the price skyrockets, so we threshold the value.
        if 'reserve_shortfall_cost' not in lmp_sced_instance.data['system'] or \
                lmp_sced_instance.data['system']['reserve_shortfall_cost'] > \
                    options.reserve_price_threshold:
            lmp_sced_instance.data['system']['reserve_shortfall_cost'] = \
                    options.reserve_price_threshold

        if self._last_sced_pyo_model is None:
            self._ptdf_manager.mark_active(lmp_sced_instance)
            pyo_model = create_sced_uc_model(
                lmp_sced_instance,
                relaxed=True,
                ptdf_options=self._ptdf_manager.lmpsced_ptdf_options,
                PTDF_matrix_dict=self._ptdf_manager.PTDF_matrix_dict)
            pyo_solver = self._sced_solver
            self._p._zero_out_costs(pyo_model, self._hours_in_objective)
        else:
            pyo_model = self._last_sced_pyo_model
            pyo_solver = self._last_sced_pyo_solver
            self._transform_for_lmp(pyo_model, pyo_solver, lmp_sced_instance)

        pyo_model.dual = pe.Suffix(direction=pe.Suffix.IMPORT)

        try:
            lmp_sced_results, _, _ = self._p.call_solver(
                pyo_solver,
                pyo_model,
                options,
                options.sced_solver_options,
                relaxed=True,
                set_instance=(self._last_sced_pyo_model is None))
        except:
            print("Some issue with LMP SCED, writing instance")
            quickstart_uc_filename = options.output_directory + os.sep + "FAILED_LMP_SCED.json"
            lmp_sced_instance.write(quickstart_uc_filename)
            print(f"Problematic LMP SCED written to {quickstart_uc_filename}")
            raise

        self._attach_fake_pyomo_objects(lmp_sced_results)

        return lmp_sced_results
Exemple #29
0
def _employee(linear=False, **kwargs):
    """
    Factory method for the Employee scheduling problem.

    Parameters
    ----------
    linear : :py:obj:`bool`, optional
        Determines whether decision variables will be
        Reals (True) or Integer (False).
    **kwargs : optional
        if any given, returns pyomo concrete model instead, with these passed
        into pyomo's `create_instance`.

    Notes
    -----
    Simple model: minimize # of workers employed to meet shift requirements
    """
    def _obj_expression(model):
        """Objective Expression: Minimizing Number of Workers"""
        return pyo.summation(model.NumWorkers)

    def _period_reqs_constraint_rule(model, p):
        """Constraints for having enough workers per period"""
        # Get index of current period
        ind = model.Periods.ord(p)
        num_periods = len(model.Periods)
        # Get effective periods based on ShiftLength - loops back
        effective_periods = [
            model.Periods[((ind - 1 - shift) % num_periods) + 1]
            for shift in range(model.ShiftLength.value)
        ]
        # Sum up how many workers are working this period
        my_sum = sum(
            [model.NumWorkers[period] for period in effective_periods])
        return my_sum >= model.PeriodReqs[p]

    # Create the abstract model & dual suffix
    model = pyo.AbstractModel()
    model.dual = pyo.Suffix(direction=pyo.Suffix.IMPORT)
    # Define sets/params that are always used
    model.Periods = pyo.Set(ordered=True)
    model.ShiftLength = pyo.Param()  # num periods a worker works in a row
    model.PeriodReqs = pyo.Param(model.Periods)
    # Define decision variables
    model.NumWorkers = pyo.Var(
        model.Periods,
        within=pyo.NonNegativeReals if linear else pyo.NonNegativeIntegers)
    # Define objective & constraints
    model.OBJ = pyo.Objective(rule=_obj_expression, sense=pyo.minimize)
    model.PeriodReqsConstraint = pyo.Constraint(
        model.Periods, rule=_period_reqs_constraint_rule)
    # Check if returning concrete or abstract model
    if kwargs:
        return model.create_instance(**kwargs)
    else:
        return model
Exemple #30
0
def solve(localsolver, solvername, instance,
          logfilename='logfile_loadobjective.log',
          get_suffixes=True, solver_options=None, outputfile=None):
    # Wall time - clock starts.
    starttime_modelsolve = time.time()

    if localsolver:
        solver = SolverFactory(solvername)

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

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

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


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

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

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

        results.write()

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

    feasible = check_whether_feasible(instance, results)

    return instance, results, feasible