コード例 #1
0
def solve():
    problem = Problem()

    size = matrixOfStrimko.size + 1

    # Define the variables:  rows of x variables rangin in 1...x
    # x = tam of the matrix
    for i in range(1, size):
        problem.addVariables(range(i * 10 + 1, i * 10 + size), range(1, size))

    #Each row has different values
    for i in range(1, size):
        problem.addConstraint(AllDifferentConstraint(),
                              range(i * 10 + 1, i * 10 + size))

    # Each colum has different values
    for i in range(1, size):
        problem.addConstraint(AllDifferentConstraint(),
                              range(10 + i, 10 * size + i, 10))

    #Each route has different values
    for i in range(0, size - 1):
        problem.addConstraint(AllDifferentConstraint(),
                              matrixOfStrimko.routes[i].elements)

    return problem.getSolutions()
コード例 #2
0
def find_mapping(signal_patterns: Set[FrozenSet[str]]) -> Dict[str, str]:

    # Let’s express this as a constraint satisfaction problem
    problem = Problem()
    for signal in "abcdefg":
        problem.addVariable(signal, "abcdefg")

    # Each signal wire goes to a different segment
    problem.addConstraint(AllDifferentConstraint())

    # Unambiguous digits based on count of lit segments
    for digit in {1, 4, 7, 8}:
        for wire in find_possible_signals_for(signal_patterns, digit):
            segments = DIGIT_TO_SEGMENTS[digit]
            problem.addConstraint(InSetConstraint(segments), wire)

    # Unambiguous segments based on how many times they appear in patterns
    for signal_wire in {"a", "b", "c", "d", "e", "f", "g"}:
        count = sum(1 for pattern in signal_patterns if signal_wire in pattern)
        if count == 4:
            problem.addConstraint(InSetConstraint(["e"]), signal_wire)
        elif count == 6:
            problem.addConstraint(InSetConstraint(["b"]), signal_wire)
        elif count == 7:
            problem.addConstraint(InSetConstraint(["d", "g"]), signal_wire)
        elif count == 8:
            problem.addConstraint(InSetConstraint(["a", "c"]), signal_wire)
        elif count == 9:
            problem.addConstraint(InSetConstraint(["f"]), signal_wire)
        else:
            raise ValueError

    return problem.getSolution()
コード例 #3
0
def problem_1():
    """Function for performing work of problem 1."""
    # Initialize the problem.
    problem = Problem()

    # Add the variables (which all have the same domain)
    problem.addVariables(variables=["NM", "AR", "RR", "AL", "RL", "RA"],
                         domain=[0, 1, 2, 3, 4, 5, 6, 7])

    # All variables must be different.
    problem.addConstraint(AllDifferentConstraint())

    # Add individual constraints.
    # NM --> AR
    problem.addConstraint(check_constraint_problem_1, ["NM", "AR"])
    # AR --> RR
    problem.addConstraint(check_constraint_problem_1, ["AR", "RR"])
    # NM --> AL
    problem.addConstraint(check_constraint_problem_1, ["NM", "AL"])
    # AL --> RL
    problem.addConstraint(check_constraint_problem_1, ["AL", "RL"])
    # RR --> RA
    problem.addConstraint(check_constraint_problem_1, ["RR", "RA"])
    # RL --> RA
    problem.addConstraint(check_constraint_problem_1, ["RL", "RA"])
    # RA --> NM
    problem.addConstraint(check_constraint_problem_1, ["RA", "NM"])

    return problem
コード例 #4
0
ファイル: User.py プロジェクト: tsoonjin/kronos
    def generateSchedule(self, assignments, scoring_function):
        """ Generate schedule for a user based on scoring_function and user's existing schedule
        """
        problem = Problem()
        solution = {}
        print("Name: {self.name}")
        print("Existing schedule: {self.schedule}")
        print(
            f"Possible Rotations: {self.possibleRotations}\nOrder: {self.order}"
        )
        print()
        if len(self.possibleRotations) > 0:
            problem.addVariables(self.possibleRotations, self.order)

            # HARD CONSTRAINT 1 - All rotations must be unique in the period of the program
            problem.addConstraint(AllDifferentConstraint(),
                                  self.possibleRotations)
            solutions = problem.getSolutions()

            # Score the options
            print(f"Scoring {len(solutions)} found")
            scores = np.zeros(len(solutions))
            for sidx, solution in enumerate(solutions):
                scores[sidx] = scoring_function(
                    assignments, sorted(solution.items(), key=lambda x: x[1]),
                    self.earliestAvailableDate())

            chosen = np.argsort(scores)
            solution = solutions[chosen[0]]
            print(f"Best solution: {solution}")
        return solution
コード例 #5
0
def solve():
    problem = Problem()
    problem.addVariables("sendmory", range(10))
    problem.addConstraint(lambda d, e, y: (d + e) % 10 == y, "dey")
    problem.addConstraint(
        lambda n, d, r, e, y: (n * 10 + d + r * 10 + e) % 100 == e * 10 + y, "ndrey"
    )
    problem.addConstraint(
        lambda e, n, d, o, r, y: (e * 100 + n * 10 + d + o * 100 + r * 10 + e) % 1000 ==
        n * 100 + e * 10 + y,
        "endory",
    )
    problem.addConstraint(
        lambda s, e, n, d, m, o, r, y: 1000 * s +
        100 * e +
        10 * n +
        d +
        1000 * m +
        100 * o +
        10 * r +
        e ==
        10000 * m + 1000 * o + 100 * n + 10 * e + y,
        "sendmory",
    )
    problem.addConstraint(NotInSetConstraint([0]), "sm")
    problem.addConstraint(AllDifferentConstraint())
    solutions = problem.getSolutions()
    return solutions
コード例 #6
0
    def run(self, dag):
        """run the layout method"""
        qubits = dag.qubits
        cxs = set()

        from constraint import Problem, AllDifferentConstraint, RecursiveBacktrackingSolver
        from qiskit.transpiler.passes.layout._csp_custom_solver import CustomSolver

        for gate in dag.two_qubit_ops():
            cxs.add((qubits.index(gate.qargs[0]), qubits.index(gate.qargs[1])))
        edges = set(self.coupling_map.get_edges())

        if self.time_limit is None and self.call_limit is None:
            solver = RecursiveBacktrackingSolver()
        else:
            solver = CustomSolver(call_limit=self.call_limit,
                                  time_limit=self.time_limit)

        variables = list(range(len(qubits)))
        variable_domains = list(self.coupling_map.physical_qubits)
        random.Random(self.seed).shuffle(variable_domains)

        problem = Problem(solver)
        problem.addVariables(variables, variable_domains)
        problem.addConstraint(
            AllDifferentConstraint())  # each wire is map to a single qubit

        if self.strict_direction:

            def constraint(control, target):
                return (control, target) in edges

        else:

            def constraint(control, target):
                return (control, target) in edges or (target, control) in edges

        for pair in cxs:
            problem.addConstraint(constraint, [pair[0], pair[1]])

        solution = problem.getSolution()

        if solution is None:
            stop_reason = "nonexistent solution"
            if isinstance(solver, CustomSolver):
                if solver.time_current is not None and solver.time_current >= self.time_limit:
                    stop_reason = "time limit reached"
                elif solver.call_current is not None and solver.call_current >= self.call_limit:
                    stop_reason = "call limit reached"
        else:
            stop_reason = "solution found"
            self.property_set["layout"] = Layout(
                {v: qubits[k]
                 for k, v in solution.items()})
            for reg in dag.qregs.values():
                self.property_set["layout"].add_register(reg)

        self.property_set["CSPLayout_stop_reason"] = stop_reason
コード例 #7
0
def solve_puzzles(puzzles, solver):
    """
    Solves an array of sudoku puzzles, recording runtime.

    :param puzzles: an array of 2D array boards
    :param solver: the CSP solver to be used
    :return: none
    """
    fail_count = 0
    start_time = datetime.now()     # start timer (for runtime)

    for puzzle in puzzles:
        # initialize Board
        b = Board(puzzle)

        sudoku = Problem(solver)      # initialize CSP with custom solver

        # add variables for each square, indexed 1...size^2
        for index in range(b.board_size ** 2):
            value = b.get_value(index)

            if value == 0:
                sudoku.addVariable(index, range(1, b.board_size + 1))
            else:
                sudoku.addVariable(index, [value])

        # add uniqueness constraints to each row, column, and subsquare
        for i in range(b.board_size):
            sudoku.addConstraint(AllDifferentConstraint(), [el[0] for el in b.row(i)])
            sudoku.addConstraint(AllDifferentConstraint(), [el[0] for el in b.col(i)])
            sudoku.addConstraint(AllDifferentConstraint(), [el[0] for el in b.subsquare(i)])

        sln = sudoku.getSolution()      # solve CSP

        if sln:
            # assign solved values
            for index, value in sln.items():
                b.set_value(index, value)
        else:
            fail_count += 1

    # perform/display runtime calculation
    runtime = datetime.now() - start_time
    print("Runtime: {} seconds ({} failed)".format(runtime.total_seconds(), fail_count))
コード例 #8
0
 def _each_once_per_square(self):
     for line_square_index in range(3):
         for column_square_index in range(3):
             variable_names = []
             line_index_start = line_square_index * 3
             for line_index in range(line_index_start, line_index_start + 3):
                 column_index_start = column_square_index * 3
                 for column_index in range(column_index_start, column_index_start + 3):
                     variable_names.append(self._variable_name(line_index, column_index))
             self._problem.addConstraint(AllDifferentConstraint(), variable_names)
コード例 #9
0
def solve():
    problem = Problem()
    problem.addVariables("abcdxefgh", range(1, 10))
    problem.addConstraint(
        lambda a, b, c, d, x: a < b < c < d and a + b + c + d + x == 27,
        "abcdx")
    problem.addConstraint(
        lambda e, f, g, h, x: e < f < g < h and e + f + g + h + x == 27,
        "efghx")
    problem.addConstraint(AllDifferentConstraint())
    solutions = problem.getSolutions()
    return solutions
コード例 #10
0
    def _reset_vars(self):
        self._number_of_items = len(self._items)

        self.addVariable(FIRST, [0])
        self.addVariable(LAST, [self._number_of_items - 1])

        if self._number_of_items < 10:
            self.addVariable(NEARBY, [3])
        else:
            self.addVariable(NEARBY,
                             [round(stdev(range(self._number_of_items)))])

        self.addVariables(self._items, range(self._number_of_items))

        # given self._items might have changed update the
        # first constraint to consider the new set of self._items
        # otherwise we'd be adding redundant constraints
        if len(self._constraints) > 0:
            self._constraints[0] = (AllDifferentConstraint(), self._items)
        else:
            self.addConstraint(AllDifferentConstraint(), self._items)
コード例 #11
0
def solve():
    problem = Problem()
    problem.addVariables("twofur", range(10))
    problem.addConstraint(lambda o, r: (2 * o) % 10 == r, "or")
    problem.addConstraint(lambda w, o, u,
                          r: ((10 * 2 * w) + (2 * o)) % 100 == u * 10 + r, "wour")
    problem.addConstraint(lambda t, w, o, f, u, r:
                          2 * (t * 100 + w * 10 + o) ==
                          f * 1000 + o * 100 + u * 10 + r, "twofur")
    problem.addConstraint(NotInSetConstraint([0]), "ft")
    problem.addConstraint(AllDifferentConstraint())
    solutions = problem.getSolutions()
    return solutions
コード例 #12
0
def buildproblem(terms, total):
    problem = Problem()

    letters = sorted(list(set("".join(terms) + total)))
    initial = set([word[0] for word in terms + [total]])

    for letter in letters:
        if letter in initial:
            problem.addVariable(letter, list(range(1, 10)))
        else:
            problem.addVariable(letter, list(range(10)))
    problem.addConstraint(AllDifferentConstraint())
    digit_checks(problem, terms, total, letters)
    return problem
コード例 #13
0
    def build_constraints(self):

        # all pilots assigned to different
        self.problem.addConstraint(AllDifferentConstraint(), self.pilot_vars)

        # missions must be assigned uas only if a pilot has been assigned to it
        for mission in self.mission_vars:
            mission_and_all_pilots = [mission] + self.pilot_vars
            self.problem.addConstraint(
                self.__assign__mission_from_assigned_pilots_only,
                mission_and_all_pilots)

        # no uas can be assigned to more than 3 missions
        self.problem.addConstraint(self.__limit_mission_uas, self.mission_vars)
コード例 #14
0
ファイル: strimko.py プロジェクト: Szwarc99/Strimko
def solveStrimko(routes, values):
    res = [["." for i in range(size)] for j in range(size)]

    for r in res:
        for c in r:
            print(c, end=" ")
        print()

    S = len(res)
    problem = Problem()
    for route in routes:
        problem.addConstraint(AllDifferentConstraint(), route)
        print(route)

    for x in values:
        res[int(x[0])][int(x[1])] = str(x[2])

    cellnames = [(i, j) for j, row in enumerate(res) for i, val in enumerate(row)]
    lookup = {(i, j): res[i][j] for i, j in cellnames}
    problem.addVariables(cellnames, [str(j) for j in range(1, size + 1)])

    for j in range(size):
        # Columns in grid
        problem.addConstraint(AllDifferentConstraint(), [(i, j) for i in range(size)])
        # Rows in grid
        problem.addConstraint(AllDifferentConstraint(), [(j, i) for i in range(size)])

    for cell, value in lookup.items():
        if value != ".":
            problem.addConstraint(InSetConstraint([str(value)]), [cell])
            print("check")
    print("\n".join(" ".join(lookup[(i, j)] for j in range(size)) for i in range(size)))

    for solution in problem.getSolutions():
        for i in range(0, size):
            for j in range(0, size):
                fields[i][j].value = solution[(i, j)]
コード例 #15
0
ファイル: csp_layout.py プロジェクト: v-r0/qiskit-terra
    def run(self, dag):
        qubits = dag.qubits
        cxs = set()

        for gate in dag.two_qubit_ops():
            cxs.add((qubits.index(gate.qargs[0]), qubits.index(gate.qargs[1])))
        edges = set(self.coupling_map.get_edges())

        if self.time_limit is None and self.call_limit is None:
            solver = RecursiveBacktrackingSolver()
        else:
            solver = CustomSolver(call_limit=self.call_limit,
                                  time_limit=self.time_limit)

        problem = Problem(solver)
        problem.addVariables(list(range(len(qubits))),
                             self.coupling_map.physical_qubits)
        problem.addConstraint(
            AllDifferentConstraint())  # each wire is map to a single qubit

        if self.strict_direction:

            def constraint(control, target):
                return (control, target) in edges
        else:

            def constraint(control, target):
                return (control, target) in edges or (target, control) in edges

        for pair in cxs:
            problem.addConstraint(constraint, [pair[0], pair[1]])

        random.seed(self.seed)
        solution = problem.getSolution()

        if solution is None:
            stop_reason = 'nonexistent solution'
            if isinstance(solver, CustomSolver):
                if solver.time_current is not None and solver.time_current >= self.time_limit:
                    stop_reason = 'time limit reached'
                elif solver.call_current is not None and solver.call_current >= self.call_limit:
                    stop_reason = 'call limit reached'
        else:
            stop_reason = 'solution found'
            self.property_set['layout'] = Layout(
                {v: qubits[k]
                 for k, v in solution.items()})

        self.property_set['CSPLayout_stop_reason'] = stop_reason
コード例 #16
0
ファイル: seating.py プロジェクト: csams/musical-desks
def load_problem(cfg):
    room = cfg.room

    problem = Problem()

    # only one kid to a seat
    problem.addConstraint(AllDifferentConstraint())

    assigned = set()
    # kids with assigned seats
    for k, a in cfg.assigned.items():
        seat = room.get(*a)
        assigned.add(seat)
        problem.addConstraint(InSetConstraint([seat]), [k])

    # keep kids apart
    for s in cfg.separate:
        problem.addConstraint(keep_away, s)

    # sit kids next to each other
    for s in cfg.keep_near:
        problem.addConstraint(keep_near, s)

    # allow kids only in certain rows
    for k, a in cfg.allowed_rows.items():
        allowed = list(chain.from_iterable(room.row(r) for r in a))
        problem.addConstraint(InSetConstraint(allowed), [k])

    # disallow kids in certain rows
    for k, d in cfg.disallowed_rows.items():
        disallowed = list(chain.from_iterable(room.row(r) for r in d))
        problem.addConstraint(NotInSetConstraint(disallowed), [k])

    # allow kids only in certain columns
    for k, a in cfg.allowed_columns.items():
        allowed = list(chain.from_iterable(room.column(c) for c in a))
        problem.addConstraint(InSetConstraint(allowed), [k])

    # disallow kids in certain columns
    for k, d in cfg.disallowed_columns.items():
        disallowed = list(chain.from_iterable(room.column(c) for c in d))
        problem.addConstraint(NotInSetConstraint(disallowed), [k])

    # populate from the front back
    num_kids = len(cfg.kids)
    front = sorted(set(room.desks[:num_kids]) | assigned)
    problem.addVariables(cfg.kids, front)

    return problem
コード例 #17
0
def solve():
    problem = Problem()
    problem.addVariables("seidoz", range(10))
    problem.addConstraint(lambda s, e: (2 * s) % 10 == e, "se")
    problem.addConstraint(
        lambda i, s, z, e: ((10 * 2 * i) + (2 * s)) % 100 == z * 10 + e,
        "isze")
    problem.addConstraint(
        lambda s, e, i, d, o, z: 2 *
        (s * 1000 + e * 100 + i * 10 + s) == d * 1000 + o * 100 + z * 10 + e,
        "seidoz")
    problem.addConstraint(lambda s: s != 0, "s")
    problem.addConstraint(lambda d: d != 0, "d")
    problem.addConstraint(AllDifferentConstraint())
    solutions = problem.getSolutions()
    return solutions
コード例 #18
0
def solve():
    problem = Problem()
    problem.addVariables(range(1, 21), ["A", "B", "C", "D", "E"])
    problem.addConstraint(SomeInSetConstraint(["A"], 4, True))
    problem.addConstraint(SomeInSetConstraint(["B"], 4, True))
    problem.addConstraint(SomeInSetConstraint(["C"], 4, True))
    problem.addConstraint(SomeInSetConstraint(["D"], 4, True))
    problem.addConstraint(SomeInSetConstraint(["E"], 4, True))
    for row in range(len(STUDENTDESKS) - 1):
        for col in range(len(STUDENTDESKS[row]) - 1):
            lst = [
                STUDENTDESKS[row][col], STUDENTDESKS[row][col + 1],
                STUDENTDESKS[row + 1][col], STUDENTDESKS[row + 1][col + 1]
            ]
            lst = [x for x in lst if x]
            problem.addConstraint(AllDifferentConstraint(), lst)
    solutions = problem.getSolution()
    return solutions
コード例 #19
0
    def determine(state):
        card_played_this_round = [
            card is not None and 1 or 0
            for card in state.cards_played_by_player
        ]
        remaining_hand_size = 5 - sum(state.tricks_won_by_team)
        hand_size_by_player = [
            remaining_hand_size - played for played in card_played_this_round
        ]
        cards = list(
            set(deal()) - set(list(chain(*state.hands))) -
            set(state.cards_played))
        shuffle(cards)

        problem = Problem()
        for player in range(4):
            if state.hands[player]:
                for card_index, card in enumerate(state.hands[player]):
                    problem.addVariable((player, card_index), [card])
            else:
                voids_by_player = state.voids_by_player[player]
                for card_index in range(hand_size_by_player[player]):
                    if voids_by_player:
                        potential_cards = potential_cards_given_voids(
                            state.trump, voids_by_player, cards)
                        shuffle(potential_cards)
                        problem.addVariable((player, card_index),
                                            potential_cards)
                    else:
                        problem.addVariable((player, card_index), cards)
        problem.addConstraint(AllDifferentConstraint())

        cards = sorted(iteritems(problem.getSolution()))
        hands = [[], [], [], []]
        for player in range(4):
            hands[player] = [c[1] for c in cards[:hand_size_by_player[player]]]
            del cards[:hand_size_by_player[player]]

        state = state._replace(hands=hands)
        return state
コード例 #20
0
    def run(self, dag):
        try:
            from constraint import Problem, RecursiveBacktrackingSolver, AllDifferentConstraint
        except ImportError:
            raise TranspilerError('CSPLayout requires python-constraint to run. '
                                  'Run pip install python-constraint')
        qubits = dag.qubits()
        cxs = set()

        for gate in dag.twoQ_gates():
            cxs.add((qubits.index(gate.qargs[0]),
                     qubits.index(gate.qargs[1])))
        edges = self.coupling_map.get_edges()

        problem = Problem(RecursiveBacktrackingSolver())

        problem.addVariables(list(range(len(qubits))), self.coupling_map.physical_qubits)

        problem.addConstraint(AllDifferentConstraint())  # each wire is map to a single qbit

        if self.strict_direction:
            def constraint(control, target):
                return (control, target) in edges
        else:
            def constraint(control, target):
                return (control, target) in edges or (target, control) in edges

        for pair in cxs:
            problem.addConstraint(constraint, [pair[0], pair[1]])

        random.seed(self.seed)
        solution = problem.getSolution()

        if solution is None:
            return

        self.property_set['layout'] = Layout({v: qubits[k] for k, v in solution.items()})
コード例 #21
0
    def run(self, dag):
        try:
            from constraint import Problem, RecursiveBacktrackingSolver, AllDifferentConstraint
        except ImportError:
            raise TranspilerError(
                'CSPLayout requires python-constraint to run. '
                'Run pip install python-constraint')
        qubits = dag.qubits()
        cxs = set()

        for gate in dag.twoQ_gates():
            cxs.add((qubits.index(gate.qargs[0]), qubits.index(gate.qargs[1])))
        edges = self.coupling_map.get_edges()

        class CustomSolver(RecursiveBacktrackingSolver):
            """A wrap to RecursiveBacktrackingSolver to support ``call_limit``"""
            def __init__(self, call_limit=None, time_limit=None):
                self.call_limit = call_limit
                self.time_limit = time_limit
                self.call_current = None
                self.time_start = None
                self.time_current = None
                super().__init__()

            def limit_reached(self):
                """Checks if a limit is reached."""
                if self.call_current is not None:
                    self.call_current += 1
                    if self.call_current > self.call_limit:
                        return True
                if self.time_start is not None:
                    self.time_current = time() - self.time_start
                    if self.time_current > self.time_limit:
                        return True
                return False

            def getSolution(
                    self,  # pylint: disable=invalid-name
                    domains,
                    constraints,
                    vconstraints):
                """Wrap RecursiveBacktrackingSolver.getSolution to add the limits."""
                if self.call_limit is not None:
                    self.call_current = 0
                if self.time_limit is not None:
                    self.time_start = time()
                return super().getSolution(domains, constraints, vconstraints)

            def recursiveBacktracking(
                    self,  # pylint: disable=invalid-name
                    solutions,
                    domains,
                    vconstraints,
                    assignments,
                    single):
                """Like ``constraint.RecursiveBacktrackingSolver.recursiveBacktracking`` but
                limited in the amount of calls by ``self.call_limit`` """
                if self.limit_reached():
                    return None
                return super().recursiveBacktracking(solutions, domains,
                                                     vconstraints, assignments,
                                                     single)

        if self.time_limit is None and self.call_limit is None:
            solver = RecursiveBacktrackingSolver()
        else:
            solver = CustomSolver(call_limit=self.call_limit,
                                  time_limit=self.time_limit)

        problem = Problem(solver)
        problem.addVariables(list(range(len(qubits))),
                             self.coupling_map.physical_qubits)
        problem.addConstraint(
            AllDifferentConstraint())  # each wire is map to a single qbit

        if self.strict_direction:

            def constraint(control, target):
                return (control, target) in edges
        else:

            def constraint(control, target):
                return (control, target) in edges or (target, control) in edges

        for pair in cxs:
            problem.addConstraint(constraint, [pair[0], pair[1]])

        random.seed(self.seed)
        solution = problem.getSolution()

        if solution is None:
            stop_reason = 'nonexistent solution'
            if isinstance(solver, CustomSolver):
                if solver.time_limit is not None and solver.time_current >= self.time_limit:
                    stop_reason = 'time limit reached'
                elif solver.call_limit is not None and solver.call_current >= self.call_limit:
                    stop_reason = 'call limit reached'
        else:
            stop_reason = 'solution found'
            self.property_set['layout'] = Layout(
                {v: qubits[k]
                 for k, v in solution.items()})

        self.property_set['CSPLayout_stop_reason'] = stop_reason
コード例 #22
0
def solve_block(block, cur_solution, schedule, top_per_block, task_penalties):
    print '\tSetting up'
    block_time = schedule.block_times[block]

    # Get the available staffers
    staffers = [s for s in schedule.staffers if block in s.available_blocks]

    # Get the tasks
    tasks = [t for t in schedule.tasks if block in t.blocks]

    # Are breaks allowed in this block?
    breaks_allowed = block >= schedule.min_break_block and block <= schedule.max_break_block

    # Setup the constraint satisfaction problem
    problem = Problem()
    block_vars = []

    # Add each task to the list that need to be fulfilled
    for task in tasks:
        options = [s for s in staffers if task.valid(s)]
        for i in range(task.nstaffers):
            variable = '{} {} {}'.format(block_time, task, i)
            block_vars.append(variable)
            problem.addVariable(variable, options)

    # Allow up to max_on_break people on break at once
    if breaks_allowed:
        prev_breaks = [s for v, s in cur_solution.iteritems() if 'Break' in str(v) and not str(v).startswith('{} Break'.format(schedule.block_times[block-1])) and s != 'None']
        breakable_staffers = [s for s in staffers if s not in prev_breaks]
        for break_idx in range(schedule.max_on_break):
            problem.addVariable('{} Break {}'.format(block_time, break_idx), breakable_staffers + ['None'])
            block_vars.append('{} Break {}'.format(block_time, break_idx))
    elif block == schedule.max_break_block+1:
        prev_breaks = [s for v, s in cur_solution.iteritems() if str(v).startswith('{} Break'.format(schedule.block_times[block-1])) and s != 'None']
        prev_prev_breaks = [s for v, s in cur_solution.iteritems() if str(v).startswith('{} Break'.format(schedule.block_times[block-2])) and s != 'None']
        breakable_staffers = [s for s in staffers if s in prev_breaks and s not in prev_prev_breaks]
        for break_idx in range(schedule.max_on_break):
            problem.addVariable('{} Break {}'.format(block_time, break_idx), breakable_staffers + ['None'])
            block_vars.append('{} Break {}'.format(block_time, break_idx))

    # Only one task per person
    problem.addConstraint(AllDifferentConstraint(), block_vars)

    # Find every possible solution
    print '\tSolving'
    solutions = problem.getSolutions()

    # Score the options
    print '\tScoring'
    # obs_tasks = [task for task in tasks if isinstance(task, PatientObservationTask) or isinstance(task, GeneralObservationTask)]
    scores = np.zeros(len(solutions))
    for sidx, solution in enumerate(solutions):
        score = 0
        # Add the current block observations
        for task in tasks:
            for i in range(task.nstaffers):
                staffer = solution['{} {} {}'.format(block_time, task, i)]
                score += task_penalties[staffer][task]
        
        if breaks_allowed:
            for break_idx in range(schedule.max_on_break):
                on_break = solution['{} Break {}'.format(block_time, break_idx)]
                if on_break == 'None':
                    continue
                elif on_break.rmn:
                    score -= RMN_NO_BREAK_PENALTY
                else:
                    score -= HCA_NO_BREAK_PENALTY
        scores[sidx] = score

    print '\tFinding top'
    chosen = np.argsort(scores)
    ntied = (scores == scores[chosen[0]]).sum()
    if ntied > top_per_block:
        chosen = chosen[:ntied]
        np.random.shuffle(chosen)
    top_solutions = [solutions[i] for i in chosen[:top_per_block]]
    top_scores = scores[chosen[:top_per_block]]

    return top_solutions, top_scores
コード例 #23
0
ファイル: sudoku.py プロジェクト: gridl/constraint-examples
7...2...6
.6....28.
...419..5
....8..79
"""
grid = [list(row.strip()) for row in grid.splitlines() if row.strip()]
S = len(grid)
cellnames = [(i, j) for j, row in enumerate(grid) for i, val in enumerate(row)]
lookup = {(i, j): grid[i][j] for i, j in cellnames}

problem = Problem()
problem.addVariables(cellnames, [str(j) for j in range(1, 10)])

for j in range(9):
    # Cells in a column must all be different
    problem.addConstraint(AllDifferentConstraint(), [(i, j) for i in range(9)])
    # Cells in a row must all be different
    problem.addConstraint(AllDifferentConstraint(), [(j, i) for i in range(9)])
for i in range(3):
    for j in range(3):
        # Cells in a 3x3 group must all be different
        problem.addConstraint(AllDifferentConstraint(), [(i * 3 + a, j * 3 + b)
                                                         for a in range(3)
                                                         for b in range(3)])
for cell, value in lookup.items():
    if value != ".":
        problem.addConstraint(InSetConstraint([str(value)]), [cell])

for solution in problem.getSolutions():
    print("\n".join(" ".join(solution[(i, j)] for j in range(9))
                    for i in range(9)))
コード例 #24
0
ファイル: Interview.py プロジェクト: asifrasheed6/CSP
from constraint import Problem
from constraint import AllDifferentConstraint

problem = Problem()

# The possible appointment times are 1, 2, 3 or 4
# There are four applicants: Ali, Bob, Cyl, and Dan

problem.addVariable('Ali', [1, 3, 4])  # Ali is busy from 2 to 3
problem.addVariable('Dan', [1, 4])  # Dan is busy from 2 to 4
# Bob and Cyl are free before 4
problem.addVariable('Bob', [1, 2, 3])
problem.addVariable('Cyl', [1, 2, 3])

# All the time allocated should be different
problem.addConstraint(AllDifferentConstraint(), ['Ali', 'Dan', 'Bob', 'Cyl'])

# Possible Schedules without considering preferences
solutions = problem.getSolutions()

print('Possible Schedules (without considering preferences): ')
for solution in solutions:
    print('Ali:',
          str(solution['Ali']) + 'pm,', 'Dan:',
          str(solution['Dan']) + 'pm,', 'Bob:',
          str(solution['Bob']) + 'pm,', 'Cyl:',
          str(solution['Cyl']) + 'pm')

# Giving the earliest appoinment to Cyl
problem.addConstraint(
    lambda ali, dan, bob, cyl: cyl == min(ali, dan, bob, cyl),
コード例 #25
0
ファイル: crosswords.py プロジェクト: darencorp/sudoku_solver
def main(puzzle, lines):
    puzzle = puzzle.rstrip().splitlines()
    while puzzle and not puzzle[0]:
        del puzzle[0]

    # Extract horizontal words
    horizontal = []
    word = []
    predefined = {}
    for row in range(len(puzzle)):
        for col in range(len(puzzle[row])):
            char = puzzle[row][col]
            if not char.isspace():
                word.append((row, col))
                if char != "#":
                    predefined[row, col] = char
            elif word:
                if len(word) > MINLEN:
                    horizontal.append(word[:])
                del word[:]
        if word:
            if len(word) > MINLEN:
                horizontal.append(word[:])
            del word[:]

    # Extract vertical words
    vertical = []
    validcol = True
    col = 0
    while validcol:
        validcol = False
        for row in range(len(puzzle)):
            if col >= len(puzzle[row]):
                if word:
                    if len(word) > MINLEN:
                        vertical.append(word[:])
                    del word[:]
            else:
                validcol = True
                char = puzzle[row][col]
                if not char.isspace():
                    word.append((row, col))
                    if char != "#":
                        predefined[row, col] = char
                elif word:
                    if len(word) > MINLEN:
                        vertical.append(word[:])
                    del word[:]
        if word:
            if len(word) > MINLEN:
                vertical.append(word[:])
            del word[:]
        col += 1

    # hnames = ["h%d" % i for i in range(len(horizontal))]
    # vnames = ["v%d" % i for i in range(len(vertical))]

    # problem = Problem(MinConflictsSolver())
    problem = Problem()

    for hi, hword in enumerate(horizontal):
        for vi, vword in enumerate(vertical):
            for hchar in hword:
                if hchar in vword:
                    hci = hword.index(hchar)
                    vci = vword.index(hchar)
                    problem.addConstraint(
                        lambda hw, vw, hci=hci, vci=vci: hw[hci] == vw[vci],
                        ("h%d" % hi, "v%d" % vi))

    for char, letter in predefined.items():
        for hi, hword in enumerate(horizontal):
            if char in hword:
                hci = hword.index(char)
                problem.addConstraint(
                    lambda hw, hci=hci, letter=letter: hw[hci] == letter,
                    ("h%d" % hi, ))
        for vi, vword in enumerate(vertical):
            if char in vword:
                vci = vword.index(char)
                problem.addConstraint(
                    lambda vw, vci=vci, letter=letter: vw[vci] == letter,
                    ("v%d" % vi, ))

    wordsbylen = {}
    for hword in horizontal:
        wordsbylen[len(hword)] = []
    for vword in vertical:
        wordsbylen[len(vword)] = []

    for line in lines:
        line = line.strip()
        l = len(line)
        if l in wordsbylen:
            wordsbylen[l].append(line.upper())

    for hi, hword in enumerate(horizontal):
        words = wordsbylen[len(hword)]
        random.shuffle(words)
        problem.addVariable("h%d" % hi, words)
    for vi, vword in enumerate(vertical):
        words = wordsbylen[len(vword)]
        random.shuffle(words)
        problem.addVariable("v%d" % vi, words)

    problem.addConstraint(AllDifferentConstraint())

    solution = problem.getSolution()
    if not solution:
        print("No solution found!")

    maxcol = 0
    maxrow = 0
    for hword in horizontal:
        for row, col in hword:
            if row > maxrow:
                maxrow = row
            if col > maxcol:
                maxcol = col
    for vword in vertical:
        for row, col in vword:
            if row > maxrow:
                maxrow = row
            if col > maxcol:
                maxcol = col

    matrix = []
    for row in range(maxrow + 1):
        matrix.append([" "] * (maxcol + 1))

    for variable in solution:
        if variable[0] == "v":
            word = vertical[int(variable[1:])]
        else:
            word = horizontal[int(variable[1:])]
        for (row, col), char in zip(word, solution[variable]):
            matrix[row][col] = char

    for row in range(maxrow + 1):
        for col in range(maxcol + 1):
            sys.stdout.write(matrix[row][col])
        sys.stdout.write("\n")
コード例 #26
0
ファイル: sudoku.py プロジェクト: CMSC-471-02-S2020/471-code
def sudoku(initValue):

    p = Problem()

    # Define a variable for each cell: 11,12,13...21,22,23...98,99
    for i in range(1, 10):
        p.addVariables(range(i * 10 + 1, i * 10 + 10), range(1, 10))

    # Each row has different values
    for i in range(1, 10):
        p.addConstraint(AllDifferentConstraint(),
                        range(i * 10 + 1, i * 10 + 10))

    # Each colum has different values
    for i in range(1, 10):
        p.addConstraint(AllDifferentConstraint(), range(10 + i, 100 + i, 10))

    # Each 3x3 box has different values
    p.addConstraint(AllDifferentConstraint(),
                    [11, 12, 13, 21, 22, 23, 31, 32, 33])
    p.addConstraint(AllDifferentConstraint(),
                    [41, 42, 43, 51, 52, 53, 61, 62, 63])
    p.addConstraint(AllDifferentConstraint(),
                    [71, 72, 73, 81, 82, 83, 91, 92, 93])

    p.addConstraint(AllDifferentConstraint(),
                    [14, 15, 16, 24, 25, 26, 34, 35, 36])
    p.addConstraint(AllDifferentConstraint(),
                    [44, 45, 46, 54, 55, 56, 64, 65, 66])
    p.addConstraint(AllDifferentConstraint(),
                    [74, 75, 76, 84, 85, 86, 94, 95, 96])

    p.addConstraint(AllDifferentConstraint(),
                    [17, 18, 19, 27, 28, 29, 37, 38, 39])
    p.addConstraint(AllDifferentConstraint(),
                    [47, 48, 49, 57, 58, 59, 67, 68, 69])
    p.addConstraint(AllDifferentConstraint(),
                    [77, 78, 79, 87, 88, 89, 97, 98, 99])

    # add unary constraints for cells with initial non-zero values
    for i in range(1, 10):
        for j in range(1, 10):
            value = initValue[i - 1][j - 1]
            if value:
                p.addConstraint(lambda var, val=value: var == val,
                                (i * 10 + j, ))

    return p.getSolution()
コード例 #27
0
ファイル: abc.py プロジェクト: gridl/constraint-examples
top = "ECAD.A."
bottom = "AFCFE.B"

N = len(letters)
S = len(left)  # size of the grid.
B = S - N  # number of blanks per row/column.

# Each variable represents the column position of the given letter in the given row.
variables = [letter + str(row) for letter in letters for row in range(S)]
problem = Problem()
problem.addVariables(variables, list(range(S)))

# Within a row, each letter must be in a different column.
for row in range(S):
    rowvars = [letter + str(row) for letter in letters]
    problem.addConstraint(AllDifferentConstraint(), rowvars)

# The columns that a single given letter appears in must be all different.
for letter in letters:
    lettervars = [letter + str(row) for row in range(S)]
    problem.addConstraint(AllDifferentConstraint(), lettervars)

# Left constraints: if specified, the column of the letter given in the constraint must be
# less than the column of every other letter in that row.
for row, letter in enumerate(left):
    if letter == ".": continue
    for other in letters:
        if other != letter:
            problem.addConstraint(lambda x, y: x < y,
                                  (letter + str(row), other + str(row)))
# Right constraints: if specified, the column of the letter given in the constraint must be
コード例 #28
0
 def _each_once_per_column(self):
     for column_index in range(9):
         variable_names = [self._variable_name(line_index, column_index) for line_index in range(9)]
         self._problem.addConstraint(AllDifferentConstraint(), variable_names)
コード例 #29
0
#!/usr/bin/env python
# encoding=utf-8 (pep 0263)

# je zapotrebi nainstaloval balicek python-constraint
# <https://github.com/python-constraint/python-constraint>
from constraint import Problem, AllDifferentConstraint

problem = Problem()
domain = range(10)
variables = ("S", "E", "N", "D", "M", "O", "R", "Y")
for name in variables:
    problem.addVariable(name, domain)
problem.addConstraint(lambda s: s > 0, ("S"))
problem.addConstraint(lambda m: m > 0, ("M"))
problem.addConstraint(AllDifferentConstraint())
problem.addConstraint(lambda s, e, n, d, m, o, r, y: \
                      1000 * s + 100 * e + 10 * n + d +
                      1000 * m + 100 * o + 10 * r + e ==
                      10000 * m + 1000 * o + 100 * n + 10 * e + y, variables)

# demonstracni vypis
if __name__ == "__main__":
    print("CLP - Algebrogram\n")

    print("  S E N D")
    print("+ M O R E")
    print("---------")
    print("M O N E Y\n")

    print("Vysledek volani problem.getSolutions():")
    solution = problem.getSolutions()[0]
コード例 #30
0
ファイル: day21.py プロジェクト: bantmen/advent-of-code
for line in s.split("\n"):
    lhs, rhs = line.split(" (contains ")
    ingredients, allergens = lhs.split(" "), rhs.split(", ")
    allergens[-1] = allergens[-1][:-1]
    for ing in ingredients:
        i_to_a[ing] |= set(allergens)
    for al in allergens:
        if not a_to_i[al]:
            a_to_i[al] = set(ingredients)
        else:
            a_to_i[al] &= set(ingredients)
    i.append(ingredients)

p = Problem()

p.addConstraint(AllDifferentConstraint())

for al, ingredients in a_to_i.items():
    p.addVariable(al, list(ingredients))

not_seen = set(i_to_a.keys())
for soln in p.getSolutions():
    for ing in soln.values():
        if ing in not_seen:
            not_seen.remove(ing)

count = 0
for ingredients in i:
    for ing in ingredients:
        if ing in not_seen:
            count += 1