Пример #1
0
 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)
Пример #2
0
 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
Пример #3
0
    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)
Пример #4
0
 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])
Пример #5
0
    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])
Пример #6
0
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)
Пример #7
0
    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}))
Пример #8
0
    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)
Пример #9
0
    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])
Пример #10
0
    def from_json(
            cls, 
            input_problem: str, 
            name: Optional[str] = None
        ) -> Problem:
        """Deserializes the problem from a
        json serialized with Problem.serialize()

        :param input_problem:
            the json string to be deserialized to a `Problem` instance
        :type problem_msgs: str
        :param
        :param name: 
            The name of the problem is optional, since it will try 
            to read the serialized name from the json payload.
            If this parameter is not empty, it will use it as the
            problem name ignoring the serialized value.
        :type name: Optional[str]
        """
        result = json.loads(input_problem)

        if name is None:
            metadata = result.get("metadata")
            if metadata is not None:
                name = metadata.get("name")

        terms = [Term.from_dict(t) for t in result["cost_function"]["terms"]] if "terms" in result["cost_function"] else []
        if "terms_slc" in result["cost_function"]:
            terms.append([SlcTerm.from_dict(t) for t in result["cost_function"]["terms_slc"]])

        problem = cls(
            name=name,
            terms=terms,
            problem_type=ProblemType[result["cost_function"]["type"]],
        )

        if "initial_configuration" in result["cost_function"]:
            problem.init_config = result["cost_function"]["initial_configuration"]

        return problem
Пример #11
0
    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
Пример #12
0
    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())
Пример #13
0
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",
Пример #14
0
    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)