1# ___________________________________________________________________________ 2# 3# Pyomo: Python Optimization Modeling Objects 4# Copyright 2017 National Technology and Engineering Solutions of Sandia, LLC 5# Under the terms of Contract DE-NA0003525 with National Technology and 6# Engineering Solutions of Sandia, LLC, the U.S. Government retains certain 7# rights in this software. 8# This software is distributed under the 3-clause BSD License. 9# ___________________________________________________________________________ 10# 11# Unit Tests for Elements of a Model 12# 13# Test Class to test the Model class 14# 15 16import json 17import os 18from os.path import abspath, dirname, join 19currdir = dirname(abspath(__file__)) 20import pickle 21 22from filecmp import cmp 23import pyomo.common.unittest as unittest 24 25from pyomo.common.dependencies import yaml_available 26from pyomo.common.tempfiles import TempfileManager 27from pyomo.core.expr import current as EXPR 28from pyomo.environ import RangeSet, ConcreteModel, Var, Param, Block, AbstractModel, Set, Constraint, Objective, value, sum_product, SolverFactory, VarList, ObjectiveList, ConstraintList 29from pyomo.opt import check_available_solvers 30from pyomo.opt.parallel.local import SolverManager_Serial 31 32if yaml_available: 33 import yaml 34 35solvers = check_available_solvers('glpk') 36 37class Test(unittest.TestCase): 38 39 def tearDown(self): 40 if os.path.exists("unknown.lp"): 41 os.unlink("unknown.lp") 42 TempfileManager.clear_tempfiles() 43 44 45 def test_clone_concrete_model(self): 46 def _populate(b, *args): 47 b.A = RangeSet(1,3) 48 b.v = Var() 49 b.vv = Var(m.A) 50 b.p = Param() 51 52 m = ConcreteModel() 53 _populate(m) 54 m.b = Block() 55 _populate(m.b) 56 m.b.c = Block() 57 _populate(m.b.c) 58 m.bb = Block(m.A, rule=_populate) 59 60 n = m.clone() 61 self.assertNotEqual(id(m), id(n)) 62 63 self.assertEqual(id(m), id(m.b.parent_block())) 64 self.assertEqual(id(m), id(m.bb.parent_block())) 65 self.assertEqual(id(m), id(m.bb[1].parent_block())) 66 self.assertEqual(id(m), id(m.bb[2].parent_block())) 67 self.assertEqual(id(m), id(m.bb[3].parent_block())) 68 69 self.assertEqual(id(n), id(n.b.parent_block())) 70 self.assertEqual(id(n), id(n.bb.parent_block())) 71 self.assertEqual(id(n), id(n.bb[1].parent_block())) 72 self.assertEqual(id(n), id(n.bb[2].parent_block())) 73 self.assertEqual(id(n), id(n.bb[3].parent_block())) 74 75 for x,y in ((m, n), (m.b, n.b), (m.b.c, n.b.c), (m.bb[2], n.bb[2])): 76 self.assertNotEqual(id(x), id(y)) 77 self.assertNotEqual(id(x.parent_block()), id(x)) 78 self.assertNotEqual(id(y.parent_block()), id(y)) 79 80 self.assertEqual(id(x.A.parent_block()), id(x)) 81 self.assertEqual(id(x.v.parent_block()), id(x)) 82 self.assertEqual(id(x.vv.parent_block()), id(x)) 83 self.assertEqual(id(x.vv[1].parent_block()), id(x)) 84 self.assertEqual(id(x.p.parent_block()), id(x)) 85 86 self.assertEqual(id(y.A.parent_block()), id(y)) 87 self.assertEqual(id(y.v.parent_block()), id(y)) 88 self.assertEqual(id(y.vv.parent_block()), id(y)) 89 self.assertEqual(id(y.vv[1].parent_block()), id(y)) 90 self.assertEqual(id(y.p.parent_block()), id(y)) 91 92 def test_clone_abstract_model(self): 93 def _populate(b, *args): 94 b.A = RangeSet(1,3) 95 b.v = Var() 96 b.vv = Var(m.A) 97 b.p = Param() 98 99 m = AbstractModel() 100 _populate(m) 101 m.b = Block() 102 _populate(m.b) 103 m.b.c = Block() 104 _populate(m.b.c) 105 m.bb = Block(m.A, rule=_populate) 106 107 n = m.clone() 108 self.assertNotEqual(id(m), id(n)) 109 110 self.assertEqual(id(m), id(m.b.parent_block())) 111 self.assertEqual(id(m), id(m.bb.parent_block())) 112 113 self.assertEqual(id(n), id(n.b.parent_block())) 114 self.assertEqual(id(n), id(n.bb.parent_block())) 115 116 for x,y in ((m, n), (m.b, n.b), (m.b.c, n.b.c)): 117 self.assertNotEqual(id(x), id(y)) 118 self.assertNotEqual(id(x.parent_block()), id(x)) 119 self.assertNotEqual(id(y.parent_block()), id(y)) 120 121 self.assertEqual(id(x.A.parent_block()), id(x)) 122 self.assertEqual(id(x.v.parent_block()), id(x)) 123 self.assertEqual(id(x.vv.parent_block()), id(x)) 124 self.assertEqual(id(x.p.parent_block()), id(x)) 125 126 self.assertEqual(id(y.A.parent_block()), id(y)) 127 self.assertEqual(id(y.v.parent_block()), id(y)) 128 self.assertEqual(id(y.vv.parent_block()), id(y)) 129 self.assertEqual(id(y.p.parent_block()), id(y)) 130 131 def test_clear_attribute(self): 132 # Test coverage of the _clear_attribute method 133 model = ConcreteModel() 134 obj = Set() 135 model.A = obj 136 self.assertEqual(model.A.local_name, "A") 137 self.assertEqual(obj.local_name, "A") 138 self.assertIs(obj, model.A) 139 140 obj = Var() 141 model.A = obj 142 self.assertEqual(model.A.local_name, "A") 143 self.assertEqual(obj.local_name, "A") 144 self.assertIs(obj, model.A) 145 146 obj = Param() 147 model.A = obj 148 self.assertEqual(model.A.local_name, "A") 149 self.assertEqual(obj.local_name, "A") 150 self.assertIs(obj, model.A) 151 152 obj = Objective() 153 model.A = obj 154 self.assertEqual(model.A.local_name, "A") 155 self.assertEqual(obj.local_name, "A") 156 self.assertIs(obj, model.A) 157 158 obj = Constraint() 159 model.A = obj 160 self.assertEqual(model.A.local_name, "A") 161 self.assertEqual(obj.local_name, "A") 162 self.assertIs(obj, model.A) 163 164 obj = Set() 165 model.A = obj 166 self.assertEqual(model.A.local_name, "A") 167 self.assertEqual(obj.local_name, "A") 168 self.assertIs(obj, model.A) 169 170 def test_set_attr(self): 171 model = ConcreteModel() 172 model.x = Param(mutable=True) 173 model.x = 5 174 self.assertEqual(value(model.x), 5) 175 model.x = 6 176 self.assertEqual(value(model.x), 6) 177 model.x = None 178 self.assertEqual(model.x._value, None) 179 180 def test_write(self): 181 model = ConcreteModel() 182 model.A = RangeSet(1,4) 183 model.x = Var(model.A, bounds=(-1,1)) 184 def obj_rule(model): 185 return sum_product(model.x) 186 model.obj = Objective(rule=obj_rule) 187 model.write() 188 189 def test_write2(self): 190 model = ConcreteModel() 191 model.A = RangeSet(1,4) 192 model.x = Var(model.A, bounds=(-1,1)) 193 def obj_rule(model): 194 return sum_product(model.x) 195 model.obj = Objective(rule=obj_rule) 196 def c_rule(model): 197 return (1, model.x[1]+model.x[2], 2) 198 model.c = Constraint(rule=c_rule) 199 model.write() 200 201 def test_write3(self): 202 # Test that the summation works correctly, even though param 'w' has a default value 203 model = ConcreteModel() 204 model.J = RangeSet(1,4) 205 model.w=Param(model.J, default=4) 206 model.x=Var(model.J, initialize=3) 207 def obj_rule(instance): 208 return sum_product(instance.w, instance.x) 209 model.obj = Objective(rule=obj_rule) 210 self.assertEqual( value(model.obj), 48 ) 211 212 @unittest.skipIf('glpk' not in solvers, "glpk solver is not available") 213 def test_solve1(self): 214 model = ConcreteModel() 215 model.A = RangeSet(1,4) 216 model.x = Var(model.A, bounds=(-1,1)) 217 def obj_rule(model): 218 return sum_product(model.x) 219 model.obj = Objective(rule=obj_rule) 220 def c_rule(model): 221 expr = 0 222 for i in model.A: 223 expr += i*model.x[i] 224 return expr == 0 225 model.c = Constraint(rule=c_rule) 226 opt = SolverFactory('glpk') 227 results = opt.solve(model, symbolic_solver_labels=True) 228 model.solutions.store_to(results) 229 results.write(filename=join(currdir,"solve1.out"), format='json') 230 with open(join(currdir,"solve1.out"), 'r') as out, \ 231 open(join(currdir,"solve1.txt"), 'r') as txt: 232 self.assertStructuredAlmostEqual(json.load(txt), json.load(out), 233 abstol=1e-4, 234 allow_second_superset=True) 235 # 236 def d_rule(model): 237 return model.x[1] >= 0 238 model.d = Constraint(rule=d_rule) 239 model.d.deactivate() 240 results = opt.solve(model) 241 model.solutions.store_to(results) 242 results.write(filename=join(currdir,"solve1x.out"), format='json') 243 with open(join(currdir,"solve1x.out"), 'r') as out, \ 244 open(join(currdir,"solve1.txt"), 'r') as txt: 245 self.assertStructuredAlmostEqual(json.load(txt), json.load(out), 246 abstol=1e-4, 247 allow_second_superset=True) 248 # 249 model.d.activate() 250 results = opt.solve(model) 251 model.solutions.store_to(results) 252 results.write(filename=join(currdir,"solve1a.out"), format='json') 253 with open(join(currdir,"solve1a.out"), 'r') as out, \ 254 open(join(currdir,"solve1a.txt"), 'r') as txt: 255 self.assertStructuredAlmostEqual(json.load(txt), json.load(out), 256 abstol=1e-4, 257 allow_second_superset=True) 258 # 259 model.d.deactivate() 260 def e_rule(model, i): 261 return model.x[i] >= 0 262 model.e = Constraint(model.A, rule=e_rule) 263 for i in model.A: 264 model.e[i].deactivate() 265 results = opt.solve(model) 266 model.solutions.store_to(results) 267 results.write(filename=join(currdir,"solve1y.out"), format='json') 268 with open(join(currdir,"solve1y.out"), 'r') as out, \ 269 open(join(currdir,"solve1.txt"), 'r') as txt: 270 self.assertStructuredAlmostEqual(json.load(txt), json.load(out), 271 abstol=1e-4, 272 allow_second_superset=True) 273 # 274 model.e.activate() 275 results = opt.solve(model) 276 model.solutions.store_to(results) 277 results.write(filename=join(currdir,"solve1b.out"), format='json') 278 with open(join(currdir,"solve1b.out"), 'r') as out, \ 279 open(join(currdir,"solve1b.txt"), 'r') as txt: 280 self.assertStructuredAlmostEqual(json.load(txt), json.load(out), 281 abstol=1e-4, 282 allow_second_superset=True) 283 284 @unittest.skipIf('glpk' not in solvers, "glpk solver is not available") 285 def test_store_to_skip_stale_vars(self): 286 # test store_to() function with skip_stale_vars=True 287 model = ConcreteModel() 288 model.A = RangeSet(1,4) 289 model.x = Var(model.A, bounds=(-1,1)) 290 def obj_rule(model): 291 return sum_product(model.x) 292 model.obj = Objective(rule=obj_rule) 293 def c_rule(model): 294 expr = 0 295 for i in model.A: 296 expr += i*model.x[i] 297 return expr == 0 298 model.c = Constraint(rule=c_rule) 299 opt = SolverFactory('glpk') 300 results = opt.solve(model, symbolic_solver_labels=True) 301 model.x[1].fix() 302 results = opt.solve(model, symbolic_solver_labels=True) 303 model.solutions.store_to(results,skip_stale_vars=False) 304 for index in model.A: 305 self.assertIn(model.x[index].getname(), results.solution.variable.keys()) 306 model.solutions.store_to(results,skip_stale_vars=True) 307 for index in model.A: 308 if index == 1: 309 self.assertNotIn(model.x[index].getname(), results.solution.variable.keys()) 310 else: 311 self.assertIn(model.x[index].getname(), results.solution.variable.keys()) 312 313 314 def test_display(self): 315 model = ConcreteModel() 316 model.A = RangeSet(1,4) 317 model.x = Var(model.A, bounds=(-1,1)) 318 def obj_rule(model): 319 expr = 0 320 for i in model.A: 321 expr += model.x[i] 322 return expr 323 model.obj = Objective(rule=obj_rule) 324 model.display(join(currdir,"solve3.out")) 325 _out, _txt = join(currdir,"solve3.out"), join(currdir,"solve3.txt") 326 self.assertTrue(cmp(_out, _txt), 327 msg="Files %s and %s differ" % (_txt, _out)) 328 329 @unittest.skipIf('glpk' not in solvers, "glpk solver is not available") 330 def test_solve4(self): 331 model = ConcreteModel() 332 model.A = RangeSet(1,4) 333 model.x = Var(model.A, bounds=(-1,1)) 334 def obj_rule(model): 335 return sum_product(model.x) 336 model.obj = Objective(rule=obj_rule) 337 def c_rule(model): 338 expr = 0 339 for i in model.A: 340 expr += i*model.x[i] 341 return expr == 0 342 model.c = Constraint(rule=c_rule) 343 opt = SolverFactory('glpk') 344 results = opt.solve(model, symbolic_solver_labels=True) 345 model.solutions.store_to(results) 346 results.write(filename=join(currdir,'solve4.out'), format='json') 347 with open(join(currdir,"solve4.out"), 'r') as out, \ 348 open(join(currdir,"solve1.txt"), 'r') as txt: 349 self.assertStructuredAlmostEqual(json.load(txt), json.load(out), 350 abstol=1e-4, 351 allow_second_superset=True) 352 353 @unittest.skipIf('glpk' not in solvers, "glpk solver is not available") 354 def test_solve6(self): 355 # 356 # Test that solution values have complete block names: 357 # b.obj 358 # b.x 359 # 360 model = ConcreteModel() 361 model.y = Var(bounds=(-1,1)) 362 model.b = Block() 363 model.b.A = RangeSet(1,4) 364 model.b.x = Var(model.b.A, bounds=(-1,1)) 365 def obj_rule(block): 366 return sum_product(block.x) 367 model.b.obj = Objective(rule=obj_rule) 368 def c_rule(model): 369 expr = model.y 370 for i in model.b.A: 371 expr += i*model.b.x[i] 372 return expr == 0 373 model.c = Constraint(rule=c_rule) 374 opt = SolverFactory('glpk') 375 results = opt.solve(model, symbolic_solver_labels=True) 376 model.solutions.store_to(results) 377 results.write(filename=join(currdir,'solve6.out'), format='json') 378 with open(join(currdir,"solve6.out"), 'r') as out, \ 379 open(join(currdir,"solve6.txt"), 'r') as txt: 380 self.assertStructuredAlmostEqual(json.load(txt), json.load(out), 381 abstol=1e-4, 382 allow_second_superset=True) 383 384 @unittest.skipIf('glpk' not in solvers, "glpk solver is not available") 385 def test_solve7(self): 386 # 387 # Test that solution values are writen with appropriate 388 # quotations in results 389 # 390 model = ConcreteModel() 391 model.y = Var(bounds=(-1,1)) 392 model.A = RangeSet(1,4) 393 model.B = Set(initialize=['A B', 'C,D', 'E']) 394 model.x = Var(model.A, model.B, bounds=(-1,1)) 395 def obj_rule(model): 396 return sum_product(model.x) 397 model.obj = Objective(rule=obj_rule) 398 def c_rule(model): 399 expr = model.y 400 for i in model.A: 401 for j in model.B: 402 expr += i*model.x[i,j] 403 return expr == 0 404 model.c = Constraint(rule=c_rule) 405 opt = SolverFactory('glpk') 406 results = opt.solve(model, symbolic_solver_labels=True) 407 #model.display() 408 model.solutions.store_to(results) 409 results.write(filename=join(currdir,'solve7.out'), format='json') 410 with open(join(currdir,"solve7.out"), 'r') as out, \ 411 open(join(currdir,"solve7.txt"), 'r') as txt: 412 self.assertStructuredAlmostEqual(json.load(txt), json.load(out), 413 abstol=1e-4, 414 allow_second_superset=True) 415 416 def test_stats1(self): 417 model = ConcreteModel() 418 model.x = Var([1,2]) 419 def obj_rule(model, i): 420 return sum_product(model.x) 421 model.obj = Objective([1,2], rule=obj_rule) 422 def c_rule(model, i): 423 expr = 0 424 for j in [1,2]: 425 expr += j*model.x[j] 426 return expr == 0 427 model.c = Constraint([1,2], rule=c_rule) 428 self.assertEqual(model.nvariables(), 2) 429 self.assertEqual(model.nobjectives(), 2) 430 self.assertEqual(model.nconstraints(), 2) 431 432 def test_stats2(self): 433 model = ConcreteModel() 434 # 435 model.x = Var([1,2]) 436 def obj_rule(model, i): 437 return sum_product(model.x) 438 model.y = VarList() 439 model.y.add() 440 model.y.add() 441 # 442 model.obj = Objective([1,2], rule=obj_rule) 443 model.o = ObjectiveList() 444 model.o.add(model.y[1]) 445 model.o.add(model.y[2]) 446 # 447 def c_rule(model, i): 448 expr = 0 449 for j in [1,2]: 450 expr += j*model.x[j] 451 return expr == 0 452 model.c = Constraint([1,2], rule=c_rule) 453 model.C = ConstraintList() 454 model.C.add(model.y[1] == 0) 455 model.C.add(model.y[2] == 0) 456 # 457 self.assertEqual(model.nvariables(), 4) 458 self.assertEqual(model.nobjectives(), 4) 459 self.assertEqual(model.nconstraints(), 4) 460 461 def test_stats3(self): 462 model = ConcreteModel() 463 model.x = Var([1,2]) 464 def obj_rule(model, i): 465 return sum_product(model.x) 466 model.obj = Objective([1,2], rule=obj_rule) 467 def c_rule(model, i): 468 expr = 0 469 for j in [1,2]: 470 expr += j*model.x[j] 471 return expr == 0 472 model.c = Constraint([1,2], rule=c_rule) 473 # 474 model.B = Block() 475 model.B.x = Var([1,2]) 476 model.B.o = ObjectiveList() 477 model.B.o.add(model.B.x[1]) 478 model.B.o.add(model.B.x[2]) 479 model.B.c = ConstraintList() 480 model.B.c.add(model.x[1] == 0) 481 model.B.c.add(model.x[2] == 0) 482 self.assertEqual(model.nvariables(), 4) 483 self.assertEqual(model.nobjectives(), 4) 484 self.assertEqual(model.nconstraints(), 4) 485 486 def test_stats4(self): 487 model = ConcreteModel() 488 model.x = Var([1]) 489 490 model.B = Block() 491 model.B.x = Var([1, 2, 3]) 492 model.B.o = ObjectiveList() 493 model.B.o.add(model.B.x[1]) 494 model.B.c = ConstraintList() 495 model.B.c.add(model.B.x[1] == 0) 496 model.B.c.add(model.B.x[2] == 0) 497 model.B.c.add(model.B.x[3] == 0) 498 self.assertEqual(model.nvariables(), 4) 499 self.assertEqual(model.nobjectives(), 1) 500 self.assertEqual(model.nconstraints(), 3) 501 model.clear() 502 self.assertEqual(model.nvariables(), 0) 503 self.assertEqual(model.nobjectives(), 0) 504 self.assertEqual(model.nconstraints(), 0) 505 506 @unittest.skipIf('glpk' not in solvers, "glpk solver is not available") 507 def test_solve_with_pickle(self): 508 model = ConcreteModel() 509 model.A = RangeSet(1,4) 510 model.b = Block() 511 model.b.x = Var(model.A, bounds=(-1,1)) 512 model.b.obj = Objective(expr=sum_product(model.b.x)) 513 model.c = Constraint(expr=model.b.x[1] >= 0) 514 opt = SolverFactory('glpk') 515 self.assertEqual(len(model.solutions), 0) 516 results = opt.solve(model, symbolic_solver_labels=True) 517 self.assertEqual(len(model.solutions), 1) 518 # 519 self.assertEqual(model.solutions[0].gap, 0.0) 520 #self.assertEqual(model.solutions[0].status, SolutionStatus.feasible) 521 self.assertEqual(model.solutions[0].message, None) 522 # 523 buf = pickle.dumps(model) 524 tmodel = pickle.loads(buf) 525 self.assertEqual(len(tmodel.solutions), 1) 526 self.assertEqual(tmodel.solutions[0].gap, 0.0) 527 #self.assertEqual(tmodel.solutions[0].status, SolutionStatus.feasible) 528 self.assertEqual(tmodel.solutions[0].message, None) 529 530 @unittest.skipIf('glpk' not in solvers, "glpk solver is not available") 531 def test_solve_with_pickle_then_clone(self): 532 # This tests github issue Pyomo-#65 533 model = ConcreteModel() 534 model.A = RangeSet(1,4) 535 model.b = Block() 536 model.b.x = Var(model.A, bounds=(-1,1)) 537 model.b.obj = Objective(expr=sum_product(model.b.x)) 538 model.c = Constraint(expr=model.b.x[1] >= 0) 539 opt = SolverFactory('glpk') 540 self.assertEqual(len(model.solutions), 0) 541 results = opt.solve(model, symbolic_solver_labels=True) 542 self.assertEqual(len(model.solutions), 1) 543 # 544 self.assertEqual(model.solutions[0].gap, 0.0) 545 #self.assertEqual(model.solutions[0].status, SolutionStatus.feasible) 546 self.assertEqual(model.solutions[0].message, None) 547 # 548 buf = pickle.dumps(model) 549 tmodel = pickle.loads(buf) 550 self.assertEqual(len(tmodel.solutions), 1) 551 self.assertEqual(tmodel.solutions[0].gap, 0.0) 552 #self.assertEqual(tmodel.solutions[0].status, SolutionStatus.feasible) 553 self.assertEqual(tmodel.solutions[0].message, None) 554 self.assertIn(id(tmodel.b.obj), tmodel.solutions[0]._entry['objective']) 555 self.assertIs( 556 tmodel.b.obj, 557 tmodel.solutions[0]._entry['objective'][id(tmodel.b.obj)][0]() ) 558 559 inst = tmodel.clone() 560 561 # make sure the clone has all the attributes 562 self.assertTrue(hasattr(inst,'A')) 563 self.assertTrue(hasattr(inst,'b')) 564 self.assertTrue(hasattr(inst.b,'x')) 565 self.assertTrue(hasattr(inst.b,'obj')) 566 self.assertTrue(hasattr(inst,'c')) 567 # and that they were all copied 568 self.assertIsNot(inst.A, tmodel.A) 569 self.assertIsNot(inst.b, tmodel.b) 570 self.assertIsNot(inst.b.x, tmodel.b.x) 571 self.assertIsNot(inst.b.obj, tmodel.b.obj) 572 self.assertIsNot(inst.c, tmodel.c) 573 574 # Make sure the solution is on the new model 575 self.assertTrue(hasattr(inst,'solutions')) 576 self.assertEqual(len(inst.solutions), 1) 577 self.assertEqual(inst.solutions[0].gap, 0.0) 578 #self.assertEqual(inst.solutions[0].status, SolutionStatus.feasible) 579 self.assertEqual(inst.solutions[0].message, None) 580 581 # Spot-check some components and make sure all the weakrefs in 582 # the ModelSOlution got updated 583 self.assertIn(id(inst.b.obj), inst.solutions[0]._entry['objective']) 584 _obj = inst.solutions[0]._entry['objective'][id(inst.b.obj)] 585 self.assertIs(_obj[0](), inst.b.obj) 586 587 for v in [1,2,3,4]: 588 self.assertIn(id(inst.b.x[v]), inst.solutions[0]._entry['variable']) 589 _v = inst.solutions[0]._entry['variable'][id(inst.b.x[v])] 590 self.assertIs(_v[0](), inst.b.x[v]) 591 592 @unittest.skipIf('glpk' not in solvers, "glpk solver is not available") 593 @unittest.skipIf(not yaml_available, "YAML not available available") 594 def test_solve_with_store1(self): 595 # With symbolic solver labels 596 model = ConcreteModel() 597 model.A = RangeSet(1,4) 598 model.b = Block() 599 model.b.x = Var(model.A, bounds=(-1,1)) 600 model.b.obj = Objective(expr=sum_product(model.b.x)) 601 model.c = Constraint(expr=model.b.x[1] >= 0) 602 opt = SolverFactory('glpk') 603 results = opt.solve(model, symbolic_solver_labels=True) 604 # 605 results.write(filename=join(currdir,'solve_with_store1.out'), 606 format='yaml') 607 with open(join(currdir,"solve_with_store1.out"), 'r') as out, \ 608 open(join(currdir,"solve_with_store1.txt"), 'r') as txt: 609 self.assertStructuredAlmostEqual(yaml.full_load(txt), 610 yaml.full_load(out), 611 allow_second_superset=True) 612 model.solutions.store_to(results) 613 # 614 results.write(filename=join(currdir,'solve_with_store2.out'), 615 format='yaml') 616 with open(join(currdir,"solve_with_store2.out"), 'r') as out, \ 617 open(join(currdir,"solve_with_store2.txt"), 'r') as txt: 618 self.assertStructuredAlmostEqual(yaml.full_load(txt), 619 yaml.full_load(out), 620 allow_second_superset=True) 621 # 622 # Load results with string indices 623 # 624 tmodel = ConcreteModel() 625 tmodel.A = RangeSet(1,4) 626 tmodel.b = Block() 627 tmodel.b.x = Var(tmodel.A, bounds=(-1,1)) 628 tmodel.b.obj = Objective(expr=sum_product(tmodel.b.x)) 629 tmodel.c = Constraint(expr=tmodel.b.x[1] >= 0) 630 self.assertEqual(len(tmodel.solutions), 0) 631 tmodel.solutions.load_from(results) 632 self.assertEqual(len(tmodel.solutions), 1) 633 634 @unittest.skipIf('glpk' not in solvers, "glpk solver is not available") 635 @unittest.skipIf(not yaml_available, "YAML not available available") 636 def test_solve_with_store2(self): 637 # Without symbolic solver labels 638 model = ConcreteModel() 639 model.A = RangeSet(1,4) 640 model.b = Block() 641 model.b.x = Var(model.A, bounds=(-1,1)) 642 model.b.obj = Objective(expr=sum_product(model.b.x)) 643 model.c = Constraint(expr=model.b.x[1] >= 0) 644 opt = SolverFactory('glpk') 645 results = opt.solve(model, symbolic_solver_labels=False) 646 # 647 results.write(filename=join(currdir,'solve_with_store1.out'), 648 format='yaml') 649 with open(join(currdir,"solve_with_store1.out"), 'r') as out, \ 650 open(join(currdir,"solve_with_store1.txt"), 'r') as txt: 651 self.assertStructuredAlmostEqual(yaml.full_load(txt), 652 yaml.full_load(out), 653 allow_second_superset=True) 654 model.solutions.store_to(results) 655 # 656 results.write(filename=join(currdir,'solve_with_store2.out'), 657 format='yaml') 658 with open(join(currdir,"solve_with_store2.out"), 'r') as out, \ 659 open(join(currdir,"solve_with_store2.txt"), 'r') as txt: 660 self.assertStructuredAlmostEqual(yaml.full_load(txt), 661 yaml.full_load(out), 662 allow_second_superset=True) 663 # 664 # Load results with string indices 665 # 666 tmodel = ConcreteModel() 667 tmodel.A = RangeSet(1,4) 668 tmodel.b = Block() 669 tmodel.b.x = Var(tmodel.A, bounds=(-1,1)) 670 tmodel.b.obj = Objective(expr=sum_product(tmodel.b.x)) 671 tmodel.c = Constraint(expr=tmodel.b.x[1] >= 0) 672 self.assertEqual(len(tmodel.solutions), 0) 673 tmodel.solutions.load_from(results) 674 self.assertEqual(len(tmodel.solutions), 1) 675 676 @unittest.skipIf('glpk' not in solvers, "glpk solver is not available") 677 @unittest.skipIf(not yaml_available, "YAML not available available") 678 def test_solve_with_store2(self): 679 model = ConcreteModel() 680 model.A = RangeSet(1,4) 681 model.b = Block() 682 model.b.x = Var(model.A, bounds=(-1,1)) 683 model.b.obj = Objective(expr=sum_product(model.b.x)) 684 model.c = Constraint(expr=model.b.x[1] >= 0) 685 opt = SolverFactory('glpk') 686 results = opt.solve(model) 687 # 688 results.write(filename=join(currdir,'solve_with_store3.out'), 689 format='json') 690 with open(join(currdir,"solve_with_store3.out"), 'r') as out, \ 691 open(join(currdir,"solve_with_store3.txt"), 'r') as txt: 692 self.assertStructuredAlmostEqual(yaml.full_load(txt), 693 yaml.full_load(out), 694 allow_second_superset=True) 695 # 696 model.solutions.store_to(results) 697 results.write(filename=join(currdir,'solve_with_store4.out'), 698 format='json') 699 with open(join(currdir,"solve_with_store4.out"), 'r') as out, \ 700 open(join(currdir,"solve_with_store4.txt"), 'r') as txt: 701 self.assertStructuredAlmostEqual(yaml.full_load(txt), 702 yaml.full_load(out), 703 allow_second_superset=True) 704 # 705 # Test that we can pickle the results object 706 # 707 buf = pickle.dumps(results) 708 results_ = pickle.loads(buf) 709 results.write(filename=join(currdir,'solve_with_store4.out'), 710 format='json') 711 with open(join(currdir,"solve_with_store4.out"), 'r') as out, \ 712 open(join(currdir,"solve_with_store4.txt"), 'r') as txt: 713 self.assertStructuredAlmostEqual(yaml.full_load(txt), 714 yaml.full_load(out), 715 allow_second_superset=True) 716 # 717 # Load results with string indices 718 # 719 tmodel = ConcreteModel() 720 tmodel.A = RangeSet(1,3) 721 tmodel.b = Block() 722 tmodel.b.x = Var(tmodel.A, bounds=(-1,1)) 723 tmodel.b.obj = Objective(expr=sum_product(tmodel.b.x)) 724 tmodel.c = Constraint(expr=tmodel.b.x[1] >= 0) 725 self.assertEqual(len(tmodel.solutions), 0) 726 tmodel.solutions.load_from(results, ignore_invalid_labels=True) 727 self.assertEqual(len(tmodel.solutions), 1) 728 729 @unittest.skipIf('glpk' not in solvers, "glpk solver is not available") 730 @unittest.skipIf(not yaml_available, "YAML not available available") 731 def test_solve_with_store3(self): 732 model = ConcreteModel() 733 model.A = RangeSet(1,4) 734 model.b = Block() 735 model.b.x = Var(model.A, bounds=(-1,1)) 736 model.b.obj = Objective(expr=sum_product(model.b.x)) 737 model.c = Constraint(expr=model.b.x[1] >= 0) 738 opt = SolverFactory('glpk') 739 results = opt.solve(model) 740 # 741 model.solutions.store_to(results) 742 results.write(filename=join(currdir,'solve_with_store5.out'), 743 format='json') 744 with open(join(currdir,"solve_with_store5.out"), 'r') as out, \ 745 open(join(currdir,"solve_with_store4.txt"), 'r') as txt: 746 self.assertStructuredAlmostEqual(yaml.full_load(txt), 747 yaml.full_load(out), 748 allow_second_superset=True) 749 # 750 model.solutions.store_to(results, cuid=True) 751 buf = pickle.dumps(results) 752 results_ = pickle.loads(buf) 753 model.solutions.load_from(results_) 754 model.solutions.store_to(results_) 755 results_.write(filename=join(currdir,'solve_with_store6.out'), 756 format='json') 757 with open(join(currdir,"solve_with_store6.out"), 'r') as out, \ 758 open(join(currdir,"solve_with_store4.txt"), 'r') as txt: 759 self.assertStructuredAlmostEqual(yaml.full_load(txt), 760 yaml.full_load(out), 761 allow_second_superset=True) 762 # 763 # Load results with string indices 764 # 765 tmodel = ConcreteModel() 766 tmodel.A = RangeSet(1,4) 767 tmodel.b = Block() 768 tmodel.b.x = Var(tmodel.A, bounds=(-1,1)) 769 tmodel.b.obj = Objective(expr=sum_product(tmodel.b.x)) 770 tmodel.c = Constraint(expr=tmodel.b.x[1] >= 0) 771 self.assertEqual(len(tmodel.solutions), 0) 772 tmodel.solutions.load_from(results) 773 self.assertEqual(len(tmodel.solutions), 1) 774 tmodel.solutions.store_to(results) 775 results.write(filename=join(currdir,'solve_with_store7.out'), 776 format='json') 777 with open(join(currdir,"solve_with_store7.out"), 'r') as out, \ 778 open(join(currdir,"solve_with_store4.txt"), 'r') as txt: 779 self.assertStructuredAlmostEqual(yaml.full_load(txt), 780 yaml.full_load(out), 781 allow_second_superset=True) 782 783 @unittest.skipIf('glpk' not in solvers, "glpk solver is not available") 784 @unittest.skipIf(not yaml_available, "YAML not available available") 785 def test_solve_with_store4(self): 786 model = ConcreteModel() 787 model.A = RangeSet(1,4) 788 model.b = Block() 789 model.b.x = Var(model.A, bounds=(-1,1)) 790 model.b.obj = Objective(expr=sum_product(model.b.x)) 791 model.c = Constraint(expr=model.b.x[1] >= 0) 792 opt = SolverFactory('glpk') 793 results = opt.solve(model, load_solutions=False) 794 self.assertEqual(len(model.solutions), 0) 795 self.assertEqual(len(results.solution), 1) 796 model.solutions.load_from(results) 797 self.assertEqual(len(model.solutions), 1) 798 self.assertEqual(len(results.solution), 1) 799 # 800 model.solutions.store_to(results) 801 results.write(filename=join(currdir,'solve_with_store8.out'), 802 format='json') 803 with open(join(currdir,"solve_with_store8.out"), 'r') as out, \ 804 open(join(currdir,"solve_with_store4.txt"), 'r') as txt: 805 self.assertStructuredAlmostEqual(yaml.full_load(txt), 806 yaml.full_load(out), 807 allow_second_superset=True) 808 809 @unittest.skipIf('glpk' not in solvers, "glpk solver is not available") 810 @unittest.skipIf(not yaml_available, "YAML not available available") 811 def test_solve_with_store5(self): 812 model = ConcreteModel() 813 model.A = RangeSet(1,4) 814 model.b = Block() 815 model.b.x = Var(model.A, bounds=(-1,1)) 816 model.b.obj = Objective(expr=sum_product(model.b.x)) 817 model.c = Constraint(expr=model.b.x[1] >= 0) 818 819 smanager = SolverManager_Serial() 820 ah = smanager.queue(model, solver='glpk', load_solutions=False) 821 results = smanager.wait_for(ah) 822 self.assertEqual(len(model.solutions), 0) 823 self.assertEqual(len(results.solution), 1) 824 model.solutions.load_from(results) 825 self.assertEqual(len(model.solutions), 1) 826 self.assertEqual(len(results.solution), 1) 827 # 828 model.solutions.store_to(results) 829 results.write(filename=join(currdir,'solve_with_store8.out'), 830 format='json') 831 with open(join(currdir,"solve_with_store8.out"), 'r') as out, \ 832 open(join(currdir,"solve_with_store4.txt"), 'r') as txt: 833 self.assertStructuredAlmostEqual(yaml.full_load(txt), 834 yaml.full_load(out), 835 allow_second_superset=True) 836 837 838 def test_create_concrete_from_rule(self): 839 def make(m): 840 m.I = RangeSet(3) 841 m.x = Var(m.I) 842 m.c = Constraint( expr=sum(m.x[i] for i in m.I) >= 0 ) 843 model = ConcreteModel(rule=make) 844 self.assertEqual( [x.local_name for x in model.component_objects()], 845 ['I','x','c'] ) 846 self.assertEqual( len(list(EXPR.identify_variables(model.c.body))), 3 ) 847 848 849 def test_create_abstract_from_rule(self): 850 def make_invalid(m): 851 m.I = RangeSet(3) 852 m.x = Var(m.I) 853 m.c = Constraint( expr=sum(m.x[i] for i in m.I) >= 0 ) 854 855 def make(m): 856 m.I = RangeSet(3) 857 m.x = Var(m.I) 858 def c(b): 859 return sum(m.x[i] for i in m.I) >= 0 860 m.c = Constraint( rule=c ) 861 862 with self.assertRaisesRegex( 863 ValueError, r'x\[1\]: The component has not been constructed.'): 864 model = AbstractModel(rule=make_invalid) 865 instance = model.create_instance() 866 867 model = AbstractModel(rule=make) 868 instance = model.create_instance() 869 self.assertEqual( [x.local_name for x in model.component_objects()], 870 [] ) 871 self.assertEqual( [x.local_name for x in instance.component_objects()], 872 ['I','x','c'] ) 873 self.assertEqual( len(list(EXPR.identify_variables(instance.c.body))), 3 ) 874 875 model = AbstractModel(rule=make) 876 model.y = Var() 877 instance = model.create_instance() 878 self.assertEqual( [x.local_name for x in instance.component_objects()], 879 ['y','I','x','c'] ) 880 self.assertEqual( len(list(EXPR.identify_variables(instance.c.body))), 3 ) 881 882 def test_error1(self): 883 model = ConcreteModel() 884 model.x = Var() 885 instance = model.create_instance() 886 887if __name__ == "__main__": 888 unittest.main() 889 890