def test_errant_grouped_terms(self): with self.assertRaises(ValueError): _ = SlcTerm([Term(c=i + 2, indices=[i % 2]) for i in range(3)], c=1) with self.assertRaises(ValueError): _ = SlcTerm([Term(c=i + 1, indices=[i, i + 1]) for i in range(2)], c=1) with self.assertRaises(ValueError): _ = SlcTerm([Term(c=i, indices=[]) for i in range(1, 3)], c=1)
def add_slc_term( self, terms: Union[List[Tuple[Union[int, float], Optional[int]]], List[Term]], c: Union[int, float] = 1 ): """Adds a squared linear combination term to the `Problem` representation. Helper function to construct terms list. :param terms: List of monomial terms, with each represented by a pair. The first entry represents the monomial term weight. The second entry is the monomial term variable index or None. Alternatively, a list of Term objects may be input. :param c: Weight of SLC term """ if all(isinstance(term, Term) for term in terms): gterms = terms else: gterms = [Term([index], c=tc) if index is not None else Term([], c=tc) for tc,index in terms] self.terms_slc.append( SlcTerm(gterms, c=c) ) self.problem_type_to_grouped() self.uploaded_blob_uri = None
def create_problem( self, name: str, init: bool = False, problem_type: ProblemType = ProblemType.pubo, test_grouped: bool = False, content_type: ContentType = None, ) -> Problem: """Create optimization problem with some default terms :param init: Set initial configuration :type init: bool :return: Optimization problem :rtype: Problem """ terms = [ Term(w=-3, indices=[1, 0]), Term(w=5, indices=[2, 0]), Term(w=9, indices=[2, 1]), Term(w=2, indices=[3, 0]), Term(w=-4, indices=[3, 1]), Term(w=4, indices=[3, 2]), ] if test_grouped: terms.append( SlcTerm(c=1, terms=[Term(c=i + 2, indices=[i]) for i in range(3)])) initial_config = {"1": 0, "0": 1, "2": 0, "3": 1} if init \ else None return Problem(name=name, terms=terms, init_config=initial_config, problem_type=problem_type, content_type=content_type or ContentType.json)
def test_deserialize(self): count = 2 terms = [] for i in range(count): terms.append(Term(c=i, indices=[i, i + 1])) subterms = [Term(c=1, indices=[i]) for i in range(3)] subterms.append(Term(c=-2, indices=[])) terms.append(SlcTerm(subterms, c=1)) problem = Problem(name="test", terms=terms) deserialized = Problem.deserialize(problem.serialize(), problem.name) self.assertEqual(problem.name, deserialized.name) self.assertEqual(problem.problem_type, deserialized.problem_type) self.assertEqual(count + 1, len(deserialized.terms)) self.assertEqual(problem.init_config, deserialized.init_config) self.assertEqual(Term(c=0, indices=[0, 1]), problem.terms[0]) self.assertEqual(Term(c=1, indices=[1, 2]), problem.terms[1]) self.assertEqual(SlcTerm(subterms, c=1), problem.terms_slc[-1])
def test_add_terms_cterms(self): problem = Problem(name="test") count = 4 for i in range(count): problem.add_term(c=i, indices=[i, i + 1]) self.assertEqual(ProblemType.ising, problem.problem_type) self.assertEqual(count, len(problem.terms)) self.assertEqual(Term(c=1, indices=[1, 2]), problem.terms[1]) more = [] for i in range(1, count + 1): more.append(Term(c=i, indices=[i - 1, i])) problem.add_terms(more) self.assertEqual(2 * count, len(problem.terms)) self.assertEqual(Term(c=count, indices=[count - 1, count]), problem.terms[-1]) subterms = [Term(c=1, indices=[i]) for i in range(count)] subterms.append(Term(c=-5, indices=[])) problem.add_slc_term(terms=[(1, i) for i in range(count)] + [(-5, None)], c=2) self.assertEqual(2 * count, len(problem.terms)) self.assertEqual(1, len(problem.terms_slc)) self.assertEqual(SlcTerm(subterms, c=2), problem.terms_slc[-1]) problem.add_terms(subterms, term_type=GroupType.squared_linear_combination, c=2) self.assertEqual(2 * count, len(problem.terms)) self.assertEqual(2, len(problem.terms_slc)) self.assertEqual(SlcTerm(subterms, c=2), problem.terms_slc[-1]) problem.add_terms(subterms, term_type=GroupType.combination, c=0.5) self.assertEqual(3 * count + 1, len(problem.terms)) self.assertEqual( [Term(subterm.ids, c=subterm.c) for subterm in subterms], problem.terms[-len(subterms):]) problem.add_slc_term(subterms, c=3) self.assertEqual(3 * count + 1, len(problem.terms)) self.assertEqual(3, len(problem.terms_slc)) self.assertEqual(SlcTerm(subterms, c=3), problem.terms_slc[-1])
def createFBP_factored(weights: List[int]) -> Problem: # Construct the factored form terms = [ SlcTerm(c=1, terms=[ Term(c=weights[i], indices=[i]) for i in range(len(weights)) ]) ] # Return an Ising-type problem return Problem(name="Freight Balancing Problem", problem_type=ProblemType.ising, terms=terms)
def test_problem_evaluate(self): terms = [] problem = Problem(name="test", terms=terms, problem_type=ProblemType.pubo) self.assertEqual(0, problem.evaluate({})) self.assertEqual(0, problem.evaluate({"0": 1})) terms = [Term(c=10, indices=[0, 1, 2])] problem = Problem(name="test", terms=terms, problem_type=ProblemType.pubo) self.assertEqual(0, problem.evaluate({"0": 0, "1": 1, "2": 1})) self.assertEqual(10, problem.evaluate({"0": 1, "1": 1, "2": 1})) problem = Problem(name="test", terms=terms, problem_type=ProblemType.ising) self.assertEqual(-10, problem.evaluate({"0": -1, "1": 1, "2": 1})) self.assertEqual(10, problem.evaluate({"0": -1, "1": -1, "2": 1})) terms = [Term(c=10, indices=[0, 1, 2]), Term(c=-5, indices=[1, 2])] problem = Problem(name="test", terms=terms, problem_type=ProblemType.pubo) self.assertEqual(-5, problem.evaluate({"0": 0, "1": 1, "2": 1})) self.assertEqual(5, problem.evaluate({"0": 1, "1": 1, "2": 1})) terms = [Term(c=10, indices=[])] # constant term problem = Problem(name="test", terms=terms, problem_type=ProblemType.pubo) self.assertEqual(10, problem.evaluate({})) terms = [ Term(c=2, indices=[0, 1, 2]), SlcTerm(terms=[ Term(c=1, indices=[0]), Term(c=1, indices=[1]), Term(c=1, indices=[2]), Term(c=-5, indices=[]) ], c=3) ] problem = Problem(name="test", terms=terms, problem_type=ProblemType.pubo) self.assertEqual(27, problem.evaluate({"0": 0, "1": 1, "2": 1})) self.assertEqual(14, problem.evaluate({"0": 1, "1": 1, "2": 1}))
def test_serialization_cterms(self): count = 2 terms = [] for i in range(count): terms.append(Term(c=i, indices=[i, i + 1])) terms.append( SlcTerm([ Term(c=0, indices=[0]), Term(c=1, indices=[1]), Term(c=-5, indices=[]) ], c=1)) problem = Problem(name="test", terms=terms) expected = json.dumps({ "metadata": { "name": "test" }, "cost_function": { "version": "1.0", "type": "ising_grouped", "terms": [{ "c": 0, "ids": [0, 1] }, { "c": 1, "ids": [1, 2] }], "terms_slc": [{ "c": 1, "terms": [{ "c": 0, "ids": [0] }, { "c": 1, "ids": [1] }, { "c": -5, "ids": [] }] }] } }) actual = problem.serialize() self.assertEqual(expected, actual)
def test_provide_cterms(self): count = 4 terms = [] for i in range(count): terms.append(Term(c=i, indices=[i, i + 1])) terms.append( SlcTerm([Term(c=i / 2, indices=[i + 2]) for i in range(count)] + [Term(c=5, indices=[])], c=1)) problem = Problem(name="test", terms=terms, problem_type=ProblemType.pubo) self.assertEqual(ProblemType.pubo_grouped, problem.problem_type) self.assertEqual(count, len(problem.terms)) self.assertEqual(1, len(problem.terms_slc)) self.assertEqual(Term(c=1, indices=[1, 2]), problem.terms[1])
def add_terms( self, terms: List[Term], term_type: GroupType=GroupType.combination, c: Union[int, float]=1 ): """Adds an optionally grouped list of monomial terms to the `Problem` representation :param terms: The list of terms to add to the problem :param term_type: Type of grouped term being added If GroupType.combination, terms will be added as ungrouped monomials. :param c: Weight of grouped term, only applicable for grouped terms that support it. """ if term_type is GroupType.combination: # Default type is a group of monomials self.terms += terms else: # Slc term self.terms_slc.append(SlcTerm(terms=terms, c=c)) self.problem_type_to_grouped() self.uploaded_blob_uri = None
def test_problem_large(self): problem = Problem(name="test", terms=[], problem_type=ProblemType.pubo) self.assertTrue(not problem.is_large()) problem.add_term(5.0, []) self.assertTrue(not problem.is_large()) problem.add_term(6.0, list(range(3000))) self.assertTrue(not problem.is_large()) problem.add_terms([Term(indices=[9999], c=1.0)] * int(1e6)) # create 1mil dummy terms self.assertTrue(problem.is_large()) problem = Problem(name="test", terms=[ SlcTerm(terms=[Term(indices=[9999], c=1)], c=1) for i in range(int(1e6)) ], problem_type=ProblemType.pubo) self.assertTrue(not problem.is_large()) problem.add_slc_term([(1.0, i) for i in range(3000)]) self.assertTrue(problem.is_large())
print("variables -> ids:", variable_map) print("\nterms:", terms_list) # Constraints and Penalty Terms # We set penalty to the largest coefficient in the original objective function (although we can go higher than this) # In practice, the penalty value also needs to be tuned. P = 1000 k = -1 # Construct facility constraints for i in range(n): terms_list.append( SlcTerm( c=P, terms=[ Term(c=1, indices=[variable_map[(i, j)]]) for j in range(n) ] + [Term(c=k, indices=[])] #constant k term )) # Construct location constraints for i in range(n): terms_list.append( SlcTerm( c=P, terms=[ Term(c=1, indices=[variable_map[(j, i)]]) for j in range(n) ] + [Term(c=k, indices=[])] #constant k term )) # Construct final problem with all the terms (monomial and slc) problem = Problem(name="Small QAP",
def test_problem_fixed_variables(self): terms = [] problem = Problem(name="test", terms=terms, problem_type=ProblemType.pubo) problem_new = problem.set_fixed_variables({"0": 1}) self.assertEqual([], problem_new.terms) # test small cases terms = [Term(c=10, indices=[0, 1, 2]), Term(c=-5, indices=[1, 2])] problem = Problem(name="test", terms=terms, problem_type=ProblemType.pubo) self.assertEqual([], problem.set_fixed_variables({"1": 0}).terms) self.assertEqual( [Term(c=10, indices=[0]), Term(c=-5, indices=[])], problem.set_fixed_variables({ "1": 1, "2": 1 }).terms, ) # test all const terms get merged self.assertEqual( [Term(c=5, indices=[])], problem.set_fixed_variables({ "0": 1, "1": 1, "2": 1 }).terms, ) # test grouped terms terms = [ Term(c=1, indices=[]), Term(c=2, indices=[0, 1, 2]), SlcTerm(terms=[ Term(c=1, indices=[0]), Term(c=1, indices=[1]), Term(c=-5, indices=[]) ], c=3) ] problem = Problem(name="test", terms=terms, problem_type=ProblemType.pubo) self.assertEqual( [Term(c=30, indices=[])], problem.set_fixed_variables({ "0": 1, "1": 1, "2": 1 }).terms, ) self.assertEqual( [Term(c=2, indices=[1]), Term(c=1, indices=[])], problem.set_fixed_variables({ "0": 1, "2": 1 }).terms, ) self.assertEqual( [ SlcTerm(terms=[Term(c=-4, indices=[]), Term(c=1, indices=[1])], c=3) ], problem.set_fixed_variables({ "0": 1, "2": 1 }).terms_slc, ) # test init_config gets transferred problem = Problem("My Problem", terms=terms, init_config={ "0": 1, "1": 1, "2": 1 }) problem2 = problem.set_fixed_variables({"0": 0}) self.assertEqual({"1": 1, "2": 1}, problem2.init_config)