def test_ordered(self): M = ConcreteModel() M.v = Var({1, 2, 3}) try: M.c = SOSConstraint(var=M.v, sos=2) self.fail("Expected ValueError") except ValueError: pass M = ConcreteModel() M.s = Set(initialize=[1, 2, 3], ordered=True) M.v = Var(M.s) M.c = SOSConstraint(var=M.v, sos=2)
def test2(self): # Use an index set, which is a subset of M.x.index_set() M = ConcreteModel() M.x = Var(range(20)) M.c = SOSConstraint(var=M.x, index=list(range(10)), sos=1) self.assertEqual(set((v.name, w) for v, w in M.c.get_items()), set((M.x[i].name, i + 1) for i in range(10)))
def test_arg1(self): M = ConcreteModel() try: M.c = SOSConstraint() self.fail("Expected TypeError") except TypeError: pass
def test_negative_weights(self): M = ConcreteModel() M.v = Var() try: M.c = SOSConstraint(var=M.v, weights={None: -1}, sos=1) self.fail("Expected ValueError") except ValueError: pass
def test_arg3(self): M = ConcreteModel() M.v = Var() try: M.c = SOSConstraint(var=M.v) self.fail("Expected TypeError") except TypeError: pass
def test_abstract_index(self): model = AbstractModel() model.A = Set(initialize=[0]) model.B = Set(initialize=[1]) model.C = model.A | model.B M = ConcreteModel() M.x = Var([1,2,3]) M.c = SOSConstraint(model.C, var=M.x, sos=1, index={0:[1,2], 1:[2,3]})
def test10(self): M = ConcreteModel() M.x = Var([1,2,3]) M.c = SOSConstraint([0,1], var=M.x, sos=1, index={0:[1,2], 1:[2,3]}) self.assertEqual(set((v.name,w) for v,w in M.c[0].get_items()), set((M.x[i].name, i) for i in [1,2])) self.assertEqual(set((v.name,w) for v,w in M.c[1].get_items()), set((M.x[i].name, i-1) for i in [2,3]))
def test3(self): # User-specified weights w = {1: 10, 2: 2, 3: 30} M = ConcreteModel() M.x = Var([1, 2, 3]) M.c = SOSConstraint(var=M.x, weights=w, sos=1) self.assertEqual(set((v.name, w) for v, w in M.c.get_items()), set((M.x[i].name, w[i]) for i in [1, 2, 3]))
def test13(self): I = {0: [1, 2], 1: [2, 3]} M = ConcreteModel() M.x = Var([1, 2, 3], dense=True) M.c = SOSConstraint([0, 1], var=M.x, index=I, sos=1) self.assertEqual(set((v.name, w) for v, w in M.c[0].get_items()), set((M.x[i].name, i) for i in I[0])) self.assertEqual(set((v.name, w) for v, w in M.c[1].get_items()), set((M.x[i].name, i - 1) for i in I[1]))
def test11(self): w = {1:10, 2:2, 3:30} M = ConcreteModel() M.x = Var([1,2,3], dense=True) M.c = SOSConstraint([0,1], var=M.x, weights=w, sos=1, index={0:[1,2], 1:[2,3]}) self.assertEqual(set((v.name,w) for v,w in M.c[0].get_items()), set((M.x[i].name, w[i]) for i in [1,2])) self.assertEqual(set((v.name,w) for v,w in M.c[1].get_items()), set((M.x[i].name, w[i]) for i in [2,3]))
def test4(self): # User-specified weights w = {1:10, 2:2, 3:30} def rule(model): return list(M.x[i] for i in M.x), [10, 2, 30] M = ConcreteModel() M.x = Var([1,2,3], dense=True) M.c = SOSConstraint(rule=rule, sos=1) self.assertEqual(set((v.name,w) for v,w in M.c.get_items()), set((M.x[i].name, w[i]) for i in [1,2,3]))
def test_level(self): # Test level property self.M.x = Var([1, 2, 3]) self.M.c = SOSConstraint(var=self.M.x, sos=1) self.assertEqual(self.M.c.level, 1) self.M.c.level = 2 self.assertEqual(self.M.c.level, 2) try: self.M.c.level = -1 self.fail("Expected ValueError") except ValueError: pass
def test14(self): def rule(model, i): if i == 0: return SOSConstraint.Skip else: return list(M.x[i] for i in M.x), [1, 20, 3] w = {0:{1:10, 2:2, 3:30}, 1:{1:1, 2:20, 3:3}} M = ConcreteModel() M.x = Var([1,2,3], dense=True) M.c = SOSConstraint([0,1], rule=rule, sos=1) self.assertEqual(list(M.c.keys()), [1]) self.assertEqual(set((v.name,w) for v,w in M.c[1].get_items()), set((M.x[i].name, w[1][i]) for i in [1,2,3]))
def test_num_vars(self): # Test the number of variables self.M.x = Var([1, 2, 3]) self.M.c = SOSConstraint(var=self.M.x, sos=1) self.assertEqual(self.M.c.num_variables(), 3)
def test1(self): M = ConcreteModel() M.x = Var(range(20)) M.c = SOSConstraint(var=M.x, sos=1) self.assertEqual(set((v.name, w) for v, w in M.c.get_items()), set((M.x[i].name, i + 1) for i in range(20)))
def test_get_variables(self): # Test that you get the correct variables self.M.x = Var([1, 2, 3]) self.M.c = SOSConstraint(var=self.M.x, sos=1) self.assertEqual(set(id(v) for v in self.M.c.get_variables()), set(id(v) for v in self.M.x.values()))
def build_opt_model(self, X, y): """ Build an pyomo MIQP model that minimizes the MSE for the data. The model then can be solved or exported. model.b are the coefficients. :param X: 2-D numpy array of shape (N, d) :param y: 1-D numpy array of shape (d, ) :returns: (unsolved) pyomo model of the fitting problem """ N_rows, N_cols = X.shape row_index = list(range(N_rows)) column_index = list(range(N_cols)) piece_index = list(range(self.n_pieces)) X = X.tolist() y = y.tolist() model = ConcreteModel() model.t = Var(row_index, within=Reals) model.m = Var(row_index, within=Reals) model.b = Var(piece_index, column_index, within=Reals) model.s = Var(row_index, piece_index, within=Binary) def MinLTRule(model, i, p): return model.m[i] <= sum(model.b[p, j] * X[i][j] for j in column_index) model.MinLT = Constraint(row_index, piece_index, rule=MinLTRule) def MinGTRule(model, i, p): return model.m[i] >= sum( model.b[p, j] * X[i][j] for j in column_index) - (1 - model.s[i, p]) * self.M model.MinGT = Constraint(row_index, piece_index, rule=MinGTRule) # def SOS1Rule(model, i): # return sum(model.s[i, p] for p in piece_index) == 1 # model.SOS1 = Constraint(row_index, rule=SOS1Rule) # ===== # Alternative: model.SOS1 = SOSConstraint(row_index, var=model.s, index=Set(piece_index), sos=1) model.lg = Constraint( row_index, rule=lambda model, i: sum(model.s[i, p] for p in piece_index) >= 1) def TConstraintRule(model, i): return model.t[i] == y[i] - model.m[i] model.TConstraint = Constraint(row_index, rule=TConstraintRule) # Maintain the order of the pieces so there might be # no duplicates def OrderConstraintRule(model, p): return model.b[p, 0] <= model.b[p + 1, 0] model.OrderConstraint = Constraint(list(range(self.n_pieces - 1)), rule=OrderConstraintRule) model.obj = Objective(expr=(1 / N_rows) * sum(model.t[i] * model.t[i] for i in row_index), sense=minimize) return model