def test_sat_or(): f = OR assert f() == {(): 1} assert f('x', 'y') == PUBO({('x', ): 1, ('y', ): 1, ('x', 'y'): -1}) assert (f({('x', 'y'): 1}, 'a') == PUBO({ ('x', 'y'): 1, ('a', ): 1, ('x', 'y', 'a'): -1 })) for n in range(1, 5): P = f(*tuple(range(n))) for i in range(1 << n): sol = decimal_to_boolean(i, n) if any(sol): assert P.value(sol) == 1 else: assert not P.value(sol) # testing type x, y = boolean_var(0), boolean_var(1) for model in BOOLEAN_MODELS: assert isinstance(f(model(x), y), model)
def solve_bruteforce(self, all_solutions=False): """solve_bruteforce. Solves the JobSequence problem exactly with a brute force method. THIS SHOULD NOT BE USED FOR LARGE PROBLEMS! The advantage over this method as opposed to using a brute force QUBO solver is that the QUBO formulation has many slack variables. Parameters ---------- all_solutions : boolean (optional, defaults to False). If ``all_solutions`` is set to True, all the best solutions to the problem will be returned rather than just one of the best. If the problem is very big, then it is best if ``all_solutions == False``, otherwise this function will use a lot of memory. Returns ------- res : tuple of sets or list of tuple of sets. Each element of the tuple corresponds to a worker. Each element of the tuple is a set of jobs that are assigned to that worker. If ``all_solutions == True`` then ``res`` will be a list, where each element of the list will be one of the optimal solutions. Example ------- >>> job_lengths = {"job1": 2, "job2": 3, "job3": 1} >>> num_workers = 2 >>> problem = JobSequencing(job_lengths, num_workers) >>> print(problem.solve_bruteforce()) ({'job1', 'job3'}, {'job2'}) # or ({'job2'}, {'job1', 'job3'}) >>> print(problem.solve_bruteforce(True)) [({'job1', 'job3'}, {'job2'}), ({'job2'}, {'job1', 'job3'})] """ best = None, None all_sols, n = {}, self._m * self._N for i in range(1 << n): sol = self.convert_solution(decimal_to_boolean(i, n)) if self.is_solution_valid(sol): obj = max( sum(self._lengths[job] for job in cluster) for cluster in sol) if not all_solutions and (best[0] is None or obj < best[0]): best = obj, sol elif all_solutions and (best[0] is None or obj <= best[0]): best = obj, sol all_sols.setdefault(obj, []).append(sol) if all_solutions: return all_sols[best[0]] return best[1]
def test_decimal_to_boolean(): assert decimal_to_boolean(10, 7) == (0, 0, 0, 1, 0, 1, 0) assert decimal_to_boolean(10) == (1, 0, 1, 0) with assert_raises(ValueError): decimal_to_boolean(.5) with assert_raises(ValueError): decimal_to_boolean(1000, 2)
def test_boolean_to_decimal(): for i in range(8): assert i == boolean_to_decimal(decimal_to_boolean(i))