예제 #1
0
파일: test_mcpp.py 프로젝트: mskarha/pyomo
 def test_reciprocal(self):
     m = ConcreteModel()
     m.x = Var(bounds=(1, 2), initialize=1)
     m.y = Var(bounds=(2, 3), initialize=2)
     mc_expr = mc(m.x / m.y)
     self.assertEqual(mc_expr.lower(), 1 / 3)
     self.assertEqual(mc_expr.upper(), 1)
예제 #2
0
파일: test_mcpp.py 프로젝트: mskarha/pyomo
 def test_var(self):
     m = ConcreteModel()
     m.x = Var(bounds=(-1, 1), initialize=3)
     mc_var = mc(m.x)
     self.assertEqual(mc_var.lower(), -1)
     self.assertEqual(mc_var.upper(), 1)
     m.no_ub = Var(bounds=(0, None), initialize=3)
     output = StringIO()
     with LoggingIntercept(output, 'pyomo.contrib.mcpp', logging.WARNING):
         mc_var = mc(m.no_ub)
         self.assertIn("Var no_ub missing upper bound.",
                       output.getvalue().strip())
         self.assertEqual(mc_var.lower(), 0)
         self.assertEqual(mc_var.upper(), 500000)
     m.no_lb = Var(bounds=(None, -3), initialize=-1)
     output = StringIO()
     with LoggingIntercept(output, 'pyomo.contrib.mcpp', logging.WARNING):
         mc_var = mc(m.no_lb)
         self.assertIn("Var no_lb missing lower bound.",
                       output.getvalue().strip())
         self.assertEqual(mc_var.lower(), -500000)
         self.assertEqual(mc_var.upper(), -3)
     m.no_val = Var(bounds=(0, 1))
     output = StringIO()
     with LoggingIntercept(output, 'pyomo.contrib.mcpp', logging.WARNING):
         mc_var = mc(m.no_val)
         mc_var.subcv()
         self.assertIn("Var no_val missing value.",
                       output.getvalue().strip())
         self.assertEqual(mc_var.lower(), 0)
         self.assertEqual(mc_var.upper(), 1)
예제 #3
0
파일: test_mcpp.py 프로젝트: mskarha/pyomo
 def test_linear_expression(self):
     m = ConcreteModel()
     m.x = Var(bounds=(1, 2), initialize=1)
     with self.assertRaises(NotImplementedError):
         mc_expr = mc(quicksum([m.x, m.x], linear=True))
         self.assertEqual(mc_expr.lower(), 2)
         self.assertEqual(mc_expr.upper(), 4)
예제 #4
0
파일: test_util.py 프로젝트: Pyomo/pyomo
    def test_clone_without_expression_components(self):
        m = ConcreteModel()
        m.x = Var(initialize=5)
        m.y = Var(initialize=3)
        m.e = Expression(expr=m.x**2 + m.x - 1)

        base = m.x**2 + 1
        test = clone_without_expression_components(base, {})
        self.assertIs(base, test)
        self.assertEqual(base(), test())
        test = clone_without_expression_components(base, {id(m.x): m.y})
        self.assertEqual(3**2+1, test())

        base = m.e
        test = clone_without_expression_components(base, {})
        self.assertIsNot(base, test)
        self.assertEqual(base(), test())
        self.assertIsInstance(base, _ExpressionData)
        self.assertIsInstance(test, EXPR.SumExpression)
        test = clone_without_expression_components(base, {id(m.x): m.y})
        self.assertEqual(3**2+3-1, test())

        base = m.e + m.x
        test = clone_without_expression_components(base, {})
        self.assertIsNot(base, test)
        self.assertEqual(base(), test())
        self.assertIsInstance(base, EXPR.SumExpression)
        self.assertIsInstance(test, EXPR.SumExpression)
        self.assertIsInstance(base.arg(0), _ExpressionData)
        self.assertIsInstance(test.arg(0), EXPR.SumExpression)
        test = clone_without_expression_components(base, {id(m.x): m.y})
        self.assertEqual(3**2+3-1 + 3, test())
예제 #5
0
 def test_active_parent_block(self):
     m = ConcreteModel()
     m.d1 = Block()
     m.d1.sub1 = Disjunct()
     m.d1.sub2 = Disjunct()
     m.d1.disj = Disjunction(expr=[m.d1.sub1, m.d1.sub2])
     with self.assertRaises(GDP_Error):
         TransformationFactory('gdp.reclassify').apply_to(m)
예제 #6
0
파일: test_mcpp.py 프로젝트: mskarha/pyomo
 def test_lmtd(self):
     m = ConcreteModel()
     m.x = Var(bounds=(0.1, 500), initialize=33.327)
     m.y = Var(bounds=(0.1, 500), initialize=14.436)
     m.z = Var(bounds=(0, 90), initialize=22.5653)
     mc_expr = mc(m.z - (m.x * m.y * (m.x + m.y) / 2) ** (1/3))
     self.assertAlmostEqual(mc_expr.convex(), -407.95444629965016)
     self.assertAlmostEqual(mc_expr.lower(), -499.99999999999983)
예제 #7
0
파일: test_mcpp.py 프로젝트: mskarha/pyomo
 def test_improved_bounds(self):
     m = ConcreteModel()
     m.x = Var(bounds=(0, 100), initialize=5)
     improved_bounds = ComponentMap()
     improved_bounds[m.x] = (10, 20)
     mc_expr = mc(m.x, improved_var_bounds=improved_bounds)
     self.assertEqual(mc_expr.lower(), 10)
     self.assertEqual(mc_expr.upper(), 20)
예제 #8
0
파일: test_mcpp.py 프로젝트: Pyomo/pyomo
 def test_fixed_var(self):
     m = ConcreteModel()
     m.x = Var(bounds=(-50, 80), initialize=3)
     m.y = Var(bounds=(0, 6), initialize=2)
     m.y.fix()
     mc_expr = mc(m.x * m.y)
     self.assertEqual(mc_expr.lower(), -100)
     self.assertEqual(mc_expr.upper(), 160)
예제 #9
0
파일: models.py 프로젝트: Pyomo/pyomo
def makeDisjunctWithRangeSet():
    m = ConcreteModel()
    m.x = Var(bounds=(0, 1))
    m.d1 = Disjunct()
    m.d1.s = RangeSet(1)
    m.d1.c = Constraint(rule=lambda _: m.x == 1)
    m.d2 = Disjunct()
    m.disj = Disjunction(expr=[m.d1, m.d2])
    return m
예제 #10
0
파일: test_mcpp.py 프로젝트: mskarha/pyomo
 def test_mc_2d(self):
     m = ConcreteModel()
     m.x = Var(bounds=(pi / 6, pi / 3), initialize=pi / 4)
     m.e = Expression(expr=cos(pow(m.x, 2)) * sin(pow(m.x, -3)))
     mc_ccVals, mc_cvVals, aff_cc, aff_cv = make2dPlot(m.e.expr, 50)
     self.assertAlmostEqual(mc_ccVals[1], 0.6443888590411435)
     self.assertAlmostEqual(mc_cvVals[1], 0.2328315489072924)
     self.assertAlmostEqual(aff_cc[1], 0.9674274332870583)
     self.assertAlmostEqual(aff_cv[1], -1.578938503009686)
예제 #11
0
파일: test_mcpp.py 프로젝트: mskarha/pyomo
 def test_mc_3d(self):
     m = ConcreteModel()
     m.x = Var(bounds=(-2, 1), initialize=-1)
     m.y = Var(bounds=(-1, 2), initialize=0)
     m.e = Expression(expr=m.x * pow(exp(m.x) - m.y, 2))
     ccSurf, cvSurf, ccAffine, cvAffine = make3dPlot(m.e.expr, 30)
     self.assertAlmostEqual(ccSurf[48], 11.5655473482574)
     self.assertAlmostEqual(cvSurf[48], -15.28102124928224)
     self.assertAlmostEqual(ccAffine[48], 11.565547348257398)
     self.assertAlmostEqual(cvAffine[48], -23.131094696514797)
예제 #12
0
    def test_indexedvar_noindextemplate(self):
        st_model = CreateConcreteTwoStageScenarioTreeModel(1)
        st_model.StageVariables['Stage1'].add("x")
        st_model.StageDerivedVariables['Stage1'].add("y")
        st_model.NodeVariables['RootNode'].add("z")
        st_model.NodeDerivedVariables['RootNode'].add("q")
        st_model.StageCost['Stage1'] = "FirstStageCost"
        st_model.StageCost['Stage2'] = "SecondStageCost"

        scenario_tree = ScenarioTree(scenariotreeinstance=st_model)
        self.assertEqual(len(scenario_tree.stages), 2)
        self.assertEqual(len(scenario_tree.nodes), 2)
        self.assertEqual(len(scenario_tree.scenarios), 1)

        model = ConcreteModel()
        model.s = Set(initialize=[1,2,3])
        model.x = Var(model.s)
        model.y = Var(model.s)
        model.z = Var(model.s)
        model.q = Var(model.s)
        model.FirstStageCost = Expression(expr=0.0)
        model.SecondStageCost = Expression(expr=0.0)
        model.obj = Objective(expr=0.0)

        scenario_tree.linkInInstances({'Scenario1': model})

        root = scenario_tree.findRootNode()
        self.assertEqual(len(root._variable_ids), 12)
        self.assertEqual(len(root._standard_variable_ids), 6)
        self.assertEqual(len(root._derived_variable_ids), 6)
        for name in ("x", "y", "z", "q"):
            for index in model.s:
                self.assertEqual(
                    (name,index) in root._name_index_to_id, True)
예제 #13
0
파일: test_mcpp.py 프로젝트: mskarha/pyomo
 def test_fixed_var(self):
     m = ConcreteModel()
     m.x = Var(bounds=(-50, 80), initialize=3)
     m.y = Var(bounds=(0, 6), initialize=2)
     m.y.fix()
     mc_expr = mc(m.x * m.y)
     self.assertEqual(mc_expr.lower(), -100)
     self.assertEqual(mc_expr.upper(), 160)
     self.assertEqual(
         str(mc_expr),
         "[ -1.00000e+02 :  1.60000e+02 ] [  6.00000e+00 :  6.00000e+00 ] [ ( 2.00000e+00) : ( 2.00000e+00) ]")
예제 #14
0
 def test_deactivated_parent_block(self):
     m = ConcreteModel()
     m.d1 = Block()
     m.d1.sub1 = Disjunct()
     m.d1.sub2 = Disjunct()
     m.d1.disj = Disjunction(expr=[m.d1.sub1, m.d1.sub2])
     m.d1.deactivate()
     TransformationFactory('gdp.reclassify').apply_to(m)
     self.assertIs(m.d1.type(), Block)
     self.assertIs(m.d1.sub1.type(), Block)
     self.assertIs(m.d1.sub2.type(), Block)
예제 #15
0
 def test_active_parent_disjunct_target(self):
     m = ConcreteModel()
     m.d1 = Disjunct()
     m.d1.sub1 = Disjunct()
     m.d1.sub2 = Disjunct()
     m.d1.disj = Disjunction(expr=[m.d1.sub1, m.d1.sub2])
     TransformationFactory('gdp.bigm').apply_to(m, targets=m.d1.disj)
     m.d1.indicator_var.fix(1)
     TransformationFactory('gdp.reclassify').apply_to(m)
     self.assertIs(m.d1.type(), Block)
     self.assertIs(m.d1.sub1.type(), Block)
     self.assertIs(m.d1.sub2.type(), Block)
예제 #16
0
파일: test_mcpp.py 프로젝트: mskarha/pyomo
 def test_trig(self):
     m = ConcreteModel()
     m.x = Var(bounds=(pi / 4, pi / 2), initialize=pi / 4)
     mc_expr = mc(tan(atan((m.x))))
     self.assertAlmostEqual(mc_expr.lower(), pi / 4)
     self.assertAlmostEqual(mc_expr.upper(), pi / 2)
     m.y = Var(bounds=(0, sin(pi / 4)), initialize=0)
     mc_expr = mc(asin((m.y)))
     self.assertEqual(mc_expr.lower(), 0)
     self.assertAlmostEqual(mc_expr.upper(), pi / 4)
     m.z = Var(bounds=(0, cos(pi / 4)), initialize=0)
     mc_expr = mc(acos((m.z)))
     self.assertAlmostEqual(mc_expr.lower(), pi / 4)
     self.assertAlmostEqual(mc_expr.upper(), pi / 2)
예제 #17
0
    def test_singletonvar_wildcardtemplate(self):
        st_model = CreateConcreteTwoStageScenarioTreeModel(1)
        st_model.StageVariables['Stage1'].add("x[*]")
        st_model.StageDerivedVariables['Stage1'].add("y[*]")
        st_model.NodeVariables['RootNode'].add("z[*]")
        st_model.NodeDerivedVariables['RootNode'].add("q[*]")
        st_model.StageCost['Stage1'] = "FirstStageCost"
        st_model.StageCost['Stage2'] = "SecondStageCost"

        scenario_tree = ScenarioTree(scenariotreeinstance=st_model)
        self.assertEqual(len(scenario_tree.stages), 2)
        self.assertEqual(len(scenario_tree.nodes), 2)
        self.assertEqual(len(scenario_tree.scenarios), 1)

        model = ConcreteModel()
        model.x = Var()
        model.y = Var()
        model.z = Var()
        model.q = Var()
        model.FirstStageCost = Expression(expr=0.0)
        model.SecondStageCost = Expression(expr=0.0)
        model.obj = Objective(expr=0.0)

        scenario_tree.linkInInstances({'Scenario1': model})

        root = scenario_tree.findRootNode()
        self.assertEqual(len(root._variable_ids), 4)
        self.assertEqual(len(root._standard_variable_ids), 2)
        self.assertEqual(len(root._derived_variable_ids), 2)
        for name in ("x", "y", "z", "q"):
            for index in [None]:
                self.assertEqual(
                    (name,index) in root._name_index_to_id, True)
예제 #18
0
    def select_tear_mip_model(self, G):
        """
        Generate a model for selecting tears from the given graph

        Returns
        -------
            model
            bin_list
                A list of the binary variables representing each edge,
                indexed by the edge index of the graph
        """
        model = ConcreteModel()

        bin_list = []
        for i in range(G.number_of_edges()):
            # add a binary "torn" variable for every edge
            vname = "edge%s" % i
            var = Var(domain=Binary)
            bin_list.append(var)
            model.add_component(vname, var)

        # var containing the maximum number of times any cycle is torn
        mct = model.max_cycle_tears = Var()

        _, cycleEdges = self.all_cycles(G)

        for i in range(len(cycleEdges)):
            ecyc = cycleEdges[i]

            # expression containing sum of tears for each cycle
            ename = "cycle_sum%s" % i
            expr = Expression(expr=sum(bin_list[i] for i in ecyc))
            model.add_component(ename, expr)

            # every cycle must have at least 1 tear
            cname_min = "cycle_min%s" % i
            con_min = Constraint(expr=expr >= 1)
            model.add_component(cname_min, con_min)

            # mct >= cycle_sum for all cycles, thus it becomes the max
            cname_mct = mct.name + "_geq%s" % i
            con_mct = Constraint(expr=mct >= expr)
            model.add_component(cname_mct, con_mct)

        # weigh the primary objective much greater than the secondary
        obj_expr = 1000 * mct + sum(var for var in bin_list)
        model.obj = Objective(expr=obj_expr, sense=minimize)

        return model, bin_list
예제 #19
0
 def test_deactivate_nested_disjunction(self):
     m = ConcreteModel()
     m.d1 = Disjunct()
     m.d1.d1 = Disjunct()
     m.d1.d2 = Disjunct()
     m.d1.disj = Disjunction(expr=[m.d1.d1, m.d1.d2])
     m.d2 = Disjunct()
     m.disj = Disjunction(expr=[m.d1, m.d2])
     m.d1.deactivate()
     TransformationFactory('gdp.bigm').apply_to(m)
     # for disj in m.component_data_objects(Disjunction, active=True):
     #     print(disj.name)
     # There should be no active Disjunction objects.
     self.assertIsNone(
         next(m.component_data_objects(Disjunction, active=True), None))
예제 #20
0
파일: models.py 프로젝트: Pyomo/pyomo
def makeThreeTermDisj_IndexedConstraints():
    m = ConcreteModel()
    m.I = [1, 2, 3]
    m.x = Var(m.I, bounds=(0, 10))

    def c_rule(b, i):
        m = b.model()
        return m.x[i] >= i

    def d_rule(d, j):
        m = d.model()
        d.c = Constraint(m.I[:j], rule=c_rule)
    m.d = Disjunct(m.I, rule=d_rule)
    m.disjunction = Disjunction(expr=[m.d[i] for i in m.I])
    return m
예제 #21
0
파일: models.py 프로젝트: Pyomo/pyomo
def makeTwoTermDisj():
    m = ConcreteModel()
    m.a = Var(bounds=(2, 7))
    m.x = Var(bounds=(4, 9))

    def d_rule(disjunct, flag):
        m = disjunct.model()
        if flag:
            disjunct.c1 = Constraint(expr=m.a == 0)
            disjunct.c2 = Constraint(expr=m.x <= 7)
        else:
            disjunct.c = Constraint(expr=m.a >= 5)
    m.d = Disjunct([0, 1], rule=d_rule)
    m.disjunction = Disjunction(expr=[m.d[0], m.d[1]])
    return m
예제 #22
0
 def _create_model(self, ctype, **kwds):
     self.model = ConcreteModel()
     self.model.x = Var()
     self.model.IDX = Set(initialize=sorted(range(1000000)))
     self.model.del_component('test_component')
     self.model.test_component = \
         ctype(self.model.IDX, **kwds)
예제 #23
0
파일: test_mcpp.py 프로젝트: mskarha/pyomo
 def test_powers(self):
     m = ConcreteModel()
     m.x = Var(bounds=(0, 2), initialize=1)
     m.y = Var(bounds=(1e-4, 2), initialize=1)
     with self.assertRaisesRegexp(MCPP_Error, "Log with negative values in range"):
         mc(m.x ** 1.5)
     mc_expr = mc(m.y ** 1.5)
     self.assertAlmostEqual(mc_expr.lower(), 1e-4**1.5)
     self.assertAlmostEqual(mc_expr.upper(), 2**1.5)
     mc_expr = mc(m.y ** m.x)
     self.assertAlmostEqual(mc_expr.lower(), 1e-4**2)
     self.assertAlmostEqual(mc_expr.upper(), 4)
     m.z = Var(bounds=(-1, 1), initialize=0)
     mc_expr = mc(m.z ** 2)
     self.assertAlmostEqual(mc_expr.lower(), 0)
     self.assertAlmostEqual(mc_expr.upper(), 1)
예제 #24
0
파일: models.py 프로젝트: Pyomo/pyomo
def makeTwoTermIndexedDisjunction_BoundedVars():
    m = ConcreteModel()
    m.s = Set(initialize=[1, 2, 3])
    m.a = Var(m.s, bounds=(-100, 100))

    def disjunct_rule(d, s, flag):
        m = d.model()
        if flag:
            d.c = Constraint(expr=m.a[s] >= 6)
        else:
            d.c = Constraint(expr=m.a[s] <= 3)
    m.disjunct = Disjunct(m.s, [0, 1], rule=disjunct_rule)

    def disjunction_rule(m, s):
        return [m.disjunct[s, flag] for flag in [0, 1]]
    m.disjunction = Disjunction(m.s, rule=disjunction_rule)
    return m
예제 #25
0
파일: models.py 프로젝트: Pyomo/pyomo
def makeTwoTermDisj_IndexedConstraints_BoundedVars():
    # same concept as above, but bounded variables
    m = ConcreteModel()
    m.s = Set(initialize=[1, 2])
    m.lbs = Param(m.s, initialize={1: 2, 2: 4})
    m.ubs = Param(m.s, initialize={1: 7, 2: 6})

    def bounds_rule(m, s):
        return (m.lbs[s], m.ubs[s])
    m.a = Var(m.s, bounds=bounds_rule)

    def d_rule(disjunct, flag):
        m = disjunct.model()

        def true_rule(d, s):
            return m.a[s] == 0

        def false_rule(d, s):
            return m.a[s] >= 5
        if flag:
            disjunct.c = Constraint(m.s, rule=true_rule)
        else:
            disjunct.c = Constraint(m.s, rule=false_rule)
    m.disjunct = Disjunct([0, 1], rule=d_rule)
    m.disjunction = Disjunction(expr=[m.disjunct[0], m.disjunct[1]])
    return m
예제 #26
0
파일: models.py 프로젝트: Pyomo/pyomo
def makeTwoTermDisjOnBlock():
    m = ConcreteModel()
    m.b = Block()
    m.a = Var(bounds=(0, 5))

    # On a whim, verify that the decorator notation works
    @m.b.Disjunct([0, 1])
    def disjunct(disjunct, flag):
        m = disjunct.model()
        if flag:
            disjunct.c = Constraint(expr=m.a <= 3)
        else:
            disjunct.c = Constraint(expr=m.a == 0)

    @m.b.Disjunction()
    def disjunction(m):
        return [m.disjunct[0], m.disjunct[1]]

    return m
예제 #27
0
파일: models.py 프로젝트: Pyomo/pyomo
def makeThreeTermIndexedDisj():
    m = ConcreteModel()
    m.s = Set(initialize=[1, 2])
    m.a = Var(m.s, bounds=(2, 7))

    def d_rule(disjunct, flag, s):
        m = disjunct.model()
        if flag == 0:
            disjunct.c = Constraint(expr=m.a[s] == 0)
        elif flag == 1:
            disjunct.c = Constraint(expr=m.a[s] >= 5)
        else:
            disjunct.c = Constraint(expr=inequality(2, m.a[s], 4))
    m.disjunct = Disjunct([0, 1, 2], m.s, rule=d_rule)

    def disj_rule(m, s):
        return [m.disjunct[0, s], m.disjunct[1, s], m.disjunct[2, s]]
    m.disjunction = Disjunction(m.s, rule=disj_rule)
    return m
예제 #28
0
파일: models.py 프로젝트: Pyomo/pyomo
def makeTwoTermDisj_BlockOnDisj():
    m = ConcreteModel()
    m.x = Var(bounds=(0, 1000))
    m.y = Var(bounds=(0, 800))

    def disj_rule(d, flag):
        m = d.model()
        if flag:
            d.b = Block()
            d.b.c = Constraint(expr=m.x == 0)
            d.add_component('b.c', Constraint(expr=m.y >= 9))
            d.b.anotherblock = Block()
            d.b.anotherblock.c = Constraint(expr=m.y >= 11)
            d.bb = Block([1])
            d.bb[1].c = Constraint(expr=m.x == 0)
        else:
            d.c = Constraint(expr=m.x >= 80)
    m.evil = Disjunct([0, 1], rule=disj_rule)
    m.disjunction = Disjunction(expr=[m.evil[0], m.evil[1]])
    return m
예제 #29
0
class ComponentPerformanceBase(object):
    @classmethod
    def _create_model(self, ctype, **kwds):
        self.model = ConcreteModel()
        self.model.x = Var()
        self.model.IDX = Set(initialize=sorted(range(1000000)))
        self.model.del_component('test_component')
        self.model.test_component = \
            ctype(self.model.IDX, **kwds)

    @classmethod
    def setUp(self):
        if self.model is None:
            self._setup()

    @classmethod
    def setUpClass(self):
        self.model = None

    @classmethod
    def tearDownClass(self):
        self.model = None

    def test_0_setup(self):
        # Needed so that the time to set up the model is not included in
        # the subsequent performance tests.  This test is named so that
        # it should appear first in the set of tests run by this test class
        pass

    def test_iteration(self):
        cnt = 0
        for cdata in self.model.component_data_objects(self.model.test_component.type()):
            cnt += 1
        self.assertTrue(cnt > 0)
        if self.model.test_component.type() in (Set, Var):
            self.assertEqual(cnt,
                             len(self.model.test_component) + 1)
        else:
            self.assertEqual(cnt,
                             len(self.model.test_component))
예제 #30
0
파일: models.py 프로젝트: Pyomo/pyomo
def makeDisjunctionsOnIndexedBlock():
    m = ConcreteModel()
    m.s = Set(initialize=[1, 2])
    m.a = Var(m.s, bounds=(0, 70))

    @m.Disjunct(m.s, [0, 1])
    def disjunct1(disjunct, s, flag):
        m = disjunct.model()
        if not flag:
            disjunct.c = Constraint(expr=m.a[s] == 0)
        else:
            disjunct.c = Constraint(expr=m.a[s] >= 7)

    def disjunction1_rule(m, s):
        return [m.disjunct1[s, flag] for flag in [0, 1]]
    m.disjunction1 = Disjunction(m.s, rule=disjunction1_rule)

    m.b = Block([0, 1])
    m.b[0].x = Var(bounds=(-2, 2))

    def disjunct2_rule(disjunct, flag):
        if not flag:
            disjunct.c = Constraint(expr=m.b[0].x <= 0)
        else:
            disjunct.c = Constraint(expr=m.b[0].x >= 0)
    m.b[0].disjunct = Disjunct([0, 1], rule=disjunct2_rule)

    def disjunction(b, i):
        return [b.disjunct[0], b.disjunct[1]]
    m.b[0].disjunction = Disjunction([0], rule=disjunction)

    m.b[1].y = Var(bounds=(-3, 3))
    m.b[1].disjunct0 = Disjunct()
    m.b[1].disjunct0.c = Constraint(expr=m.b[1].y <= 0)
    m.b[1].disjunct1 = Disjunct()
    m.b[1].disjunct1.c = Constraint(expr=m.b[1].y >= 0)
    m.b[1].disjunction = Disjunction(
        expr=[m.b[1].disjunct0, m.b[1].disjunct1])
    return m
예제 #31
0
def define_model(**kwds):

    model = ConcreteModel()

    model.x = Var(INDEX_SET, bounds=(-5,4)) # domain variable
    model.Fx = Var(INDEX_SET) # range variable
    model.p = Param(INDEX_SET, initialize=1.0)

    model.obj = Objective(expr=sum_product(model.Fx), sense=kwds.pop('sense',maximize))

    model.piecewise = Piecewise(INDEX_SET,model.Fx,model.x,
                                  pw_pts=DOMAIN_PTS,
                                  f_rule=F, **kwds)

    #Fix the answer for testing purposes
    model.set_answer_constraint1 = Constraint(expr= model.x[1,0] == -5.0)
    model.set_answer_constraint2 = Constraint(expr= model.x[2,0] == -3.0)
    model.set_answer_constraint3 = Constraint(expr= model.x[3,0] == -2.5)
    model.set_answer_constraint4 = Constraint(expr= model.x[4,0] == -1.5)
    model.set_answer_constraint5 = Constraint(expr= model.x[5,0] == 2.0)
    model.set_answer_constraint6 = Constraint(expr= model.x[6,0] == 3.5)
    model.set_answer_constraint7 = Constraint(expr= model.x[7,0] == 4.0)
    model.set_answer_constraint8 = Constraint(expr= model.x[1,1] == -5.0)
    model.set_answer_constraint9 = Constraint(expr= model.x[2,1] == -3.0)
    model.set_answer_constraint10 = Constraint(expr= model.x[3,1] == -2.5)
    model.set_answer_constraint11 = Constraint(expr= model.x[4,1] == -1.5)
    model.set_answer_constraint12 = Constraint(expr= model.x[5,1] == 2.0)
    model.set_answer_constraint13 = Constraint(expr= model.x[6,1] == 3.5)
    model.set_answer_constraint14 = Constraint(expr= model.x[7,1] == 4.0)    
    
    return model
예제 #32
0
    def test_fix_value(self):
        m = ConcreteModel()
        m.iv = AutoLinkedBooleanVar()
        m.biv = AutoLinkedBinaryVar(m.iv)
        m.iv.associate_binary_var(m.biv)

        m.iv.fix()
        self.assertTrue(m.iv.is_fixed())
        self.assertTrue(m.biv.is_fixed())
        self.assertIsNone(m.iv.value)
        self.assertIsNone(m.biv.value)

        m.iv.fix(True)
        self.assertEqual(m.iv.value, True)
        self.assertEqual(m.biv.value, 1)

        m.iv.fix(False)
        self.assertEqual(m.iv.value, False)
        self.assertEqual(m.biv.value, 0)

        m.iv.fix(None)
        self.assertEqual(m.iv.value, None)
        self.assertEqual(m.biv.value, None)

        m.biv.fix(1)
        self.assertEqual(m.iv.value, True)
        self.assertEqual(m.biv.value, 1)

        with LoggingIntercept() as LOG:
            m.biv.fix(0.5)
        self.assertEqual(
            LOG.getvalue().strip(), "Setting Var 'biv' to a "
            "value `0.5` (float) not in domain Binary.")
        self.assertEqual(m.iv.value, None)
        self.assertEqual(m.biv.value, 0.5)

        with LoggingIntercept() as LOG:
            m.biv.fix(0.55, True)
        self.assertEqual(LOG.getvalue().strip(), "")
        self.assertEqual(m.iv.value, None)
        self.assertEqual(m.biv.value, 0.55)

        m.biv.fix(0)
        self.assertEqual(m.iv.value, False)
        self.assertEqual(m.biv.value, 0)

        eps = AutoLinkedBinaryVar.INTEGER_TOLERANCE / 10

        # Note that fixing to a near-True value will toggle the iv
        with LoggingIntercept() as LOG:
            m.biv.fix(1 - eps)
        self.assertEqual(
            LOG.getvalue().strip(), "Setting Var 'biv' to a "
            "value `%s` (float) not in domain Binary." % (1 - eps))
        self.assertEqual(m.iv.value, True)
        self.assertEqual(m.biv.value, 1 - eps)

        with LoggingIntercept() as LOG:
            m.biv.fix(eps, True)
        self.assertEqual(LOG.getvalue().strip(), "")
        self.assertEqual(m.iv.value, False)
        self.assertEqual(m.biv.value, eps)

        m.iv.fix(True)
        self.assertEqual(m.iv.value, True)
        self.assertEqual(m.biv.value, 1)

        m.iv.fix(False)
        self.assertEqual(m.iv.value, False)
        self.assertEqual(m.biv.value, 0)
예제 #33
0
    def _compute_entity_alone_profits(
            self, quarter: pd.Timestamp) -> Dict[int, float]:
        """
        Profit (or cost) of export, import, peak under balance constraint. No exchange between entities.
        Only one problem gathering all the entities is solved, but no variable is shared among entities.
        :param quarter: current quarter start time.
        :return: A dict entity_id -> entity_alone_profit.
        """

        model = ConcreteModel()

        # Sets
        self._add_sets(model)

        # Variables
        self._add_grid_vars(model)

        model.peak = Var(model.entities,
                         within=NonNegativeReals)  # Entity peak [kW]
        model.J = Var(model.entities, within=Reals)  # Entity profit [EUR]

        def entity_balance_rule(m, e, p):
            # Fix variables depending on the net position. (Note: If position is 0, fix all to zero.)
            if is_zero(self._net_position(e, p, quarter)):
                m.imp_grid[e, p].fix(0)
                m.exp_grid[e, p].fix(0)
                return Constraint.Skip
            elif self._net_position(e, p, quarter) > 0:
                # export position, can fix imports to zero
                m.imp_grid[e, p].fix(0)
            elif self._net_position(e, p, quarter) < 0:
                # import position, can fix exports to zero
                m.exp_grid[e, p].fix(0)

            return m.exp_grid[e, p] - m.imp_grid[e, p] == self._net_position(
                e, p, quarter)

        model.entity_balance = Constraint(model.entities,
                                          model.periods,
                                          rule=entity_balance_rule)

        def entity_peak_rule(m, e):
            """

            """
            lhs = sum(m.imp_grid[e, p]
                      for p in model.periods) / self.n_periods_in_quarter
            rhs = self.entities[e].past_peak + m.peak[e]
            return lhs <= rhs

        model.entity_peak = Constraint(model.entities, rule=entity_peak_rule)

        def entity_profit_rule(m: ConcreteModel, e: int):
            expr = 0

            # Energy
            for p in model.periods:
                expr += m.exp_grid[e, p] * self._sale_price(
                    e, p, quarter) * self.period_duration_in_hours
                expr -= m.imp_grid[e, p] * self._purchase_price(
                    e, p, quarter) * self.period_duration_in_hours

            # Capacity
            expr -= m.peak[e] * self.entities[e].peak_price

            return model.J[e] == expr

        model.entity_profit = Constraint(model.entities,
                                         rule=entity_profit_rule)

        model.obj = Objective(expr=sum(model.J[e] for e in model.entities),
                              sense=maximize)

        self._solve(model, name="entity")

        entity_alone_profits = {e: model.J[e].value for e in model.entities}
        for e in model.entities:
            self.entities[e].past_peak = max(self.entities[e].past_peak,
                                             model.peak[e].value)
            # DEBUG print("Entity %d peak: " % e, self.entities[e].past_peak)

        return entity_alone_profits
예제 #34
0
    def _generate_model(self):
        self.model = ConcreteModel()
        model = self.model
        model._name = self.description

        model.s = Set(initialize=[1,2])

        model.x_unused = Var(within=Integers)
        model.x_unused.stale = False

        model.x_unused_initialy_stale = Var(within=Integers)
        model.x_unused_initialy_stale.stale = True

        model.X_unused = Var(model.s, within=Integers)
        model.X_unused_initialy_stale = Var(model.s, within=Integers)
        for i in model.s:
            model.X_unused[i].stale = False
            model.X_unused_initialy_stale[i].stale = True

        model.x = Var(within=IntegerInterval(bounds=(None,None)))
        model.x.stale = False

        model.x_initialy_stale = Var(within=Integers)
        model.x_initialy_stale.stale = True

        model.X = Var(model.s, within=Integers)
        model.X_initialy_stale = Var(model.s, within=Integers)
        for i in model.s:
            model.X[i].stale = False
            model.X_initialy_stale[i].stale = True

        model.obj = Objective(expr= model.x + \
                                    model.x_initialy_stale + \
                                    sum_product(model.X) + \
                                    sum_product(model.X_initialy_stale))

        model.c = ConstraintList()
        model.c.add( model.x          >= 1 )
        model.c.add( model.x_initialy_stale    >= 1 )
        model.c.add( model.X[1]       >= 0 )
        model.c.add( model.X[2]       >= 1 )
        model.c.add( model.X_initialy_stale[1] >= 0 )
        model.c.add( model.X_initialy_stale[2] >= 1 )

        # Test that stale flags do not get updated
        # on inactive blocks (where "inactive blocks" mean blocks
        # that do NOT follow a path of all active parent blocks
        # up to the top-level model)
        flat_model = model.clone()
        model.b = Block()
        model.B = Block(model.s)
        model.b.b = flat_model.clone()
        model.B[1].b = flat_model.clone()
        model.B[2].b = flat_model.clone()

        model.b.deactivate()
        model.B.deactivate()
        model.b.b.activate()
        model.B[1].b.activate()
        model.B[2].b.deactivate()
        assert model.b.active is False
        assert model.B[1].active is False
        assert model.B[1].active is False
        assert model.b.b.active is True
        assert model.B[1].b.active is True
        assert model.B[2].b.active is False
예제 #35
0
 def _get_block_model(self):
     model = ConcreteModel()
     model.s = Set(initialize=[1, 2])
     b = Block(concrete=True)
     b.s = Set(initialize=[1, 2])
     b.x = Var()
     b.X = Var(model.s)
     model.b1 = b.clone()
     model.b2 = b.clone()
     model.b3 = b.clone()
     model.b4 = b.clone()
     model.B1 = Block(model.s, rule=lambda _, i: b.clone())
     model.B2 = Block(model.s, rule=lambda _, i: b.clone())
     model.B3 = Block(model.s, rule=lambda _, i: b.clone())
     model.B4 = Block(model.s, rule=lambda _, i: b.clone())
     model.FirstStageCost = Expression(expr=0.0)
     model.SecondStageCost = Expression(expr=0.0)
     model.obj = Objective(expr=0.0)
     return model
    def makeModel():
        """
        This is a single-level reformulation of a bilevel model.
        We project out the dual variables to recover the reformulation in 
        the original space.
        """
        m = ConcreteModel()
        m.x = Var(bounds=(0, 2))
        m.y = Var(domain=NonNegativeReals)
        m.lamb = Var([1, 2], domain=NonNegativeReals)
        m.M = Param([1, 2], mutable=True, default=100)
        m.u = Var([1, 2], domain=Binary)

        m.primal1 = Constraint(expr=m.x - 0.01 * m.y <= 1)
        m.dual1 = Constraint(expr=1 - m.lamb[1] - 0.01 * m.lamb[2] == 0)

        @m.Constraint([1, 2])
        def bound_lambdas(m, i):
            return m.lamb[i] <= m.u[i] * m.M[i]

        m.bound_y = Constraint(expr=m.y <= 1000 * (1 - m.u[1]))
        m.dual2 = Constraint(expr=-m.x + 0.01 * m.y + 1 <= (1 - m.u[2]) * 1000)

        return m
    def test_numerical_instability_early_elimination(self):
        # A more subtle numerical problem is that, in infinite precision, a
        # variable might be eliminated early. However, if this goes wrong, the
        # result can be unexpected (including getting no constraints when some
        # are expected.)
        m = ConcreteModel()
        m.x = Var()
        m.x0 = Var()
        m.y = Var()

        # we'll pretend that the 1.123e-9 is noise from previous calculations
        m.cons1 = Constraint(
            expr=0 <= (4.27 + 1.123e-9) * m.x + 13 * m.y - m.x0)
        m.cons2 = Constraint(expr=m.x0 >= 12 * m.y + 4.27 * m.x)

        fme = TransformationFactory('contrib.fourier_motzkin_elimination')

        # doing my own clones because I want assertIs tests
        first = m.clone()
        second = m.clone()
        third = m.clone()

        fme.apply_to(first, vars_to_eliminate=[first.x0], zero_tolerance=1e-10)
        constraints = first._pyomo_contrib_fme_transformation.\
                      projected_constraints
        cons = constraints[1]
        self.assertEqual(cons.lower, 0)
        repn = generate_standard_repn(cons.body)
        self.assertTrue(repn.is_linear())
        self.assertEqual(repn.constant, 0)
        self.assertEqual(len(repn.linear_coefs), 2)  # x is still around
        self.assertIs(repn.linear_vars[0], first.x)
        self.assertAlmostEqual(repn.linear_coefs[0], 1.123e-9)
        self.assertIs(repn.linear_vars[1], first.y)
        self.assertEqual(repn.linear_coefs[1], 1)
        self.assertIsNone(cons.upper)

        # so just to drive home the point, this results in no constraints:
        # (Though also note that that only happens if x0 is the first to be
        # projected out)
        fme.apply_to(second,
                     vars_to_eliminate=[second.x0, second.x],
                     zero_tolerance=1e-10)
        self.assertEqual(len(second._pyomo_contrib_fme_transformation.\
                             projected_constraints), 0)

        # but in this version, we assume that x is already gone...
        fme.apply_to(third,
                     vars_to_eliminate=[third.x0],
                     verbose=True,
                     zero_tolerance=1e-8)
        constraints = third._pyomo_contrib_fme_transformation.\
                      projected_constraints
        cons = constraints[1]
        self.assertEqual(cons.lower, 0)
        self.assertIs(cons.body, third.y)
        self.assertIsNone(cons.upper)

        # and this is exactly the same as the above:
        fme.apply_to(m,
                     vars_to_eliminate=[m.x0, m.x],
                     verbose=True,
                     zero_tolerance=1e-8)
        constraints = m._pyomo_contrib_fme_transformation.projected_constraints
        cons = constraints[1]
        self.assertEqual(cons.lower, 0)
        self.assertIs(cons.body, m.y)
        self.assertIsNone(cons.upper)
예제 #38
0
 def test_outofbounds(self):
     m = ConcreteModel()
     m.x = Var(bounds=(-1, 5), initialize=2)
     with self.assertRaisesRegex(MCPP_Error, '.*Log with negative values in range'):
         mc(log(m.x))
예제 #39
0
#  ___________________________________________________________________________
#
#  Pyomo: Python Optimization Modeling Objects
#  Copyright 2017 National Technology and Engineering Solutions of Sandia, LLC
#  Under the terms of Contract DE-NA0003525 with National Technology and 
#  Engineering Solutions of Sandia, LLC, the U.S. Government retains certain 
#  rights in this software.
#  This software is distributed under the 3-clause BSD License.
#  ___________________________________________________________________________

from pyomo.core import ConcreteModel, Var, Objective, Constraint, Integers

model = ConcreteModel()

model.x = Var(bounds=(1,None), within=Integers)
model.y = Var(bounds=(1,None), within=Integers)

model.o = Objective(expr=model.x-model.x)

model.c = Constraint(expr=model.x+model.y >= 3)
예제 #40
0
 def get_mock_model(self):
     model = ConcreteModel()
     model.x = Var(within=Binary)
     model.con = Constraint(expr=model.x >= 1)
     model.obj = Objective(expr=model.x)
     return model
예제 #41
0
def get_model(flag, fixprim, fixdual):
    model = ConcreteModel()

    model.obj = Param(default=20)

    model.n = Param(default=7)
    model.m = Param(default=7)

    model.N = RangeSet(1, model.n)
    model.M = RangeSet(1, model.m)

    def c_rule(model, j):
        return 5 if j < 5 else 9.0 / 2

    model.c = Param(model.N)

    def b_rule(model, i):
        if i == 4:
            i = 5
        elif i == 5:
            i = 4
        return 5 if i < 5 else 7.0 / 2

    model.b = Param(model.M)

    def A_rule(model, i, j):
        if i == 4:
            i = 5
        elif i == 5:
            i = 4
        return 2 if i == j else 1

    model.A = Param(model.M, model.N)

    model.x = Var(model.N, within=NonNegativeReals)
    model.y = Var(model.M, within=NonNegativeReals)
    model.xx = Var([1, 2], model.N, within=NonNegativeReals)
    model.yy = Var([1, 2], model.M, within=NonNegativeReals)

    if flag:
        model.ydiff = Objective(expr=model.yy[2, fixdual] -
                                model.yy[1, fixdual])

        def yext_rule(model, k):
            return sum(model.b[i] * model.yy[k, i]
                       for i in model.M) == model.obj

        model.yext = Constraint([1, 2])

        def dualcons_rule(model, k, j):
            return sum(model.A[i, j] * model.yy[k, i]
                       for i in model.N) <= model.c[j]

        model.dualcons = Constraint([1, 2], model.N)
    else:
        model.xdiff = Objective(expr=model.xx[2, fixprim] -
                                model.xx[1, fixprim])

        def xext_rule(model, k):
            return sum(model.c[j] * model.xx[k, j]
                       for j in model.N) == model.obj

        model.xext = Constraint([1, 2])

        def primcons_rule(model, k, i):
            return sum(model.A[i, j] * model.xx[k, j]
                       for j in model.M) >= model.b[i]

        model.primcons = Constraint([1, 2], model.M)

    model.create()
    return model
예제 #42
0
 def test_empty_model(self):
     """Test with an empty model."""
     empty_model = ConcreteModel()
     model_size = build_model_size_report(empty_model)
     for obj in model_size.activated.values():
         self.assertEqual(obj, 0)
예제 #43
0
def define_model(**kwds):

    model = ConcreteModel()

    model.x1 = Var(bounds=(-5, 4))  # domain variable
    model.x2 = Var(bounds=(-5, 4))  # domain variable
    model.x3 = Var(bounds=(-5, 4))  # domain variable
    model.x4 = Var(bounds=(-5, 4))  # domain variable
    model.x5 = Var(bounds=(-5, 4))  # domain variable
    model.x6 = Var(bounds=(-5, 4))  # domain variable
    model.x7 = Var(bounds=(-5, 4))  # domain variable

    model.Fx1 = Var()  # range variable
    model.Fx2 = Var()  # range variable
    model.Fx3 = Var()  # range variable
    model.Fx4 = Var()  # range variable
    model.Fx5 = Var()  # range variable
    model.Fx6 = Var()  # range variable
    model.Fx7 = Var()  # range variable

    model.obj = Objective(expr=model.Fx1 + model.Fx2 + model.Fx3 + model.Fx4 +
                          model.Fx5 + model.Fx6 + model.Fx7,
                          sense=kwds.pop('sense', maximize))

    model.piecewise1 = Piecewise(model.Fx1,
                                 model.x1,
                                 pw_pts=DOMAIN_PTS,
                                 f_rule=F,
                                 **kwds)
    model.piecewise2 = Piecewise(model.Fx2,
                                 model.x2,
                                 pw_pts=DOMAIN_PTS,
                                 f_rule=F,
                                 **kwds)
    model.piecewise3 = Piecewise(model.Fx3,
                                 model.x3,
                                 pw_pts=DOMAIN_PTS,
                                 f_rule=F,
                                 **kwds)
    model.piecewise4 = Piecewise(model.Fx4,
                                 model.x4,
                                 pw_pts=DOMAIN_PTS,
                                 f_rule=F,
                                 **kwds)
    model.piecewise5 = Piecewise(model.Fx5,
                                 model.x5,
                                 pw_pts=DOMAIN_PTS,
                                 f_rule=F,
                                 **kwds)
    model.piecewise6 = Piecewise(model.Fx6,
                                 model.x6,
                                 pw_pts=DOMAIN_PTS,
                                 f_rule=F,
                                 **kwds)
    model.piecewise7 = Piecewise(model.Fx7,
                                 model.x7,
                                 pw_pts=DOMAIN_PTS,
                                 f_rule=F,
                                 **kwds)

    #Fix the answer for testing purposes
    model.set_answer_constraint1 = Constraint(expr=model.x1 == -5.0)
    model.set_answer_constraint2 = Constraint(expr=model.x2 == -3.0)
    model.set_answer_constraint3 = Constraint(expr=model.x3 == -2.5)
    model.set_answer_constraint4 = Constraint(expr=model.x4 == -1.5)
    model.set_answer_constraint5 = Constraint(expr=model.x5 == 2.0)
    model.set_answer_constraint6 = Constraint(expr=model.x6 == 3.5)
    model.set_answer_constraint7 = Constraint(expr=model.x7 == 4.0)

    return model
예제 #44
0
    def _compute_community_repartition(
            self, quarter: pd.Timestamp,
            entity_alone_profits: Dict[int, float]) -> Dict[int, pd.DataFrame]:
        """
        Repartition of profit for a quarter.
        The model solves a first problem where the pareto superior condition ensures the profit in the community is at least as good as the profit alone.
        Then a second phase is run to attemp to equalize the profits over entities (max margin approach).
        :param quarter: current quarter start time.
        :param entity_alone_profits: output of _compute_entity_alone_profits.
        :return: A dict entity_id -> dataframe with average results over quarter.
        """
        model = ConcreteModel()

        # Sets
        self._add_sets(model)

        # Variables
        # Primal
        self._add_grid_vars(model)
        model.exp_com = Var(model.entities,
                            model.periods,
                            within=NonNegativeReals
                            )  # Power sent to the community over period [kW]
        model.imp_com = Var(
            model.entities, model.periods, within=NonNegativeReals
        )  # Energy imported from the community over period [kW]
        model.peak_MU = Var(
            model.entities,
            within=NonNegativeReals)  # Entity peak, community mode [kW]

        # Profit repartition threshold
        model.alpha = Var(within=NonNegativeReals)

        # Dual
        model.price_com = Var(model.entities, model.periods, within=Reals)
        model.mu = Var(model.periods, within=Reals)
        model.phi_peak = Var(within=NonNegativeReals)

        # Profit
        model.J_MU = Var(model.entities, within=Reals)

        # Expressions
        def profit_expression_rule(m, e):
            expr = 0

            # Energy
            for p in model.periods:
                expr += m.exp_grid[e, p] * self._sale_price(
                    e, p, quarter) * self.period_duration_in_hours
                expr -= m.imp_grid[e, p] * self._purchase_price(
                    e, p, quarter) * self.period_duration_in_hours

                expr += m.exp_com[e, p] * m.price_com[
                    e, p] * self.period_duration_in_hours
                expr -= m.imp_com[e, p] * m.price_com[
                    e, p] * self.period_duration_in_hours

                # Storage
                if self.entities[e].storage is not None:
                    s: Storage = self.entities[e].storage
                    expr += m.exp_com[
                        e,
                        p] / s.discharge_efficiency * s.usage_fee * self.period_duration_in_hours
                    expr += m.imp_com[
                        e,
                        p] * s.charge_efficiency * s.usage_fee * self.period_duration_in_hours

            # Capacity
            expr -= m.peak_MU[e] * self.community_peak_price

            return m.J_MU[e] == expr

        model.profit_MU_def = Constraint(model.entities,
                                         rule=profit_expression_rule)

        # Constraints
        # Primal

        def entity_balance_rule(m, e, p):
            # Fix variables depending on the net position. (Note: If position is 0, fix all to zero.)
            if is_zero(self._net_position(e, p, quarter)):
                m.imp_grid[e, p].fix(0)
                m.imp_com[e, p].fix(0)
                m.exp_grid[e, p].fix(0)
                m.exp_com[e, p].fix(0)
                return Constraint.Skip
            elif self._net_position(e, p, quarter) > 0:
                # export position, can fix imports to zero
                m.imp_grid[e, p].fix(0)
                m.imp_com[e, p].fix(0)
            elif self._net_position(e, p, quarter) < 0:
                # import position, can fix exports to zero
                m.exp_grid[e, p].fix(0)
                m.exp_com[e, p].fix(0)

            return m.exp_grid[e, p] - m.imp_grid[e, p] + m.exp_com[
                e, p] - m.imp_com[e, p] == self._net_position(e, p, quarter)

        model.entity_balance = Constraint(model.entities,
                                          model.periods,
                                          rule=entity_balance_rule)

        def com_balance_rule(m, p):
            return sum(m.exp_com[e, p] - m.imp_com[e, p]
                       for e in model.entities) == 0

        model.com_balance = Constraint(model.periods, rule=com_balance_rule)

        def global_peak_rule(m):
            """

            :param m: Pyomo model
            :param p: time period
            :return: constraint on the peak of the community
            """
            lhs = sum(m.imp_grid[e, p] for (e, p) in model.entities *
                      model.periods) / self.n_periods_in_quarter
            rhs = self.community_past_peak + sum(m.peak_MU[e]
                                                 for e in model.entities)
            return lhs <= rhs

        model.global_peak = Constraint(rule=global_peak_rule)

        # Dual
        def dual_exp_grid_rule(m, e, p):
            """
            Dual constraint for the export to grid variable

            :param m: Pyomo model
            :param e: entity
            :param p: time period
            :return: inequality constraint
            """
            return m.price_com[e, p] >= self._sale_price(e, p, quarter)

        model.dual_exp_grid = Constraint(model.entities,
                                         model.periods,
                                         rule=dual_exp_grid_rule)

        def dual_imp_grid_rule(m, e, p):
            """
            Dual constraint for the import from grid variable

            :param m: Pyomo model
            :param e: entity
            :param p: time period
            :return: inequality constraint
            """
            expr = -m.price_com[e,
                                p] + m.phi_peak / self.period_duration_in_hours
            return expr >= -self._purchase_price(e, p, quarter)

        model.dual_imp_grid = Constraint(model.entities,
                                         model.periods,
                                         rule=dual_imp_grid_rule)

        def dual_peak_rule(m):
            """
            Dual constraint for the entity peak variables

            :param m: Pyomo model
            :param e: entity
            :return: inequality constraint
            """
            return -m.phi_peak >= -self.community_peak_price

        model.dual_peak = Constraint(rule=dual_peak_rule)

        def dual_exp_com_rule(m, e, p):
            if self._net_position(e, p, quarter) > 0:
                # export position
                return m.price_com[e, p] - m.mu[p] == -self.community_tariff
            else:
                return m.price_com[e, p] - m.mu[p] >= -self.community_tariff

        model.dual_exp_com = Constraint(model.entities,
                                        model.periods,
                                        rule=dual_exp_com_rule)

        def dual_imp_com_rule(m, e, p):
            if self._net_position(e, p, quarter) < 0:
                # import position
                return -m.price_com[e, p] + m.mu[p] == -self.community_tariff
            else:
                return -m.price_com[e, p] + m.mu[p] >= -self.community_tariff

        model.dual_imp_com = Constraint(model.entities,
                                        model.periods,
                                        rule=dual_imp_com_rule)

        # Strong duality
        def strong_duality_rule(m):
            """
            Strong duality constraint.

            :param m: Pyomo model
            :return: Equality constraint
            """
            dual_obj = 0

            for p in model.periods:
                for e in model.entities:
                    dual_obj += m.price_com[e, p] * self._net_position(
                        e, p, quarter) * self.period_duration_in_hours

            dual_obj += self.community_past_peak * model.phi_peak

            primal_obj = 0

            for e in model.entities:
                for p in model.periods:
                    # Energy
                    primal_obj += m.exp_grid[e, p] * self._sale_price(
                        e, p, quarter) * self.period_duration_in_hours
                    primal_obj -= m.imp_grid[e, p] * self._purchase_price(
                        e, p, quarter) * self.period_duration_in_hours

                    primal_obj += (
                        m.exp_com[e, p] - m.imp_com[e, p]
                    ) * self.community_tariff * self.period_duration_in_hours

                # Capacity
                primal_obj -= m.peak_MU[e] * DEFAULT_PEAK_PRICE

                if self.entities[e].storage is not None:
                    s: Storage = self.entities[e].storage
                    primal_obj += m.exp_com[
                        e,
                        p] / s.discharge_efficiency * s.usage_fee * self.period_duration_in_hours
                    primal_obj += m.imp_com[
                        e,
                        p] * s.charge_efficiency * s.usage_fee * self.period_duration_in_hours

            return dual_obj == primal_obj

        model.strong_duality = Constraint(rule=strong_duality_rule)

        # Upper level

        def pareto_superior_rule(m, e):
            # TODO return (m.J_MU[e] - entity_alone_profits[e]) / abs(entity_alone_profits[e]) >= m.alpha
            return m.J_MU[e] >= entity_alone_profits[e]

        def pareto_superior_rule_phase_2(m, e):
            if not is_zero(entity_alone_profits[e]):
                return (m.J_MU[e] - entity_alone_profits[e]) / abs(
                    entity_alone_profits[e]) >= m.alpha
            else:
                return m.J_MU[e] >= entity_alone_profits[e]

        model.pareto_superior_cdt = Constraint(model.entities,
                                               rule=pareto_superior_rule)

        model.objective = Objective(expr=sum(
            (model.J_MU[e]) for e in model.entities),
                                    sense=maximize)

        self._solve(model)

        # PHASE 2 -> max margin profit repartition
        def community_minimum_profit_rule(m):
            return sum((model.J_MU[e])
                       for e in model.entities) >= model.objective.expr

        model.community_minimum_profit = Constraint(
            rule=community_minimum_profit_rule)

        model.pareto_superior_cdt.deactivate()
        model.pareto_superior_cdt_phase2 = Constraint(
            model.entities, rule=pareto_superior_rule_phase_2)

        model.objective.deactivate()
        model.objective_phase2 = Objective(expr=model.alpha, sense=maximize)

        self._solve(model)
        print("ALPHA = %.2f %%" % (model.alpha.value * 100))

        # Average results over quarter
        quarter_results = {e: None for e in self.entities}
        tmp_results = {e: [] for e in model.entities}
        for p in model.periods:
            for e in model.entities:
                tmp_results[e].append([
                    quarter + timedelta(minutes=p - 1),
                    model.price_com[e, p].value, model.exp_grid[e, p].value,
                    model.imp_grid[e, p].value, model.exp_com[e, p].value,
                    model.imp_com[e, p].value
                ])
        detailed_results = {
            e: pd.DataFrame(v,
                            columns=[
                                "DateTime", "price_com", "exp_grid",
                                "imp_grid", "exp_com", "imp_com"
                            ])
            for (e, v) in tmp_results.items()
        }

        for e in self.entities:
            quarter_results[e] = detailed_results[e].mean()
            num = (detailed_results[e]["exp_com"] -
                   detailed_results[e]["imp_com"]
                   ) * detailed_results[e]["price_com"]
            num = num.sum()
            den = (quarter_results[e]["exp_com"] -
                   quarter_results[e]["imp_com"])
            if not (is_zero(den)):
                quarter_results[e][
                    "price_com"] = num / den / self.n_periods_in_quarter

            quarter_results[e] = quarter_results[e].round(decimals=5)

        # Update the past_peak of the community
        self.community_past_peak = max(
            self.community_past_peak,
            sum(model.peak_MU[e].value for e in model.entities))
        # print("com peak: ", self.community_past_peak)

        # Store entitiy profits for verification
        for e in model.entities:
            self.comparison_df[e].append(
                [quarter, entity_alone_profits[e], model.J_MU[e].value])

        return quarter_results
예제 #45
0
def run_pyomo(options=Options(), parser=None):
    data = Options(options=options)

    if options.model.filename == '':
        parser.print_help()
        return Container()

    try:
        pyomo.scripting.util.setup_environment(data)

        pyomo.scripting.util.apply_preprocessing(data, parser=parser)
    except:
        # TBD: I should be able to call this function in the case of
        #      an exception to perform cleanup. However, as it stands
        #      calling finalize with its default keyword value for
        #      model(=None) results in an a different error related to
        #      task port values.  Not sure how to interpret that.
        pyomo.scripting.util.finalize(data,
                                      model=ConcreteModel(),
                                      instance=None,
                                      results=None)
        raise
    else:
        if data.error:
            # TBD: I should be able to call this function in the case of
            #      an exception to perform cleanup. However, as it stands
            #      calling finalize with its default keyword value for
            #      model(=None) results in an a different error related to
            #      task port values.  Not sure how to interpret that.
            pyomo.scripting.util.finalize(data,
                                          model=ConcreteModel(),
                                          instance=None,
                                          results=None)
            return Container()  #pragma:nocover

    try:
        model_data = pyomo.scripting.util.create_model(data)
    except:
        # TBD: I should be able to call this function in the case of
        #      an exception to perform cleanup. However, as it stands
        #      calling finalize with its default keyword value for
        #      model(=None) results in an a different error related to
        #      task port values.  Not sure how to interpret that.
        pyomo.scripting.util.finalize(data,
                                      model=ConcreteModel(),
                                      instance=None,
                                      results=None)
        raise
    else:
        if (((not options.runtime.logging == 'debug') and \
             options.model.save_file) or \
            options.runtime.only_instance):
            pyomo.scripting.util.finalize(data,
                                          model=model_data.model,
                                          instance=model_data.instance,
                                          results=None)
            return Container(instance=model_data.instance)

    try:
        opt_data = pyomo.scripting.util.apply_optimizer(
            data, instance=model_data.instance)

        pyomo.scripting.util.process_results(data,
                                             instance=model_data.instance,
                                             results=opt_data.results,
                                             opt=opt_data.opt)

        pyomo.scripting.util.apply_postprocessing(data,
                                                  instance=model_data.instance,
                                                  results=opt_data.results)
    except:
        # TBD: I should be able to call this function in the case of
        #      an exception to perform cleanup. However, as it stands
        #      calling finalize with its default keyword value for
        #      model(=None) results in an a different error related to
        #      task port values.  Not sure how to interpret that.
        pyomo.scripting.util.finalize(data,
                                      model=ConcreteModel(),
                                      instance=None,
                                      results=None)
        raise
    else:
        pyomo.scripting.util.finalize(data,
                                      model=model_data.model,
                                      instance=model_data.instance,
                                      results=opt_data.results)

        return Container(options=options,
                         instance=model_data.instance,
                         results=opt_data.results,
                         local=opt_data.local)
예제 #46
0
def define_model(**kwds):

    model = ConcreteModel()

    model.x = Var(INDEX_SET, bounds=(0, 6))  # domain variable
    model.Fx = Var(INDEX_SET)  # range variable
    model.p = Param(INDEX_SET, initialize=1.0, mutable=True)

    model.obj = Objective(expr=sum_product(model.Fx),
                          sense=kwds.pop('sense', maximize))

    model.piecewise = Piecewise(INDEX_SET,
                                model.Fx,
                                model.x,
                                pw_pts=DOMAIN_PTS,
                                f_rule=F,
                                **kwds)

    #Fix the answer for testing purposes
    model.set_answer_constraint1 = Constraint(expr=model.x[1] == 0.0)
    model.set_answer_constraint2 = Constraint(expr=model.x[2] == 3.0)
    model.set_answer_constraint3 = Constraint(expr=model.x[3] == 5.5)
    model.set_answer_constraint4 = Constraint(expr=model.x[4] == 6.0)

    return model
예제 #47
0
파일: constant1b.py 프로젝트: vova292/pyomo
#  ___________________________________________________________________________
#
#  Pyomo: Python Optimization Modeling Objects
#  Copyright 2017 National Technology and Engineering Solutions of Sandia, LLC
#  Under the terms of Contract DE-NA0003525 with National Technology and 
#  Engineering Solutions of Sandia, LLC, the U.S. Government retains certain 
#  rights in this software.
#  This software is distributed under the 3-clause BSD License.
#  ___________________________________________________________________________

from pyomo.core import ConcreteModel, Var, Objective, Constraint, maximize

model = ConcreteModel()

model.x = Var(bounds=(1,None))
model.y = Var(bounds=(1,None))

model.o = Objective(expr=model.x-model.x, sense=maximize)

model.c = Constraint(expr=model.x+model.y >= 3)
예제 #48
0
    def test_synchronize_value(self):
        m = ConcreteModel()
        m.iv = AutoLinkedBooleanVar()
        m.biv = AutoLinkedBinaryVar(m.iv)
        m.iv.associate_binary_var(m.biv)

        self.assertIsNone(m.iv.value)
        self.assertIsNone(m.biv.value)

        # Note: test the following twice to exercise the "no update"
        # situation, and to ensure no infinite loops

        m.iv = True
        self.assertEqual(m.iv.value, True)
        self.assertEqual(m.biv.value, 1)
        m.iv = True
        self.assertEqual(m.iv.value, True)
        self.assertEqual(m.biv.value, 1)

        m.iv = False
        self.assertEqual(m.iv.value, False)
        self.assertEqual(m.biv.value, 0)
        m.iv = False
        self.assertEqual(m.iv.value, False)
        self.assertEqual(m.biv.value, 0)

        m.iv = None
        self.assertEqual(m.iv.value, None)
        self.assertEqual(m.biv.value, None)
        m.iv = None
        self.assertEqual(m.iv.value, None)
        self.assertEqual(m.biv.value, None)

        m.biv = 1
        self.assertEqual(m.iv.value, True)
        self.assertEqual(m.biv.value, 1)
        m.biv = 1
        self.assertEqual(m.iv.value, True)
        self.assertEqual(m.biv.value, 1)

        eps = AutoLinkedBinaryVar.INTEGER_TOLERANCE / 10

        m.biv = None
        self.assertEqual(m.iv.value, None)
        self.assertEqual(m.biv.value, None)
        m.biv = None
        self.assertEqual(m.iv.value, None)
        self.assertEqual(m.biv.value, None)

        m.biv.value = 1 - eps
        self.assertEqual(m.iv.value, True)
        self.assertEqual(m.biv.value, 1 - eps)
        m.biv.value = 1 - eps
        self.assertEqual(m.iv.value, True)
        self.assertEqual(m.biv.value, 1 - eps)

        m.biv.value = eps
        self.assertEqual(m.iv.value, False)
        self.assertEqual(m.biv.value, eps)
        m.biv.value = eps
        self.assertEqual(m.iv.value, False)
        self.assertEqual(m.biv.value, eps)

        m.biv.value = 0.5
        self.assertEqual(m.iv.value, None)
        self.assertEqual(m.biv.value, 0.5)
        m.biv.value = 0.5
        self.assertEqual(m.iv.value, None)
        self.assertEqual(m.biv.value, 0.5)
    def test_model_with_unrelated_nonlinear_expressions(self):
        m = ConcreteModel()
        m.x = Var([1, 2, 3], bounds=(0, 3))
        m.y = Var()
        m.z = Var()

        @m.Constraint([1, 2])
        def cons(m, i):
            return m.x[i] <= m.y**i

        m.cons2 = Constraint(expr=m.x[1] >= m.y)
        m.cons3 = Constraint(expr=m.x[2] >= m.z - 3)
        # This is vacuous, but I just want something that's not quadratic
        m.cons4 = Constraint(expr=m.x[3] <= log(m.y + 1))

        fme = TransformationFactory('contrib.fourier_motzkin_elimination')
        fme.apply_to(m,
                     vars_to_eliminate=m.x,
                     constraint_filtering_callback=None)
        constraints = m._pyomo_contrib_fme_transformation.projected_constraints

        # 0 <= y <= 3
        cons = constraints[5]
        self.assertEqual(value(cons.lower), 0)
        self.assertIs(cons.body, m.y)
        cons = constraints[6]
        self.assertEqual(value(cons.lower), -3)
        body = generate_standard_repn(cons.body)
        self.assertTrue(body.is_linear())
        self.assertEqual(len(body.linear_vars), 1)
        self.assertIs(body.linear_vars[0], m.y)
        self.assertEqual(body.linear_coefs[0], -1)

        # z <= y**2 + 3
        cons = constraints[2]
        self.assertEqual(value(cons.lower), -3)
        body = generate_standard_repn(cons.body)
        self.assertTrue(body.is_quadratic())
        self.assertEqual(len(body.linear_vars), 1)
        self.assertIs(body.linear_vars[0], m.z)
        self.assertEqual(body.linear_coefs[0], -1)
        self.assertEqual(len(body.quadratic_vars), 1)
        self.assertEqual(body.quadratic_coefs[0], 1)
        self.assertIs(body.quadratic_vars[0][0], m.y)
        self.assertIs(body.quadratic_vars[0][1], m.y)

        # z <= 6
        cons = constraints[4]
        self.assertEqual(cons.lower, -6)
        body = generate_standard_repn(cons.body)
        self.assertTrue(body.is_linear())
        self.assertEqual(len(body.linear_vars), 1)
        self.assertEqual(body.linear_coefs[0], -1)
        self.assertIs(body.linear_vars[0], m.z)

        # 0 <= ln(y+ 1)
        cons = constraints[1]
        self.assertEqual(value(cons.lower), 0)
        body = generate_standard_repn(cons.body)
        self.assertTrue(body.is_nonlinear())
        self.assertFalse(body.is_quadratic())
        self.assertEqual(len(body.linear_vars), 0)
        self.assertEqual(body.nonlinear_expr.name, 'log')
        self.assertEqual(len(body.nonlinear_expr.args[0].args), 2)
        self.assertIs(body.nonlinear_expr.args[0].args[0], m.y)
        self.assertEqual(body.nonlinear_expr.args[0].args[1], 1)

        # 0 <= y**2
        cons = constraints[3]
        self.assertEqual(value(cons.lower), 0)
        body = generate_standard_repn(cons.body)
        self.assertTrue(body.is_quadratic())
        self.assertEqual(len(body.quadratic_vars), 1)
        self.assertEqual(body.quadratic_coefs[0], 1)
        self.assertIs(body.quadratic_vars[0][0], m.y)
        self.assertIs(body.quadratic_vars[0][1], m.y)

        # check constraints valid for a selection of points (this is nonconvex,
        # but anyway...)
        pts = [  #(sqrt(3), 6), Not numerically stable enough for this test
            (1, 4), (3, 6), (3, 0), (0, 0), (2, 6)
        ]
        for pt in pts:
            m.y.fix(pt[0])
            m.z.fix(pt[1])
            for i in constraints:
                self.assertLessEqual(value(constraints[i].lower),
                                     value(constraints[i].body))
        m.y.fixed = False
        m.z.fixed = False

        # check post process these are non-convex, so I don't want to deal with
        # it... (and this is a good test that I *don't* deal with it.)
        constraints[2].deactivate()
        constraints[3].deactivate()
        constraints[1].deactivate()
        # NOTE also that some of the suproblems in this test are unbounded: We
        # need to keep those constraints.
        fme.post_process_fme_constraints(m, SolverFactory('glpk'))
        # we needed all the constraints, so we kept them all
        self.assertEqual(len(constraints), 6)

        # last check that if someone activates something on the model in
        # between, we just use it. (I struggle to imagine why you would do this
        # because why withold the information *during* FME, but if there's some
        # reason, we may as well use all the information we've got.)
        m.some_new_cons = Constraint(expr=m.y <= 2)
        fme.post_process_fme_constraints(m, SolverFactory('glpk'))
        # now we should have lost one constraint
        self.assertEqual(len(constraints), 5)
        # and it should be the y <= 3 one...
        self.assertIsNone(dict(constraints).get(6))
예제 #50
0
    def test_cast_to_binary(self):
        m = ConcreteModel()
        m.iv = AutoLinkedBooleanVar()
        m.biv = AutoLinkedBinaryVar(m.iv)
        m.iv.associate_binary_var(m.biv)

        m.biv = 1

        deprecation_msg = (
            "Implicit conversion of the Boolean indicator_var 'iv'")

        out = StringIO()
        with LoggingIntercept(out):
            self.assertEqual(m.iv.lb, 0)
        self.assertIn(deprecation_msg, out.getvalue())

        out = StringIO()
        with LoggingIntercept(out):
            self.assertEqual(m.iv.ub, 1)
        self.assertIn(deprecation_msg, out.getvalue())

        out = StringIO()
        with LoggingIntercept(out):
            self.assertEqual(m.iv.bounds, (0, 1))
        self.assertIn(deprecation_msg, out.getvalue())

        out = StringIO()
        with LoggingIntercept(out):
            m.iv.lb = 1
        self.assertIn(deprecation_msg, out.getvalue())

        out = StringIO()
        with LoggingIntercept(out):
            m.iv.ub = 1
        self.assertIn(deprecation_msg, out.getvalue())

        out = StringIO()
        with LoggingIntercept(out):
            m.iv.bounds = (1, 1)
        self.assertIn(deprecation_msg, out.getvalue())

        out = StringIO()
        with LoggingIntercept(out):
            m.iv.setlb(1)
            self.assertEqual(m.biv.lb, 1)
            m.biv.setlb(0)
        self.assertIn(deprecation_msg, out.getvalue())

        out = StringIO()
        with LoggingIntercept(out):
            m.iv.setub(0)
            self.assertEqual(m.biv.ub, 0)
            m.biv.setub(1)
        self.assertIn(deprecation_msg, out.getvalue())

        out = StringIO()
        with LoggingIntercept(out):
            self.assertIs(abs(m.iv).args[0], m.biv)
        self.assertIn(deprecation_msg, out.getvalue())

        out = StringIO()
        with LoggingIntercept(out):
            with self.assertRaisesRegex(
                    PyomoException, r"Cannot convert non-constant Pyomo "
                    r"numeric value \(biv\) to bool"):
                bool(m.iv)
        self.assertIn(deprecation_msg, out.getvalue())

        out = StringIO()
        with LoggingIntercept(out):
            with self.assertRaisesRegex(
                    TypeError, r"Implicit conversion of Pyomo numeric "
                    r"value \(biv\) to float"):
                float(m.iv)
        self.assertIn(deprecation_msg, out.getvalue())

        out = StringIO()
        with LoggingIntercept(out):
            with self.assertRaisesRegex(
                    TypeError, r"Implicit conversion of Pyomo numeric "
                    r"value \(biv\) to int"):
                int(m.iv)
        self.assertIn(deprecation_msg, out.getvalue())

        out = StringIO()
        with LoggingIntercept(out):
            self.assertIs((-m.iv).args[1], m.biv)
        self.assertIn(deprecation_msg, out.getvalue())

        out = StringIO()
        with LoggingIntercept(out):
            self.assertIs(+m.iv, m.biv)
        self.assertIn(deprecation_msg, out.getvalue())

        out = StringIO()
        with LoggingIntercept(out):
            self.assertTrue(m.iv.has_lb())
        self.assertIn(deprecation_msg, out.getvalue())

        out = StringIO()
        with LoggingIntercept(out):
            self.assertTrue(m.iv.has_ub())
        self.assertIn(deprecation_msg, out.getvalue())

        out = StringIO()
        with LoggingIntercept(out):
            self.assertTrue(m.iv.is_binary())
        self.assertIn(deprecation_msg, out.getvalue())

        out = StringIO()
        with LoggingIntercept(out):
            self.assertFalse(m.iv.is_continuous())
        self.assertIn(deprecation_msg, out.getvalue())

        out = StringIO()
        with LoggingIntercept(out):
            self.assertTrue(m.iv.is_integer())
        self.assertIn(deprecation_msg, out.getvalue())

        out = StringIO()
        with LoggingIntercept(out):
            self.assertEqual(m.iv.polynomial_degree(), 1)
        self.assertIn(deprecation_msg, out.getvalue())

        out = StringIO()
        with LoggingIntercept(out):
            self.assertIs((m.iv == 0).args[0], m.biv)
        self.assertIn(deprecation_msg, out.getvalue())

        out = StringIO()
        with LoggingIntercept(out):
            self.assertIs((m.iv <= 0).args[0], m.biv)
        self.assertIn(deprecation_msg, out.getvalue())

        out = StringIO()
        with LoggingIntercept(out):
            self.assertIs((m.iv >= 0).args[1], m.biv)
        self.assertIn(deprecation_msg, out.getvalue())

        out = StringIO()
        with LoggingIntercept(out):
            self.assertIs((m.iv < 0).args[0], m.biv)
        self.assertIn(deprecation_msg, out.getvalue())

        out = StringIO()
        with LoggingIntercept(out):
            self.assertIs((m.iv > 0).args[1], m.biv)
        self.assertIn(deprecation_msg, out.getvalue())

        out = StringIO()
        with LoggingIntercept(out):
            self.assertIs((m.iv + 1).args[0], m.biv)
        self.assertIn(deprecation_msg, out.getvalue())

        out = StringIO()
        with LoggingIntercept(out):
            self.assertIs((m.iv - 1).args[0], m.biv)
        self.assertIn(deprecation_msg, out.getvalue())

        out = StringIO()
        with LoggingIntercept(out):
            self.assertIs((m.iv * 2).args[1], m.biv)
        self.assertIn(deprecation_msg, out.getvalue())

        out = StringIO()
        with LoggingIntercept(out):
            self.assertIs((m.iv / 2).args[1], m.biv)
        self.assertIn(deprecation_msg, out.getvalue())

        out = StringIO()
        with LoggingIntercept(out):
            self.assertIs((m.iv**2).args[0], m.biv)
        self.assertIn(deprecation_msg, out.getvalue())

        out = StringIO()
        with LoggingIntercept(out):
            self.assertIs((1 + m.iv).args[1], m.biv)
        self.assertIn(deprecation_msg, out.getvalue())

        out = StringIO()
        with LoggingIntercept(out):
            self.assertIs((1 - m.iv).args[1].args[1], m.biv)
        self.assertIn(deprecation_msg, out.getvalue())

        out = StringIO()
        with LoggingIntercept(out):
            self.assertIs((2 * m.iv).args[1], m.biv)
        self.assertIn(deprecation_msg, out.getvalue())

        out = StringIO()
        with LoggingIntercept(out):
            self.assertIs((2 / m.iv).args[1], m.biv)
        self.assertIn(deprecation_msg, out.getvalue())

        out = StringIO()
        with LoggingIntercept(out):
            self.assertIs((2**m.iv).args[1], m.biv)
        self.assertIn(deprecation_msg, out.getvalue())

        out = StringIO()
        with LoggingIntercept(out):
            a = m.iv
            a += 1
            self.assertIs(a.args[0], m.biv)
        self.assertIn(deprecation_msg, out.getvalue())

        out = StringIO()
        with LoggingIntercept(out):
            a = m.iv
            a -= 1
            self.assertIs(a.args[0], m.biv)
        self.assertIn(deprecation_msg, out.getvalue())

        out = StringIO()
        with LoggingIntercept(out):
            a = m.iv
            a *= 2
            self.assertIs(a.args[1], m.biv)
        self.assertIn(deprecation_msg, out.getvalue())

        out = StringIO()
        with LoggingIntercept(out):
            a = m.iv
            a /= 2
            self.assertIs(a.args[1], m.biv)
        self.assertIn(deprecation_msg, out.getvalue())

        out = StringIO()
        with LoggingIntercept(out):
            a = m.iv
            a **= 2
            self.assertIs(a.args[0], m.biv)
        self.assertIn(deprecation_msg, out.getvalue())
예제 #51
0
def device_scheduler(
    device_constraints: List[DataFrame],
    ems_constraints: DataFrame,
    commitment_quantities: List[Series],
    commitment_downwards_deviation_price: Union[List[Series], List[float]],
    commitment_upwards_deviation_price: Union[List[Series], List[float]],
) -> Tuple[List[Series], List[float]]:
    """Schedule devices given constraints on a device and EMS level, and given a list of commitments by the EMS.
    The commitments are assumed to be with regards to the flow of energy to the device (positive for consumption,
    negative for production). The solver minimises the costs of deviating from the commitments, and returns the costs
    per commitment.
    Device constraints are on a device level. Handled constraints (listed by column name):
        max: maximum stock assuming an initial stock of zero (e.g. in MWh or boxes)
        min: minimum stock assuming an initial stock of zero
        derivative max: maximum flow (e.g. in MW or boxes/h)
        derivative min: minimum flow
        derivative equals: exact amount of flow
    EMS constraints are on an EMS level. Handled constraints (listed by column name):
        derivative max: maximum flow
        derivative min: minimum flow
    Commitments are on an EMS level. Parameter explanations:
        commitment_quantities: amounts of flow specified in commitments (both previously ordered and newly requested)
            - e.g. in MW or boxes/h
        commitment_downwards_deviation_price: penalty for downwards deviations of the flow
            - e.g. in EUR/MW or EUR/(boxes/h)
            - either a single value (same value for each flow value) or a Series (different value for each flow value)
        commitment_upwards_deviation_price: penalty for upwards deviations of the flow
    All Series and DataFrames should have the same resolution.
    For now we pass in the various constraints and prices as separate variables, from which we make a MultiIndex
    DataFrame. Later we could pass in a MultiIndex DataFrame directly.
    """

    # If the EMS has no devices, don't bother
    if len(device_constraints) == 0:
        return [], [] * len(commitment_quantities)

    # Check if commitments have the same time window and resolution as the constraints
    start = device_constraints[0].index.values[0]
    resolution = to_timedelta(device_constraints[0].index.freq)
    end = device_constraints[0].index.values[-1] + resolution
    if len(commitment_quantities) != 0:
        start_c = commitment_quantities[0].index.values[0]
        resolution_c = to_timedelta(commitment_quantities[0].index.freq)
        end_c = commitment_quantities[0].index.values[-1] + resolution
        if not (start_c == start and end_c == end):
            raise Exception(
                "Not implemented for different time windows.\n(%s,%s)\n(%s,%s)"
                % (start, end, start_c, end_c))
        if resolution_c != resolution:
            raise Exception(
                "Not implemented for different resolutions.\n%s\n%s" %
                (resolution, resolution_c))

    # Turn prices per commitment into prices per commitment flow
    if len(commitment_downwards_deviation_price) != 0:
        if all(not isinstance(price, Series)
               for price in commitment_downwards_deviation_price):
            commitment_downwards_deviation_price = [
                initialize_series(price, start, end, resolution)
                for price in commitment_downwards_deviation_price
            ]
    if len(commitment_upwards_deviation_price) != 0:
        if all(not isinstance(price, Series)
               for price in commitment_upwards_deviation_price):
            commitment_upwards_deviation_price = [
                initialize_series(price, start, end, resolution)
                for price in commitment_upwards_deviation_price
            ]

    # Determine appropriate overall bounds for power and price
    min_down_price = min(min(p) for p in commitment_downwards_deviation_price)
    max_down_price = max(max(p) for p in commitment_downwards_deviation_price)
    min_up_price = min(min(p) for p in commitment_upwards_deviation_price)
    max_up_price = max(max(p) for p in commitment_upwards_deviation_price)
    overall_min_price = min(min_down_price, min_up_price)
    overall_max_price = max(max_down_price, max_up_price)
    overall_min_power = min(ems_constraints["derivative min"])
    overall_max_power = max(ems_constraints["derivative max"])

    model = ConcreteModel()

    # Add indices for devices (d), datetimes (j) and commitments (c)
    model.d = RangeSet(0, len(device_constraints) - 1, doc="Set of devices")
    model.j = RangeSet(0,
                       len(device_constraints[0].index.values) - 1,
                       doc="Set of datetimes")
    model.c = RangeSet(0,
                       len(commitment_quantities) - 1,
                       doc="Set of commitments")

    # Add parameters
    def commitment_quantity_select(m, c, j):
        v = commitment_quantities[c].iloc[j]
        if isnan(v):  # Discount this nan commitment by setting the prices to 0
            commitment_downwards_deviation_price[c].iloc[j] = 0
            commitment_upwards_deviation_price[c].iloc[j] = 0
            return 0
        else:
            return v

    def price_down_select(m, c, j):
        return commitment_downwards_deviation_price[c].iloc[j]

    def price_up_select(m, c, j):
        return commitment_upwards_deviation_price[c].iloc[j]

    def device_max_select(m, d, j):
        v = device_constraints[d]["max"].iloc[j]
        if isnan(v):
            return infinity
        else:
            return v

    def device_min_select(m, d, j):
        v = device_constraints[d]["min"].iloc[j]
        if isnan(v):
            return -infinity
        else:
            return v

    def device_derivative_max_select(m, d, j):
        max_v = device_constraints[d]["derivative max"].iloc[j]
        equal_v = device_constraints[d]["derivative equals"].iloc[j]
        if isnan(max_v) and isnan(equal_v):
            return infinity
        else:
            return nanmin([max_v])

    def device_derivative_min_select(m, d, j):
        min_v = device_constraints[d]["derivative min"].iloc[j]
        equal_v = device_constraints[d]["derivative equals"].iloc[j]
        if isnan(min_v) and isnan(equal_v):
            return -infinity
        else:
            return nanmax([min_v])

    def device_derivative_equal_select(m, d, j):
        min_v = device_constraints[d]["derivative min"].iloc[j]
        equal_v = device_constraints[d]["derivative equals"].iloc[j]
        if isnan(equal_v):
            return 0
        else:
            return nanmax([equal_v])

    def ems_derivative_max_select(m, j):
        v = ems_constraints["derivative max"].iloc[j]
        if isnan(v):
            return infinity
        else:
            return v

    def ems_derivative_min_select(m, j):
        v = ems_constraints["derivative min"].iloc[j]
        if isnan(v):
            return -infinity
        else:
            return v

    model.commitment_quantity = Param(model.c,
                                      model.j,
                                      initialize=commitment_quantity_select)
    model.up_price = Param(model.c, model.j, initialize=price_up_select)
    model.down_price = Param(model.c, model.j, initialize=price_down_select)
    model.device_max = Param(model.d, model.j, initialize=device_max_select)
    model.device_min = Param(model.d, model.j, initialize=device_min_select)
    model.device_derivative_max = Param(
        model.d, model.j, initialize=device_derivative_max_select)
    model.device_derivative_min = Param(
        model.d, model.j, initialize=device_derivative_min_select)
    model.device_derivative_equal = Param(
        model.d, model.j, initialize=device_derivative_equal_select)

    model.ems_derivative_max = Param(model.j,
                                     initialize=ems_derivative_max_select)
    model.ems_derivative_min = Param(model.j,
                                     initialize=ems_derivative_min_select)

    # Add variables
    model.power = Var(
        model.d,
        model.j,
        domain=Reals,
        initialize=0,
        bounds=(overall_min_power, overall_max_power),
    )

    # Add constraints as a tuple of (lower bound, value, upper bound)
    def device_bounds(m, d, j):
        return (
            m.device_min[d, j],
            sum(m.power[d, k] for k in range(0, j + 1)),
            m.device_max[d, j],
        )

    def device_derivative_bounds(m, d, j):
        return (
            m.device_derivative_min[d, j],
            m.power[d, j] - m.device_derivative_equal[d, j],
            m.device_derivative_max[d, j],
        )

    def ems_derivative_bounds(m, j):
        return m.ems_derivative_min[j], sum(
            m.power[:, j]), m.ems_derivative_max[j]

    model.device_energy_bounds = Constraint(model.d,
                                            model.j,
                                            rule=device_bounds)
    model.device_power_bounds = Constraint(model.d,
                                           model.j,
                                           rule=device_derivative_bounds)
    model.ems_power_bounds = Constraint(model.j, rule=ems_derivative_bounds)

    # Add logical disjunction for deviations
    model.price = Var(model.c,
                      model.j,
                      initialize=0,
                      bounds=(overall_min_price, overall_max_price))

    def up_linker(b, c, d, j):
        # print("In up linker")
        m = b.model()
        ems_power_in_j = sum(m.power[d, j] for d in m.d)
        ems_power_deviation = ems_power_in_j - m.commitment_quantity[c, j]
        # try:
        # print(value(ems_power_deviation))
        # except:
        # pass
        b.linker = Constraint(expr=m.price[c, j] == m.up_price[c, j])
        b.constr = Constraint(expr=ems_power_deviation >= 0)
        b.BigM = Suffix(direction=Suffix.LOCAL)
        b.BigM[b.linker] = 10e5
        return

    def down_linker(b, c, d, j):
        # print("In down linker")
        m = b.model()
        ems_power_in_j = sum(m.power[d, j] for d in m.d)
        ems_power_deviation = ems_power_in_j - m.commitment_quantity[c, j]
        # try:
        # print(value(ems_power_deviation))
        # except:
        # pass
        b.linker = Constraint(expr=m.price[c, j] == m.down_price[c, j])
        b.constr = Constraint(expr=ems_power_deviation <= 0)
        b.BigM = Suffix(direction=Suffix.LOCAL)
        b.BigM[b.linker] = 10e5
        return

    # def zero_linker(b, c, d, j):
    #     #print("In down linker")
    #     m = b.model()
    #     ems_power_in_j = sum(m.power[d, j] for d in m.d)
    #     ems_power_deviation = ems_power_in_j - m.commitment_quantity[c, j]
    #     #try:
    #         #print(value(ems_power_deviation))
    #     #except:
    #         #pass
    #     b.linker = Constraint(expr=m.price[c, j] == 0)
    #     b.constr = Constraint(expr=ems_power_deviation == 0)
    #     #b.BigM = Suffix(direction=Suffix.LOCAL)
    #     #b.BigM[b.linker] = 10e10
    #     return

    model.up_deviation = Disjunct(model.c, model.d, model.j, rule=up_linker)
    model.down_deviation = Disjunct(model.c,
                                    model.d,
                                    model.j,
                                    rule=down_linker)

    # model.zero_deviation = Disjunct(model.c, model.d, model.j, rule=zero_linker)

    def bind_prices(m, c, d, j):
        return [
            model.up_deviation[c, d, j],
            model.down_deviation[c, d, j],
            # model.zero_deviation[c, d, j]
        ]

    model.up_or_down_deviation = Disjunction(model.c,
                                             model.d,
                                             model.j,
                                             rule=bind_prices,
                                             xor=True)

    # Add objective
    def cost_function(m):
        costs = 0
        for j in m.j:
            for c in m.c:
                ems_power_in_j = sum(m.power[d, j] for d in m.d)
                ems_power_deviation = ems_power_in_j - m.commitment_quantity[c,
                                                                             j]
                costs += ems_power_deviation * m.price[c, j]
        return costs

    model.costs = Objective(rule=cost_function, sense=minimize)

    # def xfrm(m):
    #     TransformationFactory('gdp.chull').apply_to(m)
    # model.xfrm = BuildAction(rule=xfrm)

    # Transform and solve
    xfrm = TransformationFactory("gdp.bigm")
    xfrm.apply_to(model)
    solver = SolverFactory(
        "cplex", executable="D:/CPLEX/Studio/cplex/bin/x64_win64/cplex")
    # solver.options['CPXchgprobtype'] = "CPXPROB_QP"
    # solver.options["solver"] = "CPXqpopt"
    solver.options["qpmethod"] = 1
    solver.options["optimalitytarget"] = 3

    # solver.options["acceptable_constr_viol_tol"] = 10
    # solver.options['acceptable_tol'] = 1
    # solver.options['acceptable_dual_inf_tol'] = 10
    # solver.options['acceptable_compl_inf_tol'] = 10
    results = solver.solve(model, tee=False)

    planned_costs = value(model.costs)
    planned_power_per_device = []
    for d in model.d:
        planned_device_power = [
            round(model.power[d, j].value, 3) for j in model.j
        ]
        planned_power_per_device.append(
            initialize_series(planned_device_power,
                              start=start,
                              end=end,
                              resolution=resolution))
    # model.display()
    # results.pprint()
    # model.down_deviation.pprint()
    # model.up_deviation.pprint()
    # model.power.pprint()

    # print(planned_power_per_device)
    # input()

    # Redo the cost calculation, because before the solver actually approximated the prices.
    def redo_cost_calculation(m):
        commitments_costs = []
        for c in m.c:
            commitment_cost = 0
            for j in m.j:

                ems_power_in_j = sum(m.power[d, j] for d in m.d)
                ems_power_deviation = ems_power_in_j - m.commitment_quantity[c,
                                                                             j]

                if value(ems_power_deviation) >= 0:
                    commitment_cost += round(
                        value(ems_power_deviation * m.up_price[c, j]), 3)

                else:
                    commitment_cost += round(
                        value(ems_power_deviation * m.down_price[c, j]), 3)

            commitments_costs.append(commitment_cost)
        return commitments_costs

    planned_costs_per_commitment = redo_cost_calculation(model)
    # print(planned_costs_per_commitment)

    return planned_power_per_device, planned_costs_per_commitment
예제 #52
0
    def test_construct_implicit_disjuncts(self):
        m = ConcreteModel()
        m.x = Var()
        m.y = Var()
        m.d = Disjunction(expr=[m.x <= 0, m.y >= 1])
        self.assertEqual(len(m.component_map(Disjunction)), 1)
        self.assertEqual(len(m.component_map(Disjunct)), 1)

        implicit_disjuncts = list(m.component_map(Disjunct).keys())
        self.assertEqual(implicit_disjuncts[0][:2], "d_")
        disjuncts = m.d.disjuncts
        self.assertEqual(len(disjuncts), 2)
        self.assertIs(disjuncts[0].parent_block(), m)
        self.assertIs(disjuncts[0].constraint[1].body, m.x)
        self.assertIs(disjuncts[1].parent_block(), m)
        self.assertIs(disjuncts[1].constraint[1].body, m.y)

        # Test that the implicit disjuncts get a unique name
        m.add_component('e_disjuncts', Var())
        m.e = Disjunction(expr=[m.y <= 0, m.x >= 1])
        self.assertEqual(len(m.component_map(Disjunction)), 2)
        self.assertEqual(len(m.component_map(Disjunct)), 2)
        implicit_disjuncts = list(m.component_map(Disjunct).keys())
        self.assertEqual(implicit_disjuncts[1][:12], "e_disjuncts_")
        disjuncts = m.e.disjuncts
        self.assertEqual(len(disjuncts), 2)
        self.assertIs(disjuncts[0].parent_block(), m)
        self.assertIs(disjuncts[0].constraint[1].body, m.y)
        self.assertIs(disjuncts[1].parent_block(), m)
        self.assertIs(disjuncts[1].constraint[1].body, m.x)
        self.assertEqual(len(disjuncts[0].parent_component().name), 13)
        self.assertEqual(disjuncts[0].name[:12], "e_disjuncts_")

        # Test that the implicit disjuncts can be lists/tuples/generators
        def _gen():
            yield m.y <= 4
            yield m.x >= 5

        m.f = Disjunction(expr=[[m.y <= 0, m.x >= 1], (
            m.y <= 2,
            m.x >= 3), _gen()])
        self.assertEqual(len(m.component_map(Disjunction)), 3)
        self.assertEqual(len(m.component_map(Disjunct)), 3)
        implicit_disjuncts = list(m.component_map(Disjunct).keys())
        self.assertEqual(implicit_disjuncts[2][:12], "f_disjuncts")
        disjuncts = m.f.disjuncts
        self.assertEqual(len(disjuncts), 3)
        self.assertIs(disjuncts[0].parent_block(), m)
        self.assertIs(disjuncts[0].constraint[1].body, m.y)
        self.assertEqual(disjuncts[0].constraint[1].upper, 0)
        self.assertIs(disjuncts[0].constraint[2].body, m.x)
        self.assertEqual(disjuncts[0].constraint[2].lower, 1)

        self.assertIs(disjuncts[1].parent_block(), m)
        self.assertIs(disjuncts[1].constraint[1].body, m.y)
        self.assertEqual(disjuncts[1].constraint[1].upper, 2)
        self.assertIs(disjuncts[1].constraint[2].body, m.x)
        self.assertEqual(disjuncts[1].constraint[2].lower, 3)

        self.assertIs(disjuncts[2].parent_block(), m)
        self.assertIs(disjuncts[2].constraint[1].body, m.y)
        self.assertEqual(disjuncts[2].constraint[1].upper, 4)
        self.assertIs(disjuncts[2].constraint[2].body, m.x)
        self.assertEqual(disjuncts[2].constraint[2].lower, 5)

        self.assertEqual(len(disjuncts[0].parent_component().name), 11)
        self.assertEqual(disjuncts[0].name, "f_disjuncts[0]")
예제 #53
0
    def criticalityCheck(self, x, y, z, rom_params, worstcase=False, M=[0.0]):

        model = self.model

        self.setVarValue(x=x, y=y, z=z)
        self.setBound(x, y, z, 1e10)
        self.deactiveExtraConObj()
        self.activateRomCons(x, rom_params)

        optGJH = SolverFactory('contrib.gjh')
        optGJH.solve(model, tee=False, symbolic_solver_labels=True)
        g, J, varlist, conlist = model._gjh_info

        l = ConcreteModel()
        l.v = Var(varlist, domain=Reals)
        for i in varlist:
            #dummy = model.find_component(i)
            l.v[i] = 0.0
            l.v[i].setlb(-1.0)
            l.v[i].setub(1.0)
        if worstcase:
            if M.all() == 0.0:
                print(
                    'WARNING: worstcase criticality was requested but Jacobian error bound is zero'
                )
            l.t = Var(range(0, self.ly), domain=Reals)
            for i in range(0, self.ly):
                l.t[i].setlb(-M[i])
                l.t[i].setub(M[i])

        def linConMaker(l, i):
            # i should be range(len(conlist) - 1)
            # because last element of conlist is the objective
            con_i = model.find_component(conlist[i])

            isEquality = con_i.equality

            isROM = False

            if conlist[i][:7] == '.' + self.TRF.name + '.rom':
                isROM = True
                romIndex = int(filter(str.isdigit, conlist[i]))

            # This is very inefficient
            # Fix this later if these problems get big
            # This is the ith row of J times v
            Jv = sum(x[2] * l.v[varlist[x[1]]] for x in J if x[0] == i)

            if isEquality:
                if worstcase and isROM:
                    return Jv + l.t[romIndex] == 0
                else:
                    return Jv == 0
            else:
                lo = con_i.lower
                up = con_i.upper
                if lo is not None:
                    level = lo.value - con_i.lslack()
                    if up is not None:
                        return (lo.value <= level + Jv <= up.value)
                    else:
                        return (lo.value <= level + Jv)
                elif up is not None:
                    level = up.value - con_i.uslack()
                    return (level + Jv <= up.value)
                else:
                    raise Exception(
                        "This constraint seems to be neither equality or inequality: "
                        + conlist(i))

        l.lincons = Constraint(range(len(conlist) - 1), rule=linConMaker)

        l.obj = Objective(expr=sum(x[1] * l.v[varlist[x[0]]] for x in g))

        # Calculate gradient norm for scaling purposes
        gfnorm = sqrt(sum(x[1]**2 for x in g))

        opt = SolverFactory(self.config.solver)
        opt.options.update(self.config.solver_options)
        #opt.options['halt_on_ampl_error'] = 'yes'
        #opt.options['max_iter'] = 5000
        results = opt.solve(l,
                            keepfiles=self.keepfiles,
                            tee=self.stream_solver)

        if ((results.solver.status == SolverStatus.ok)
                and (results.solver.termination_condition
                     == TerminationCondition.optimal)):
            l.solutions.load_from(results)
            if gfnorm > 1:
                return True, abs(l.obj()) / gfnorm
            else:
                return True, abs(l.obj())
        else:
            print("Waring: Crticality check fails with solver Status: " +
                  str(results.solver.status))
            print("And Termination Conditions: " +
                  str(results.solver.termination_condition))
            return False, infinity
예제 #54
0
 def test_abs(self):
     m = ConcreteModel()
     m.x = Var(bounds=(-1, 1), initialize=0)
     mc_expr = mc(abs((m.x)))
     self.assertEqual(mc_expr.lower(), 0)
     self.assertEqual(mc_expr.upper(), 1)
예제 #55
0
    def test_multiindexedvar_singlewildcardtemplate(self):
        st_model = CreateConcreteTwoStageScenarioTreeModel(1)
        st_model.StageVariables['Stage1'].add("x[*,* ]")
        st_model.StageDerivedVariables['Stage1'].add("y[ *,*]")
        st_model.NodeVariables['RootNode'].add("z[*,*]")
        st_model.NodeDerivedVariables['RootNode'].add("q[ * , * ]")
        st_model.StageCost['Stage1'] = "FirstStageCost"
        st_model.StageCost['Stage2'] = "SecondStageCost"

        scenario_tree = ScenarioTree(scenariotreeinstance=st_model)
        self.assertEqual(len(scenario_tree.stages), 2)
        self.assertEqual(len(scenario_tree.nodes), 2)
        self.assertEqual(len(scenario_tree.scenarios), 1)

        model = ConcreteModel()
        model.s = Set(initialize=[(1, 'a'), (2, 'b'), (3, 'c')])
        model.x = Var(model.s)
        model.y = Var(model.s)
        model.z = Var(model.s)
        model.q = Var(model.s)
        model.FirstStageCost = Expression(expr=0.0)
        model.SecondStageCost = Expression(expr=0.0)
        model.obj = Objective(expr=0.0)

        root = scenario_tree.findRootNode()
        root_nonant_names = _get_names(_get_nonant_list(model, root))
        root_derived_nonant_names = _get_names(
            _get_derived_nonant_list(model, root))
        assert len(root_nonant_names) == 6
        assert len(root_derived_nonant_names) == 6

        for name in ("x", "z"):
            indexed_var = model.find_component(name)
            for index in model.s:
                var = indexed_var[index]
                assert var.name in root_nonant_names
        for name in ("y", "q"):
            indexed_var = model.find_component(name)
            for index in model.s:
                var = indexed_var[index]
                assert var.name in root_derived_nonant_names
예제 #56
0
    def select_tear_mip_model(self, G):
        """
        Generate a model for selecting tears from the given graph

        Returns
        -------
            model
            bin_list
                A list of the binary variables representing each edge,
                indexed by the edge index of the graph
        """
        model = ConcreteModel()

        bin_list = []
        for i in range(G.number_of_edges()):
            # add a binary "torn" variable for every edge
            vname = "edge%s" % i
            var = Var(domain=Binary)
            bin_list.append(var)
            model.add_component(vname, var)

        # var containing the maximum number of times any cycle is torn
        mct = model.max_cycle_tears = Var()

        _, cycleEdges = self.all_cycles(G)

        for i in range(len(cycleEdges)):
            ecyc = cycleEdges[i]

            # expression containing sum of tears for each cycle
            ename = "cycle_sum%s" % i
            expr = Expression(expr=sum(bin_list[i] for i in ecyc))
            model.add_component(ename, expr)

            # every cycle must have at least 1 tear
            cname_min = "cycle_min%s" % i
            con_min = Constraint(expr=expr >= 1)
            model.add_component(cname_min, con_min)

            # mct >= cycle_sum for all cycles, thus it becomes the max
            cname_mct = mct.name + "_geq%s" % i
            con_mct = Constraint(expr=mct >= expr)
            model.add_component(cname_mct, con_mct)

        # weigh the primary objective much greater than the secondary
        obj_expr = 1000 * mct + sum(var for var in bin_list)
        model.obj = Objective(expr=obj_expr, sense=minimize)

        return model, bin_list
예제 #57
0
    def test_deactivate(self):
        m = ConcreteModel()
        m.x = Var()
        m.d1 = Disjunct()
        m.d1.constraint = Constraint(expr=m.x <= 0)
        m.d = Disjunction(expr=[m.d1, m.x >= 1, m.x >= 5])
        d2 = m.d.disjuncts[1].parent_component()
        self.assertEqual(len(m.component_map(Disjunction)), 1)
        self.assertEqual(len(m.component_map(Disjunct)), 2)
        self.assertIsNot(m.d1, d2)

        self.assertTrue(m.d1.active)
        self.assertTrue(d2.active)
        self.assertTrue(m.d.disjuncts[0].active)
        self.assertTrue(m.d.disjuncts[1].active)
        self.assertTrue(m.d.disjuncts[2].active)
        self.assertFalse(m.d.disjuncts[0].indicator_var.is_fixed())
        self.assertFalse(m.d.disjuncts[1].indicator_var.is_fixed())
        self.assertFalse(m.d.disjuncts[2].indicator_var.is_fixed())

        m.d.disjuncts[0].deactivate()
        self.assertFalse(m.d1.active)
        self.assertTrue(d2.active)
        self.assertFalse(m.d.disjuncts[0].active)
        self.assertTrue(m.d.disjuncts[1].active)
        self.assertTrue(m.d.disjuncts[2].active)
        self.assertTrue(m.d.disjuncts[0].indicator_var.is_fixed())
        self.assertFalse(m.d.disjuncts[1].indicator_var.is_fixed())
        self.assertFalse(m.d.disjuncts[2].indicator_var.is_fixed())

        m.d.disjuncts[1].deactivate()
        self.assertFalse(m.d1.active)
        self.assertTrue(d2.active)
        self.assertFalse(m.d.disjuncts[0].active)
        self.assertFalse(m.d.disjuncts[1].active)
        self.assertTrue(m.d.disjuncts[2].active)
        self.assertTrue(m.d.disjuncts[0].indicator_var.is_fixed())
        self.assertTrue(m.d.disjuncts[1].indicator_var.is_fixed())
        self.assertFalse(m.d.disjuncts[2].indicator_var.is_fixed())

        d2.deactivate()
        self.assertFalse(m.d1.active)
        self.assertFalse(d2.active)
        self.assertFalse(m.d.disjuncts[0].active)
        self.assertFalse(m.d.disjuncts[1].active)
        self.assertFalse(m.d.disjuncts[2].active)
        self.assertTrue(m.d.disjuncts[0].indicator_var.is_fixed())
        self.assertTrue(m.d.disjuncts[1].indicator_var.is_fixed())
        self.assertTrue(m.d.disjuncts[2].indicator_var.is_fixed())

        m.d.disjuncts[2].activate()
        self.assertFalse(m.d1.active)
        self.assertTrue(d2.active)
        self.assertFalse(m.d.disjuncts[0].active)
        self.assertFalse(m.d.disjuncts[1].active)
        self.assertTrue(m.d.disjuncts[2].active)
        self.assertTrue(m.d.disjuncts[0].indicator_var.is_fixed())
        self.assertTrue(m.d.disjuncts[1].indicator_var.is_fixed())
        self.assertFalse(m.d.disjuncts[2].indicator_var.is_fixed())

        d2.activate()
        self.assertFalse(m.d1.active)
        self.assertTrue(d2.active)
        self.assertFalse(m.d.disjuncts[0].active)
        self.assertTrue(m.d.disjuncts[1].active)
        self.assertTrue(m.d.disjuncts[2].active)
        self.assertTrue(m.d.disjuncts[0].indicator_var.is_fixed())
        self.assertFalse(m.d.disjuncts[1].indicator_var.is_fixed())
        self.assertFalse(m.d.disjuncts[2].indicator_var.is_fixed())

        m.d1.activate()
        self.assertTrue(m.d1.active)
        self.assertTrue(d2.active)
        self.assertTrue(m.d.disjuncts[0].active)
        self.assertTrue(m.d.disjuncts[1].active)
        self.assertTrue(m.d.disjuncts[2].active)
        self.assertFalse(m.d.disjuncts[0].indicator_var.is_fixed())
        self.assertFalse(m.d.disjuncts[1].indicator_var.is_fixed())
        self.assertFalse(m.d.disjuncts[2].indicator_var.is_fixed())
예제 #58
0
    def _generate_model(self):
        self.model = ConcreteModel()
        model = self.model
        model._name = self.description

        model.s = RangeSet(1, 12)
        model.x = Var(model.s)
        model.x[1].setlb(-1)
        model.x[1].setub(1)
        model.x[2].setlb(-1)
        model.x[2].setub(1)
        model.obj = Objective(expr=sum(model.x[i] * ((-1)**(i + 1))
                                       for i in model.x.index_set()))
        model.c = ConstraintList()
        # to make the variable used in the constraint match the name
        model.c.add(Constraint.Skip)
        model.c.add(Constraint.Skip)
        model.c.add(model.x[3] >= -1.)
        model.c.add(model.x[4] <= 1.)
        model.c.add(model.x[5] == -1.)
        model.c.add(model.x[6] == -1.)
        model.c.add(model.x[7] == 1.)
        model.c.add(model.x[8] == 1.)
        model.c.add((-1., model.x[9], -1.))
        model.c.add((-1., model.x[10], -1.))
        model.c.add((1., model.x[11], 1.))
        model.c.add((1., model.x[12], 1.))
        cdata = model.c.add((0, 1, 3))
        assert cdata.lower == 0
        assert cdata.upper == 3
        assert cdata.body() == 1
        assert not cdata.equality
        cdata = model.c.add((0, 2, 3))
        assert cdata.lower == 0
        assert cdata.upper == 3
        assert cdata.body() == 2
        assert not cdata.equality
        cdata = model.c.add((0, 1, None))
        assert cdata.lower == 0
        assert cdata.upper is None
        assert cdata.body() == 1
        assert not cdata.equality
        cdata = model.c.add((None, 0, 1))
        assert cdata.lower is None
        assert cdata.upper == 1
        assert cdata.body() == 0
        assert not cdata.equality
        cdata = model.c.add((1, 1))
        assert cdata.lower == 1
        assert cdata.upper == 1
        assert cdata.body() == 1
        assert cdata.equality

        model.fixed_var = Var()
        model.fixed_var.fix(1.0)
        cdata = model.c.add((0, 1 + model.fixed_var, 3))
        cdata = model.c.add((0, 2 + model.fixed_var, 3))
        cdata = model.c.add((0, model.fixed_var, None))
        cdata = model.c.add((None, model.fixed_var, 1))
        cdata = model.c.add((model.fixed_var, 1))

        model.c_inactive = ConstraintList()
        # to make the variable used in the constraint match the name
        model.c_inactive.add(Constraint.Skip)
        model.c_inactive.add(Constraint.Skip)
        model.c_inactive.add(model.x[3] >= -2.)
        model.c_inactive.add(model.x[4] <= 2.)

        compile_block_linear_constraints(model, 'Amatrix')
예제 #59
0
    def generate_structured_model(self):
        """
        Using the community map and the original model used to create this community map, we will create
        structured_model, which will be based on the original model but will place variables, constraints, and
        objectives into or outside of various blocks (communities) based on the community map.

        Returns
        -------
        structured_model: Block
            a Pyomo model that reflects the nature of the community map
        """

        # Initialize a new model (structured_model) which will contain variables and constraints in blocks based on
        # their respective communities within the CommunityMap
        structured_model = ConcreteModel()

        # Create N blocks (where N is the number of communities found within the model)
        structured_model.b = Block([0, len(self.community_map) - 1,
                                    1])  # values given for (start, stop, step)

        # Initialize a ComponentMap that will map a variable from the model (for example, old_model.x1) used to
        # create the CommunityMap to a list of variables in various blocks that were created based on this
        # variable (for example, [structured_model.b[0].x1, structured_model.b[3].x1])
        blocked_variable_map = ComponentMap()
        # Example key-value pair -> {original_model.x1 : [structured_model.b[0].x1, structured_model.b[3].x1]}

        # TODO - Consider changing structure of the next two for loops to be more efficient (maybe loop through
        #  constraints and add variables as you go) (but note that disconnected variables would be
        #  missed with this strategy)

        # First loop through community_map to add all the variables to structured_model before we add constraints
        # that use those variables
        for community_key, community in self.community_map.items():
            _, variables_in_community = community

            # Loop through all of the variables (from the original model) in the given community
            for stored_variable in variables_in_community:
                # Construct a new_variable whose attributes are determined by querying the variable from the
                # original model
                new_variable = Var(domain=stored_variable.domain,
                                   bounds=stored_variable.bounds)

                # Add this new_variable to its block/community and name it using the string of the variable from the
                # original model
                structured_model.b[community_key].add_component(
                    str(stored_variable), new_variable)

                # Since there could be multiple variables 'x1' (such as
                # structured_model.b[0].x1, structured_model.b[3].x1, etc), we need to create equality constraints
                # for all of the variables 'x1' within structured_model (this is the purpose of blocked_variable_map)

                # Here we update blocked_variable_map to keep track of what equality constraints need to be made
                variable_in_new_model = structured_model.find_component(
                    new_variable)
                blocked_variable_map[
                    stored_variable] = blocked_variable_map.get(
                        stored_variable, []) + [variable_in_new_model]

        # Now that we have all of our variables within the model, we will initialize a dictionary that used to
        # replace variables within constraints to other variables (in our case, this will convert variables from the
        # original model into variables from the new model (structured_model))
        replace_variables_in_expression_map = dict()

        # Loop through community_map again, this time to add constraints (with replaced variables)
        for community_key, community in self.community_map.items():
            constraints_in_community, _ = community

            # Loop through all of the constraints (from the original model) in the given community
            for stored_constraint in constraints_in_community:

                # Now, loop through all of the variables within the given constraint expression
                for variable_in_stored_constraint in identify_variables(
                        stored_constraint.expr):

                    # Loop through each of the "blocked" variables that a variable is mapped to and update
                    # replace_variables_in_expression_map if a variable has a "blocked" form in the given community

                    # What this means is that if we are looping through constraints in community 0, then it would be
                    # best to change a variable x1 into b[0].x1 as opposed to b[2].x1 or b[5].x1 (assuming all of these
                    # blocked versions of the variable x1 exist (which depends on the community map))

                    variable_in_current_block = False
                    for blocked_variable in blocked_variable_map[
                            variable_in_stored_constraint]:
                        if 'b[%d]' % community_key in str(blocked_variable):
                            # Update replace_variables_in_expression_map accordingly
                            replace_variables_in_expression_map[
                                id(variable_in_stored_constraint
                                   )] = blocked_variable
                            variable_in_current_block = True

                    if not variable_in_current_block:
                        # Create a version of the given variable outside of blocks then add it to
                        # replace_variables_in_expression_map

                        new_variable = Var(
                            domain=variable_in_stored_constraint.domain,
                            bounds=variable_in_stored_constraint.bounds)

                        # Add the new variable just as we did above (but now it is not in any blocks)
                        structured_model.add_component(
                            str(variable_in_stored_constraint), new_variable)

                        # Update blocked_variable_map to keep track of what equality constraints need to be made
                        variable_in_new_model = structured_model.find_component(
                            new_variable)
                        blocked_variable_map[
                            variable_in_stored_constraint] = blocked_variable_map.get(
                                variable_in_stored_constraint,
                                []) + [variable_in_new_model]

                        # Update replace_variables_in_expression_map accordingly
                        replace_variables_in_expression_map[
                            id(variable_in_stored_constraint
                               )] = variable_in_new_model

                # TODO - Is there a better way to check whether something is actually an objective? (as done below)
                # Check to see whether 'stored_constraint' is actually an objective (since constraints and objectives
                # grouped together)
                if self.with_objective and isinstance(
                        stored_constraint, (_GeneralObjectiveData, Objective)):
                    # If the constraint is actually an objective, we add it to the block as an objective
                    new_objective = Objective(expr=replace_expressions(
                        stored_constraint.expr,
                        replace_variables_in_expression_map))
                    structured_model.b[community_key].add_component(
                        str(stored_constraint), new_objective)

                else:
                    # Construct a constraint based on the expression within stored_constraint and the dict we have
                    # created for the purpose of replacing the variables within the constraint expression
                    new_constraint = Constraint(expr=replace_expressions(
                        stored_constraint.expr,
                        replace_variables_in_expression_map))

                    # Add this new constraint to the corresponding community/block with its name as the string of the
                    # constraint from the original model
                    structured_model.b[community_key].add_component(
                        str(stored_constraint), new_constraint)

        # If with_objective was set to False, that means we might have missed an objective function within the
        # original model
        if not self.with_objective:
            # Construct a new dictionary for replacing the variables (replace_variables_in_objective_map) which will
            # be specific to the variables in the objective function, since there is the possibility that the
            # objective contains variables we have not yet seen (and thus not yet added to our new model)
            for objective_function in self.model.component_data_objects(
                    ctype=Objective,
                    active=self.use_only_active_components,
                    descend_into=True):

                for variable_in_objective in identify_variables(
                        objective_function):
                    # Add all of the variables in the objective function (not within any blocks)

                    # Check to make sure a form of the variable has not already been made outside of the blocks
                    if structured_model.find_component(
                            str(variable_in_objective)) is None:

                        new_variable = Var(domain=variable_in_objective.domain,
                                           bounds=variable_in_objective.bounds)
                        structured_model.add_component(
                            str(variable_in_objective), new_variable)

                        # Again we update blocked_variable_map to keep track of what
                        # equality constraints need to be made
                        variable_in_new_model = structured_model.find_component(
                            new_variable)
                        blocked_variable_map[
                            variable_in_objective] = blocked_variable_map.get(
                                variable_in_objective,
                                []) + [variable_in_new_model]

                        # Update the dictionary that we will use to replace the variables
                        replace_variables_in_expression_map[id(
                            variable_in_objective)] = variable_in_new_model

                    else:
                        for version_of_variable in blocked_variable_map[
                                variable_in_objective]:
                            if 'b[' not in str(version_of_variable):
                                replace_variables_in_expression_map[
                                    id(variable_in_objective
                                       )] = version_of_variable

                # Now we will construct a new objective function based on the one from the original model and then
                # add it to the new model just as we have done before
                new_objective = Objective(expr=replace_expressions(
                    objective_function.expr,
                    replace_variables_in_expression_map))
                structured_model.add_component(str(objective_function),
                                               new_objective)

        # Now, we need to create equality constraints for all of the different "versions" of a variable (such
        # as x1, b[0].x1, b[2].x2, etc.)

        # Create a constraint list for the equality constraints
        structured_model.equality_constraint_list = ConstraintList(
            doc="Equality Constraints for the different "
            "forms of a given variable")

        # Loop through blocked_variable_map and create constraints accordingly
        for variable, duplicate_variables in blocked_variable_map.items():
            # variable -> variable from the original model
            # duplicate_variables -> list of variables in the new model

            # Create a list of all the possible equality constraints that need to be made
            equalities_to_make = combinations(duplicate_variables, 2)

            # Loop through the list of two-variable tuples and create an equality constraint for those two variables
            for variable_1, variable_2 in equalities_to_make:
                structured_model.equality_constraint_list.add(
                    expr=variable_1 == variable_2)

        # Return 'structured_model', which is essentially identical to the original model but now has all of the
        # variables, constraints, and objectives placed into blocks based on the nature of the CommunityMap

        return structured_model
예제 #60
0
def create_linear_dual_from(block, fixed=None, unfixed=None):
    """
    Construct a block that represents the dual of the given block.

    The resulting block contains variables and constraints whose names are
    the dual names of the primal block.  Note that this involves a many
    string operations.  A quicker operations could be executed, but it
    would generate a dual representation that is difficult to interpret.

    Note that the dualization of a maximization problem is performed by
    negating objective and right-hand side coefficients after dualizing
    the corresponding minimization problem.  This suggestion is made
    by Dimitri Bertsimas and John Tsitsiklis in section 4.2 page 143 of
    "Introduction to Linear Optimization"

    Arguments:
        block: A Pyomo block or model
        unfixed: An iterable object with Variable and VarData values that are 
                not fixed variables.  All other variables are assumed to be fixed.
        fixed: An iterable object with Variable and VarData values that are fixed.  
                All other variables are assumed not fixed.

    Returns:
        If the block is a model object, then this returns a ConcreteModel.
        Otherwise, it returns a Block.
    """
    #
    # Collect vardata that needs to be fixed
    #
    fixed_modelvars = {}
    if fixed or unfixed:
        #
        # Collect model variables
        #
        modelvars = {}
        #
        # vardata in objectives
        #
        for obj in block.component_objects(Objective, active=True):
            for ndx in obj:
                #odata = generate_standard_repn(obj[ndx].expr, compute_values=False)
                for vdata in identify_variables(obj[ndx].expr, include_fixed=False):
                    id_ = id(vdata)
                    if not id_ in modelvars:
                        modelvars[id_] = vdata
        #
        # vardata in constraints
        #
        for con in block.component_objects(Constraint, active=True):
            for ndx in con:
                #cdata = generate_standard_repn(con[ndx].body, compute_values=False)
                for vdata in identify_variables(con[ndx].body, include_fixed=False):
                    id_ = id(vdata)
                    if not id_ in modelvars:
                        modelvars[id_] = vdata
        #
        # Fix everything that isn't specified as unfixed
        #
        if unfixed:
            unfixed_vars = set()
            for v in unfixed:
                if v.is_indexed():
                    for vardata in v.values():
                        unfixed_vars.add( id(vardata) )
                else:
                    unfixed_vars.add( id(v) )
            for id_, vdata in modelvars.items():
                if id_ not in unfixed_vars:
                    fixed_modelvars[id_] = vdata
        #
        # ... or fix everything that is specified as fixed
        #
        elif fixed:
            fixed_vars = set()
            for v in fixed:
                if v.is_indexed():
                    for vardata in v.values():
                        fixed_vars.add( id(vardata) )
                else:
                    fixed_vars.add( id(v) )
            for id_ in fixed_vars:
                if id_ in modelvars:
                    fixed_modelvars[id_] = modelvars[id_]

    A, b_coef, obj_constant, c_rhs, c_sense, d_sense, v_domain =\
                    collect_dual_representation(block, fixed_modelvars)

    #
    # Construct the block
    #
    if isinstance(block, Model):
        dual = ConcreteModel()
    else:
        dual = Block()
    dual.construct()
    _vars = {}

    # Return variable object from name and index (if applicable)
    def getvar(name, ndx=None):
        v = _vars.get((name, ndx), None)
        if v is None:
            v = Var()
            if ndx is None:
                v_name = name
            elif isinstance(ndx, tuple):
                v_name = "%s[%s]" % (name, ','.join(map(str, ndx)))
            else:
                v_name = "%s[%s]" % (name, str(ndx))
            setattr(dual, v_name, v)
            _vars[name, ndx] = v
        return v
    #
    # Construct the objective
    # The dualization of a maximization problem is handled by simply negating the
    # objective and left-hand side coefficients while keeping the dual sense.
    #
    if d_sense == minimize:
        dual.o = Objective(expr=obj_constant + sum(- b_coef[name, ndx]*getvar(name, ndx)
                                    for name, ndx in b_coef), sense=d_sense)
        rhs_multiplier = -1
    else:
        dual.o = Objective(expr=obj_constant + sum(b_coef[name, ndx]*getvar(name, ndx)
                                    for name, ndx in b_coef), sense=d_sense)
        rhs_multiplier = 1
    #
    # Construct the constraints from dual A matrix
    #
    for cname in A:
        for ndx, terms in A[cname].items():

            # Build left-hand side of constraint
            expr = 0
            for term in terms:
                expr += term.coef * getvar(term.var, term.ndx)

            #
            # Assign right-hand side coefficient
            # Note that rhs_multiplier is 1 if the dual is a maximization problem and -1 otherwise
            #
            rhsval = rhs_multiplier*c_rhs.get((cname, ndx), 0.0)

            # Using the correct inequality or equality
            if c_sense[cname, ndx] == 'e':
                e = expr - rhsval == 0
            elif c_sense[cname, ndx] == 'l':
                e = expr - rhsval <= 0
            else:
                e = expr - rhsval >= 0
            c = Constraint(expr=e)

            # Build constraint name
            if ndx is None:
                c_name = cname
            elif isinstance(ndx, tuple):
                c_name = "%s[%s]" % (cname, ','.join(map(str, ndx)))
            else:
                c_name = "%s[%s]" % (cname, str(ndx))

            # Add new constraint along with its name to the dual
            setattr(dual, c_name, c)

        # Set variable domains
        for (name, ndx), domain in v_domain.items():
            v = getvar(name, ndx)
            #flag = type(ndx) is tuple and (ndx[-1] == 'lb' or ndx[-1] == 'ub')
            if domain == 1:
                v.domain = NonNegativeReals
            elif domain == -1:
                v.domain = NonPositiveReals
            else:
                # This is possible when the variable's corresponding constraint is an equality
                v.domain = Reals

    return dual