Пример #1
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
Пример #2
0
class SudokuProblem(object):
    def __init__(self):
        self._problem = Problem()

    def _each_once_per_line(self):
        for line_index in range(9):
            variable_names = [self._variable_name(line_index, column_index) for column_index in range(9)]
            self._problem.addConstraint(AllDifferentConstraint(), variable_names)

    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)

    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)

    def generate_constraints(self):
        self._each_once_per_line()
        self._each_once_per_column()
        self._each_once_per_square()

    def _variable_name(self, line_index, column_index):
        return '(l%d,c%d)' % (line_index, column_index)

    def feed_puzzle(self, values_of_colum_of_line):
        for line_index, values_of_column in values_of_colum_of_line.items():
            for column_index, values in values_of_column.items():
                variable_name = self._variable_name(line_index, column_index)
                self._problem.addVariable(variable_name, values)

    def iterate_solutions(self):
        return self._problem.getSolutionIter()

    def format_solution(self, solution_dict, indent_text):
        chunks = []
        for line_index in range(9):
            values = []
            for column_index in range(9):
                value = solution_dict[self._variable_name(line_index, column_index)]
                values.append(value)
            chunks.append(indent_text + '%d %d %d | %d %d %d | %d %d %d' % tuple(values))

            if line_index % 3 == 2 and line_index < 8:
                chunks.append(indent_text + '------+-------+------')

        return '\n'.join(chunks)
Пример #3
0
def solve_board(overlays, verify_just_one=False):
    problem = Problem()
    spot_constraints = defaultdict(list)
    overlay_constraints = []
    for overlay in overlays:
        # the simplest case is a fully 3x3 grid
        if len(overlay) == 3 and len(overlay[0]) == 3:
            for x in range(3):
                for y in range(3):
                    if overlay[x][y] is None:
                        continue
                    spot_constraints[(x, y)].extend(
                        get_constraints(overlay[x][y]))
        else:
            # dealing with a grid that is smaller than 3x3 so we
            # need to make relative constraints - we add those
            # after the all different constraint so it only needs
            # to look at possible boards
            overlay_constraints.append(
                (FunctionConstraint(floating_overlay(overlay)),
                 locations))

    # the unspecified spots could be any piece
    for x in range(3):
        for y in range(3):
                if (x, y) not in spot_constraints:
                    spot_constraints[(x, y)] = pieces

    for spot, values in spot_constraints.iteritems():
        problem.addVariable(spot, values)

    problem.addConstraint(AllDifferentConstraint())

    for overlay_constraint in overlay_constraints:
        problem.addConstraint(*overlay_constraint)

    solution = None

    if verify_just_one:
        solutions = problem.getSolutions()
        assert len(solutions) == 1, ('%d solutions but there should be 1' %
                                     len(solutions))
        solution = solutions[0]
    else:
        solution = problem.getSolution()

    answer = [[None] * 3 for x in range(3)]
    for x in range(3):
        for y in range(3):
            answer[x][y] = solution[(x, y)]

    print('\n'.join(' '.join(_) for _ in answer))
    print('')

    return answer
Пример #4
0
def solve():
    problem = Problem()
    total = 5.00
    variables = ("0.01", "0.05", "0.10", "0.50", "1.00")
    values = [float(x) for x in variables]
    for variable, value in zip(variables, values):
        problem.addVariable(variable, range(int(total / value)))
    problem.addConstraint(ExactSumConstraint(total, values), variables)
    problem.addConstraint(ExactSumConstraint(100))
    solutions = problem.getSolutionIter()
    return solutions, variables
Пример #5
0
def gen_disjunct_intervals_CSP(ints):
    p = Problem()
    size = len(ints)
    sizeL = range(size)
    for intnum, key in enumerate(ints):
        values = [[]]
        for i in sizeL:
            values += [
                item
                for item in it.combinations(ints, i + 1) if key in item
            ]
        p.addVariable(intnum, values)

    for i in sizeL:
        p.addConstraint(check_continuity, (i,))
    for i1, i2 in it.product(sizeL, sizeL):
        if i1 < i2:
            p.addConstraint(check_all, (i1, i2))
    p.addConstraint(all_interval, sizeL)

    return p.getSolution()
Пример #6
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
Пример #7
0
def solve(sudoku_data):
    """ Solves the sudoku using simple constraints programming.
    Returns a list of solutions. Multiple solutions may be found if
    the sudoku wasn't parsed correctly.
    """
    problem = Problem()
    # add known numbers
    for i in range(0, 81):
        problem.addVariable(i, [int(sudoku_data[i])]
                                   if sudoku_data[i]
                                   else range(1, 10))
    for i in range(0, 9):
        # row constraint
        problem.addConstraint(AllDifferentConstraint(),
                              range(i * 9, i * 9 + 9))
        # column constraint
        problem.addConstraint(AllDifferentConstraint(),
                              [(i + 9 * c) for c in range(0, 9)])
        # box constraint
        problem.addConstraint(AllDifferentConstraint(),
                              [(i * 3) + (i / 3 * 18) + (9 * j) + k
                                  for j in range(0, 3)
                                    for k in range(0, 3)])
    return problem.getSolutions()
Пример #8
0
    def __init__(self,nodeGradesInfos=[]):

        X86AnalyzerBase.__init__(self,nodeGradesInfos)
        self.problem = Problem(MinConflictsSolver())
        # this is to make it human readable ..
        # we will generator the solution only when we need it and then cache it
        
        # TODO make __
        self.sol = None 
        
        for key in self.rewriteDict.keys():
            self.rewriteDict[key]['symbolCache'] = {}
            self.rewriteDict[key]['curLine'] = 1
            self.rewriteDict[key]['curPos'] = 1
        
        self.createRewrite()
Пример #9
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
Пример #10
0
def solve(size):
    problem = Problem()
    cols = range(size)
    rows = range(size)
    problem.addVariables(cols, rows)
    for col1 in cols:
        for col2 in cols:
            if col1 < col2:
                problem.addConstraint(lambda row1, row2: row1 != row2,
                                      (col1, col2))
    solutions = problem.getSolutions()
    return solutions
Пример #11
0
def solve():
    problem = Problem()
    size = 8
    cols = range(size)
    rows = range(size)
    problem.addVariables(cols, rows)
    for col1 in cols:
        for col2 in cols:
            if col1 < col2:
                problem.addConstraint(lambda row1, row2, col1=col1, col2=col2:
                                      abs(row1 - row2) != abs(col1 - col2) and
                                      row1 != row2, (col1, col2))
    solutions = problem.getSolutions()
    return solutions, size
Пример #12
0
def solve():
    problem = Problem()
    problem.addVariables("abc", range(1, 10))
    problem.getSolutions()
    minvalue = 999 / (9 * 3)
    minsolution = {}
    for solution in problem.getSolutions():
        a = solution["a"]
        b = solution["b"]
        c = solution["c"]
        value = (a * 100 + b * 10 + c) / (a + b + c)
        if value < minvalue:
            minsolution = solution
    return minvalue, minsolution
Пример #13
0
def kakuroCSP():

  # Pre: variables and equations have been computed by sanityCheck
  # Will be run in a background thread

  global solutions, variables       # will be accessed by main thread
  global solverDone

  problem = Problem()

  # Restrict the value of each white square as much as possible

  domains = defaultdict(set)
  univ = list(range(1,10))
  for n in univ:
    for c in combinations(univ, n):
      domains[sum(c), n] |= set(c)

  candidates = {v: set(univ) for v in variables}
  for eq in equations:
    for v in eq.variables:
      candidates[v] &= domains[eq.clue, len(eq.variables)]

  # one variable for each white square, with values in range computed above

  for v in variables:
    problem.addVariable(v, tuple(candidates[v]))

  for eq in equations:
    # All the numbers in a single sum are distinct

    problem.addConstraint(AllDifferentConstraint(), eq.variables)

    # The numbers must sum to the clue

    problem.addConstraint(ExactSumConstraint(eq.clue), eq.variables)

  solutions = problem.getSolutions()
  solverDone = True
Пример #14
0
def compute_using_external_solver(predicate, env, varList):
    # TODO: import at module level
    # external software:
    # install http://labix.org/python-constraint
    # download and unzip python-constraint-1.1.tar.bz2
    # python setup.py build
    # python setup.py install
    #from pretty_printer import pretty_print
    #print "predicate:", pretty_print(predicate)
    from constraint import Problem
    assert isinstance(predicate, Predicate)
    var_and_domain_lst = []
    # get domain 
    for idNode in varList:
        assert isinstance(idNode, AIdentifierExpression)
        atype = env.get_type_by_node(idNode)
        #if USE_RPYTHON_CODE:
        #    domain = all_values_by_type_RPYTHON(atype, env, idNode)
        #else:
        #    domain = all_values_by_type(atype, env, idNode)
        domain = all_values_by_type(atype, env, idNode)
        tup = (idNode.idName, domain)
        var_and_domain_lst.append(tup)
    problem = Problem() # import from "constraint"
    for tup in var_and_domain_lst:
        name = tup[0]
        lst  = tup[1]
        if isinstance(lst, frozenset):
            lst = set_to_list(lst) 
        problem.addVariable(name, lst)
    qme_nodes = []
    constraint_string = pretty_print_python_style(env, varList, predicate, qme_nodes)
    names = [x.idName for x in varList]
    expr = "lambda "
    for n in names[0:-1]:
        expr += n+","
    expr += varList[-1].idName+":"+constraint_string
    #print expr
    my_globales = {"qme_nodes":qme_nodes, "quick_member_eval":quick_member_eval, "env":env}
    lambda_func = eval(expr, my_globales)  # TODO:(#ISSUE 16) not Rpython
    problem.addConstraint(lambda_func, names)
    return problem.getSolutionIter()
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
Пример #16
0
def solve():
    problem = Problem()

    # Define the variables: 9 rows of 9 variables rangin in 1...9
    for i in range(1, 10):
        problem.addVariables(range(i * 10 + 1, i * 10 + 10), range(1, 10))

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

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

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

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

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

    # Some value is given.
    initValue = [[0, 9, 0, 7, 0, 0, 8, 6, 0], [0, 3, 1, 0, 0, 5, 0, 2, 0],
                 [8, 0, 6, 0, 0, 0, 0, 0, 0], [0, 0, 7, 0, 5, 0, 0, 0, 6],
                 [0, 0, 0, 3, 0, 7, 0, 0, 0], [5, 0, 0, 0, 1, 0, 7, 0, 0],
                 [0, 0, 0, 0, 0, 0, 1, 0, 9], [0, 2, 0, 6, 0, 0, 0, 5, 0],
                 [0, 5, 4, 0, 0, 8, 0, 7, 0]]

    for i in range(1, 10):
        for j in range(1, 10):
            if initValue[i - 1][j - 1] != 0:
                problem.addConstraint(
                    lambda var, val=initValue[i - 1][j - 1]: var == val,
                    (i * 10 + j, ))

    # Get the solutions.
    solutions = problem.getSolutions()
    return solutions
Пример #17
0
        return "\n".join([
            " ".join(self.formatday(d, wd, width) for (d, wd) in theweek),
            " ".join(self.formathours(d, wd, width) for (d, wd) in theweek),
        ])


CALENDAR = MCalendar()
days = [d for d in CALENDAR.itermonthdates(YEAR, MONTH) if d.month == MONTH]


def all_assigned(assignments, variables):
    return [assignments.get(v, Unassigned)
            for v in variables].count(Unassigned) == 0


problem = Problem()

problem.addVariables(days, list(range(0, 17)))

for d in days:
    if d.day in special:
        problem.addConstraint(InSetConstraint([special[d.day]]), [d])
    elif d.weekday() in regular:
        problem.addConstraint(InSetConstraint([regular[d.weekday()]]), [d])

problem.addConstraint(MaxSumConstraint(HOURS))

soln = problem.getSolution()
CALENDAR.sched = {k.day: v for k, v in soln.items()}
CALENDAR.prmonth(YEAR, MONTH)
Пример #18
0
def solve_board(board, cages):
    problem = Problem()
    height = len(board)
    width = len(board[0])
    assert width == height, 'Grid must be a square'

    cage_name_to_locations = defaultdict(list)

    for x in range(height):
        row_variables = [(x, ry) for ry in range(width)]
        column_variables = [(cx, x) for cx in range(height)]
        problem.addConstraint(AllDifferentConstraint(), row_variables)
        problem.addConstraint(AllDifferentConstraint(), column_variables)
        for y in range(width):
            if isinstance(board[x][y], basestring):
                # we are dealing with a function
                cage_name_to_locations[board[x][y]].append((x, y))
            else:
                # we are dealing with a pre-assigned number
                problem.addVariable((x, y), [board[x][y]])

    for cage_name, cage_locations in cage_name_to_locations.iteritems():
        cage_function = cages[cage_name]
        all_values = product(range(1, width + 1),
                             repeat=len(cage_locations))
        possible_values = set(chain(*[values for values in all_values
                                      if cage_function(*values)]))
        for location in cage_locations:
            problem.addVariable(location, list(possible_values))
        problem.addConstraint(FunctionConstraint(cage_function),
                              cage_locations)

    solution = problem.getSolution()

    answer = [row[:] for row in board]
    for x in range(height):
        for y in range(width):
            answer[x][y] = solution[(x, y)]

    return answer
Пример #19
0
def solution(dimension, solver=None):
    """Generate binary puzzle solution."""
    problem = Problem()
    if solver is not None:
        problem.setSolver(solver)
    else:
        problem.setSolver(BacktrackingSolver())
    problem.addVariables(range(dimension**2), [0, 1])
    for i in range(dimension):
        row_positions = range(i * dimension, (i + 1) * dimension)
        column_positions = range(i, dimension**2, dimension)
        # same number of zeros and ones in each row
        problem.addConstraint(ExactSumConstraint(dimension / 2), row_positions)
        problem.addConstraint(ExactSumConstraint(dimension / 2),
                              column_positions)
        # maximum two of the same next to each other
        for triplet in _nwise(row_positions, 3):
            problem.addConstraint(MaxSumConstraint(2), triplet)
            problem.addConstraint(MinSumConstraint(1), triplet)
        for triplet in _nwise(column_positions, 3):
            problem.addConstraint(MaxSumConstraint(2), triplet)
            problem.addConstraint(MinSumConstraint(1), triplet)
    # unique rows and columns
    problem.addConstraint(
        FunctionConstraint(partial(_test_uniqueness, dimension=dimension)),
        range(dimension**2))
    if isinstance(solver, RecursiveBacktrackingSolver):
        return problem.getSolutions()
    if isinstance(solver, MinConflictsSolver):
        return (problem.getSolution(), )
    return problem.getSolutionIter()
#Note: Requires 'pip install python-constraint'

from constraint import AllDifferentConstraint, InSetConstraint, Problem

# variables
jobs = "FA EA PA RO AC".split()
deskcolor = "Aqua Maroon Pink Cream Purple".split()
travel = "Fiji France Canada Japan Thailand".split()
drinks = "Peppermint GreenTea Chamomile EarlGrey EnglishBreakfast".split()
suburb = "Brunswick, Werribee, Frankston, Oakleigh, StKilda".split(", ")

# There are five houses.
minn, maxn = 1, 5
problem = Problem()
# value of a variable is the number of a house with corresponding property
variables = jobs + deskcolor + travel + drinks + suburb
problem.addVariables(variables, range(minn, maxn + 1))

# All jobs, colors, travel, drinks, and suburb are unique to each person
for vars_ in (jobs, deskcolor, travel, drinks, suburb):
    problem.addConstraint(AllDifferentConstraint(), vars_)

# RULE 4: The cream desk is to the left of the purple desk.
#NOTE: interpret it as 'cream desk number' < 'purple desk number'
problem.addConstraint(lambda a, b: a < b, ["Cream", "Purple"])

# RULE 8: In the middle desk the drink is Chamomile
#NOTE: interpret "middle" in a numerical sense (not geometrical)
problem.addConstraint(InSetConstraint([(minn + maxn) // 2]), ["Chamomile"])

# RULE 9: The leftmost desk's job is Financial analyst.
Пример #21
0
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)]
Пример #22
0
from constraint import Problem

# Define variables for the CSP problem
problem = Problem()
problem.addVariable("E1", ["A", "R", "M", "P"])
problem.addVariable("E2", ["A", "R", "M", "P"])
problem.addVariable("E3", ["A", "R", "M", "P"])
problem.addVariable("E4", ["A", "R", "M", "P"])
problem.addVariable("E5", ["A", "R", "M", "P"])
problem.addVariable("E6", ["A", "R", "M", "P"])
problem.addVariable("E7", ["A", "R", "M", "P"])
problem.addVariable("E8", ["A", "R", "M", "P"])
problem.addVariable("E9", ["A", "R", "M", "P"])
problem.addVariable("E10", ["A", "R", "M", "P"])
problem.addVariable("E11", ["A", "R", "M", "P"])
problem.addVariable("E12", ["A", "R", "M", "P"])
problem.addVariable("E13", ["A", "R", "M", "P"])
problem.addVariable("E14", ["A", "R", "M", "P"])
problem.addVariable("E15", ["A", "R", "M", "P"])

def lJunction(x, y):
    if x == "R" and y == "P":
        return True
    elif x == "R" and y == "R":
        return True
    elif x == "P" and y == "R":
        return True
    elif x == "A" and y == "M":
        return True
    elif x == "A" and y == "A":
        return True
Пример #23
0
def solve():
    problem = Problem()

    # Define the variables: 9 rows of 9 variables rangin in 1...9
    for i in range(1, 10):
        problem.addVariables(range(i * 10 + 1, i * 10 + 10), range(1, 10))

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

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

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

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

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

    # Some value is given.
    initValue = [
        [0, 9, 0, 7, 0, 0, 8, 6, 0],
        [0, 3, 1, 0, 0, 5, 0, 2, 0],
        [8, 0, 6, 0, 0, 0, 0, 0, 0],
        [0, 0, 7, 0, 5, 0, 0, 0, 6],
        [0, 0, 0, 3, 0, 7, 0, 0, 0],
        [5, 0, 0, 0, 1, 0, 7, 0, 0],
        [0, 0, 0, 0, 0, 0, 1, 0, 9],
        [0, 2, 0, 6, 0, 0, 0, 5, 0],
        [0, 5, 4, 0, 0, 8, 0, 7, 0],
    ]

    for i in range(1, 10):
        for j in range(1, 10):
            if initValue[i - 1][j - 1] != 0:
                problem.addConstraint(lambda var, val=initValue[i - 1][j - 1]: var == val, (i * 10 + j,))

    # Get the solutions.
    solutions = problem.getSolutions()
    return solutions
Пример #24
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
Пример #25
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()
Пример #26
0
class GraphletsConstraints(X86AnalyzerBase):

    #__registers32Bit = ["eax","ebx","ecx","edx","esi","edi","ebp","esp"]

    __dictNames = ['ref', 'tar']

    __printConds = False

    def __init__(self, nodeGradesInfos=[]):

        X86AnalyzerBase.__init__(self, nodeGradesInfos)
        self.problem = Problem(MinConflictsSolver())
        # this is to make it human readable ..
        # we will generator the solution only when we need it and then cache it

        # TODO make __
        self.sol = None

        for key in self.rewriteDict.keys():
            self.rewriteDict[key]['symbolCache'] = {}
            self.rewriteDict[key]['curLine'] = 1
            self.rewriteDict[key]['curPos'] = 1

        self.createRewrite()

    def getEmptyDict(self):
        d = X86AnalyzerBase.getEmptyDict(self)
        for key in d.keys():
            d[key]['transitions'] = []
            d[key]['valuesTrackDict'] = {}
            #if key != self.REGISTER:
            d[key]['domain'] = set()
            #self.rewriteDict[key]['inCmdCounter'] = 1

        return d

    # this will add recorded value to dict, even if there is a conflict it will be recorded...
    #
    def insertToDictWithType(self,
                             tarCmdNum,
                             fromStr,
                             refCmdNum,
                             toStr,
                             typeStr,
                             dict2insert=None):

        assert (dict2insert != None)
        dict2insert[typeStr]['transitions'].append((tarCmdNum, fromStr, toStr))

        #if typeStr != self.REGISTER:
        dict2insert[typeStr]['domain'].add(toStr)

    def commitChanges(self, tmpDict):
        for key in self.rewriteDict.keys():
            self.rewriteDict[key]['transitions'].extend(
                tmpDict[key]['transitions'])
            #if key != self.REGISTER:
            self.rewriteDict[key]['domain'].update(tmpDict[key]['domain'])

    # black list has no generation:) , we can use the rwdict type as they are the same..
    def getRewriteWithType(self, tarCmdNum, fromStr, typeStr,
                           FoundBlacklistElement):

        if self.sol == None:
            self.callSol()

        if self.rewriteDict[typeStr]['curLine'] < tarCmdNum:
            self.rewriteDict[typeStr]['curLine'] = tarCmdNum
            self.rewriteDict[typeStr]['curPos'] = 1

        varName = self.getVarName(self.getShort(typeStr), tarCmdNum,
                                  self.rewriteDict[typeStr]['curPos'])
        self.rewriteDict[typeStr]['curPos'] += 1

        if self.sol != None and varName in self.sol:
            # we have a value! update cache and return it
            newVal = self.sol[varName]
            self.rewriteDict[typeStr]['symbolCache'][fromStr] = newVal
            return newVal
        elif fromStr in self.rewriteDict[typeStr]['symbolCache']:
            return self.rewriteDict[typeStr]['symbolCache'][fromStr]
        else:
            #not found in this type's map in this generation, return original
            return fromStr

    def getShort(self, name):
        if name == self.FUNCNAME:
            return "f"
        elif name == self.VAR:
            return "m"
        elif name == self.REGISTER:
            return "r"
        else:
            raise hell

    def getVarName(self, preFix, curLine, curPos):
        return preFix + str(curLine) + "-" + str(curPos) + "_TAR"

    # TODO - make this __
    def callSol(self):
        # we need to go over each dict that is useable, and feed vars and constraints
        for typeDict in [
                x for x in self.rewriteDict.keys()
                if self.rewriteDict[x]['useAble'] == True
        ]:
            curLine = 1
            curPos = 1

            preFix = self.getShort(typeDict)
            #if typeDict != self.REGISTER:
            domain = list(self.rewriteDict[typeDict]['domain'])
            #else:
            #    domain =self.__registers32Bit
            for (line, tarStr,
                 refStr) in self.rewriteDict[typeDict]['transitions']:
                if curLine < line:
                    curPos = 1
                    curLine = line

                tarName = self.getVarName(preFix, curLine, curPos)

                self.problem.addVariables([tarName], domain)
                if (self.__printConds):
                    print "CONS(text) -> " + tarName + " == " + refStr
                self.problem.addConstraint(self.checkInputVsTarget(refStr),
                                           [tarName])

                if tarStr in self.rewriteDict[typeDict][
                        'valuesTrackDict'] != None:
                    if (self.__printConds):
                        print "CONS(bag) -> " + self.rewriteDict[typeDict][
                            'valuesTrackDict'][tarStr] + " == " + tarName
                    self.problem.addConstraint(self.varsEqual, [
                        tarName,
                        self.rewriteDict[typeDict]['valuesTrackDict'][tarStr]
                    ])
                self.rewriteDict[typeDict]['valuesTrackDict'][tarStr] = tarName

                curPos += 1

        self.sol = self.problem.getSolution()
        if traceHack:
            print "(Number of broken - " + str(
                self.problem.getSolver().getHack()) + ")",

    def varsEqual(self, v1, v2):
        return v1 == v2

    def checkInputVsTarget(self, target):
        def retFunc(inputVal):
            return inputVal == target

        return retFunc

    def getSolution(self):
        if self.sol == None:
            self.callSol()

        return self.sol

    def printSol(self, sol):
        #better call sol!

        if sol == None:
            print "NO SOL!"
            return

        last = 1
        for key in sorted(sol.iterkeys()):
            if int(key[1:2]) != last:
                last = int(key[1:2])
                print ""

            print key + ": " + sol[key] + " ",

    def getBrokenNumber(self):
        return self.problem.getSolver().getHack()
Пример #27
0
def derive_depths(marker_list, additional_constraints=[]):
    """Use constraint programming to derive the paragraph depths associated
    with a list of paragraph markers. Additional constraints (e.g. expected
    marker types, etc.) can also be added. Such constraints are functions of
    two parameters, the constraint function (problem.addConstraint) and a
    list of all variables"""
    if not marker_list:
        return []
    problem = Problem()

    # Marker type per marker
    problem.addVariables(["type" + str(i) for i in range(len(marker_list))],
                         markers.types)
    # Index within the marker list
    problem.addVariables(["idx" + str(i) for i in range(len(marker_list))],
                         range(51))
    # Depth in the tree, with an arbitrary limit of 10
    problem.addVariables(["depth" + str(i) for i in range(len(marker_list))],
                         range(10))
    all_vars = []
    for i in range(len(marker_list)):
        all_vars.extend(['type' + str(i), 'idx' + str(i), 'depth' + str(i)])

    # Always start at depth 0
    problem.addConstraint(rules.must_be(0), ("depth0",))

    for idx, marker in enumerate(marker_list):
        idx_str = str(idx)
        problem.addConstraint(rules.type_match(marker),
                              ("type" + idx_str, "idx" + idx_str))

        prior_params = ['type' + idx_str, 'idx' + idx_str, 'depth' + idx_str]
        for i in range(idx):
            prior_params += ['type' + str(i), 'idx' + str(i), 'depth' + str(i)]

        problem.addConstraint(rules.same_type, prior_params)
        problem.addConstraint(rules.diff_type, prior_params)

    # @todo: There's probably efficiency gains to making these rules over
    # prefixes (see above) rather than over the whole collection at once
    problem.addConstraint(rules.same_depth_same_type, all_vars)
    problem.addConstraint(rules.stars_occupy_space, all_vars)

    for constraint in additional_constraints:
        constraint(problem.addConstraint, all_vars)

    return [Solution(solution) for solution in problem.getSolutions()]
Пример #28
0
class Solver(object):

    problem = None
    pilots, missions, pilot_prefs = None, None, None
    uas_max = None

    # variables
    pilot_vars, mission_vars = [], []
    max_obj = 0

    def __init__(self,
                 pilot_map=None,
                 mission_map=None,
                 uas_max=None,
                 pilot_prefs=None):
        self.problem = Problem(MinConflictsSolver())
        self.pilots = pilot_map
        self.missions = mission_map
        self.uas_max = uas_max
        self.pilot_prefs = pilot_prefs

    def build_variables(self):

        # pilot-uas variable
        for key, val in self.pilots.iteritems():
            self.problem.addVariable(key, val)
            self.pilot_vars.append(key)

        # mission-uas variable
        for key, val in self.missions.iteritems():
            self.problem.addVariable(key, val)
            self.mission_vars.append(key)

    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)

    def __assign__mission_from_assigned_pilots_only(self,
                                                    *mission_and_all_pilots):
        mission = mission_and_all_pilots[0]
        i = 1
        for i in range(1, len(mission_and_all_pilots)):
            if mission == mission_and_all_pilots[i]:
                return True
        return False

    def __limit_mission_uas(self, *missions):
        mission_count = {}
        for i in range(0, self.uas_max + 1):
            mission_count[i] = 0

        for mission in missions:
            mission_count[mission] += 1

        for val in mission_count.itervalues():
            if val > 3:
                return False
        return True

    def get_solution(self):
        return self.problem.getSolution()
Пример #29
0
def rank(tree):
    @extend(node.number)
    def _rank(self):
        problem.addVariable(id(self), [0])

    @extend(node.let)
    def _rank(self):
        if isinstance(self.ret, node.ident):
            # plain assignment -- not a field, lhs indexing
            vars = [id(self.ret), id(self.args)]
            try:
                problem.addVariables(vars, list(range(4)))
                problem.addConstraint(operator.__eq__, vars)
            except ValueError:
                pass
        else:
            # lhs indexing or field
            pass

    @extend(node.for_stmt)
    def _rank(self):
        vars = [id(self.ident), id(self.expr)]
        problem.addVariables(vars, list(range(4)))
        problem.addConstraint((lambda u, v: u + 1 == v), vars)

    @extend(node.if_stmt)
    def _rank(self):
        # could use operator.__not__ instead of lambda expression
        problem.addVariable(id(self.cond_expr), list(range(4)))
        problem.addConstraint(lambda t: t == 0, [id(self.cond_expr)])

    @extend(node.ident)
    def _rank(self):
        try:
            x = id(self)
            problem.addVariable(x, list(range(4)))
            for other in self.defs:
                y = id(other)
                try:
                    problem.addVariable(y, list(range(4)))
                except ValueError:
                    pass
                problem.addConstraint(operator.__eq__, [x, y])
        except:
            print("Ignored ", self)

    """

    @extend(funcall)
    def rank(self,problem):
        if not isinstance(self.func_expr,ident):
            # In MATLAB, chaining subscripts, such as size(a)(1)
            # is not allowed, so only fields and dot expressions
            # go here.  In Octave, chaining subscripts is allowed,
            # and such expressions go here.
            return
        try:
            if defs.degree(self.func_expr):
                # If a variable is defined, it is not a function,
                # except function handle usages, such as
                #    foo=@size; foo(17)
                # which is not handled properly yet.
                x = id(self.func_expr)
                n = len(self.args)
                problem.addVariable(x,range(4))
                problem.addConstraint((lambda u: u>=n),[x])
                return
        except TypeError: # func_expr is unhashable
            # For example [10 20 30](2)
            return
        except KeyError:
            # See tests/clear_margins.m
            return
        assert getattr(self.func_expr,"name",None)
        # So func_expr is an undefined variable, and we understand
        # it's a function call -- either builtin or user-defined.
        name = self.func_expr.name
#    if name not in builtins:
#        # User-defined function
#        return
#    builtins[name](self,problem)
#
#@extend(expr)
#def rank(self,problem):
#    try:
#        builtins[self.op](self,problem)
#    except:
#        pass
    """

    problem = Problem(RecursiveBacktrackingSolver())
    for v in node.postorder(tree):
        for u in v:
            try:
                u._rank()
            except AttributeError:
                pass
    s = problem.getSolution()
    if not s:
        print("No solutions")
    else:
        d = set()
        #for k in sorted(G.nodes(), key=lambda t: (t.name,t.lexpos)):
        for k in node.postorder(tree):
            if isinstance(k, node.ident):
                print(k.name, k.lineno, s.get(id(k), -1))
Пример #30
0
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")
Пример #31
0
class GraphletsConstraints(X86AnalyzerBase):
    
    #__registers32Bit = ["eax","ebx","ecx","edx","esi","edi","ebp","esp"]
    
    __dictNames = ['ref','tar']
    
    __printConds = False
    
    def __init__(self,nodeGradesInfos=[]):

        X86AnalyzerBase.__init__(self,nodeGradesInfos)
        self.problem = Problem(MinConflictsSolver())
        # this is to make it human readable ..
        # we will generator the solution only when we need it and then cache it
        
        # TODO make __
        self.sol = None 
        
        for key in self.rewriteDict.keys():
            self.rewriteDict[key]['symbolCache'] = {}
            self.rewriteDict[key]['curLine'] = 1
            self.rewriteDict[key]['curPos'] = 1
        
        self.createRewrite()
    
    def getEmptyDict(self):
        d = X86AnalyzerBase.getEmptyDict(self)
        for key in d.keys():
            d[key]['transitions'] = []
            d[key]['valuesTrackDict'] = {}
            #if key != self.REGISTER:
            d[key]['domain'] = set()
            #self.rewriteDict[key]['inCmdCounter'] = 1
            
        return d
    
    # this will add recorded value to dict, even if there is a conflict it will be recorded...
    #
    def insertToDictWithType(self,tarCmdNum,fromStr,refCmdNum,toStr,typeStr,dict2insert=None):

        assert(dict2insert != None)
        dict2insert[typeStr]['transitions'].append((tarCmdNum,fromStr,toStr))
        
        #if typeStr != self.REGISTER:
        dict2insert[typeStr]['domain'].add(toStr)
            

    def commitChanges(self,tmpDict):
        for key in self.rewriteDict.keys():
            self.rewriteDict[key]['transitions'].extend(tmpDict[key]['transitions'])
            #if key != self.REGISTER:
            self.rewriteDict[key]['domain'].update(tmpDict[key]['domain'])
        

    # black list has no generation:) , we can use the rwdict type as they are the same..
    def getRewriteWithType(self,tarCmdNum,fromStr,typeStr,FoundBlacklistElement):
        
        if self.sol == None:
            self.callSol()

        if self.rewriteDict[typeStr]['curLine'] < tarCmdNum :
            self.rewriteDict[typeStr]['curLine'] = tarCmdNum
            self.rewriteDict[typeStr]['curPos'] = 1

            
        varName = self.getVarName(self.getShort(typeStr), tarCmdNum, self.rewriteDict[typeStr]['curPos'])
        self.rewriteDict[typeStr]['curPos'] += 1
        
        if self.sol != None and varName in self.sol:
            # we have a value! update cache and return it
            newVal = self.sol[varName]
            self.rewriteDict[typeStr]['symbolCache'][fromStr] = newVal
            return newVal
        elif fromStr in self.rewriteDict[typeStr]['symbolCache']:
            return self.rewriteDict[typeStr]['symbolCache'][fromStr]
        else:
            #not found in this type's map in this generation, return original
            return fromStr

    def getShort(self,name):
        if name == self.FUNCNAME:
            return "f"
        elif name == self.VAR:
            return "m"
        elif name == self.REGISTER:
            return "r"
        else :
            raise hell
        
    def getVarName(self,preFix,curLine,curPos):
        return preFix + str(curLine) + "-" + str(curPos) + "_TAR"

    # TODO - make this __
    def callSol(self):
        # we need to go over each dict that is useable, and feed vars and constraints
        for typeDict in [x for x in self.rewriteDict.keys() if self.rewriteDict[x]['useAble']==True ]:
            curLine = 1
            curPos = 1
            
            preFix = self.getShort(typeDict)
            #if typeDict != self.REGISTER:
            domain = list(self.rewriteDict[typeDict]['domain']) 
            #else:
            #    domain =self.__registers32Bit
            for (line,tarStr,refStr) in self.rewriteDict[typeDict]['transitions']:
                if curLine < line:
                    curPos = 1
                    curLine = line
                    
                tarName = self.getVarName(preFix, curLine, curPos)
                
                self.problem.addVariables([tarName],domain)
                if (self.__printConds):
                    print "CONS(text) -> " + tarName + " == " + refStr 
                self.problem.addConstraint(self.checkInputVsTarget(refStr),[tarName])
                
            
                if tarStr in self.rewriteDict[typeDict]['valuesTrackDict'] != None:
                    if (self.__printConds):
                        print "CONS(bag) -> " + self.rewriteDict[typeDict]['valuesTrackDict'][tarStr] + " == " + tarName 
                    self.problem.addConstraint(self.varsEqual,[tarName,self.rewriteDict[typeDict]['valuesTrackDict'][tarStr]])
                self.rewriteDict[typeDict]['valuesTrackDict'][tarStr] = tarName
                        
                curPos+=1
                
        self.sol = self.problem.getSolution()
        if traceHack:
            print "(Number of broken - " + str(self.problem.getSolver().getHack()) + ")",

    def varsEqual(self,v1, v2):
        return v1==v2
    
    def checkInputVsTarget(self,target):
        def retFunc(inputVal):
            return inputVal == target
        
        return retFunc     
    
               
    def getSolution(self):
        if self.sol == None:
            self.callSol()
            
        return self.sol
    
    def printSol(self,sol):
        #better call sol!
        
        if sol == None:
            print "NO SOL!"
            return
        
        last = 1
        for key in sorted(sol.iterkeys()):
            if int(key[1:2]) != last:
                last = int(key[1:2])
                print ""
            
            print key + ": " + sol[key] + " ",
             
    def getBrokenNumber(self):
        return self.problem.getSolver().getHack()
Пример #32
0
def derive_depths(original_markers, additional_constraints=None):
    """Use constraint programming to derive the paragraph depths associated
    with a list of paragraph markers. Additional constraints (e.g. expected
    marker types, etc.) can also be added. Such constraints are functions of
    two parameters, the constraint function (problem.addConstraint) and a
    list of all variables"""
    if additional_constraints is None:
        additional_constraints = []
    if not original_markers:
        return []
    problem = Problem()
    marker_list = _compress_markerless(original_markers)
    logger.warn(marker_list)
    # Depth in the tree, with an arbitrary limit of 10
    problem.addVariables(["depth" + str(i) for i in range(len(marker_list))],
                         range(10))

    # Always start at depth 0
    problem.addConstraint(rules.must_be(0), ("depth0",))

    all_vars = []

    for idx, marker in enumerate(marker_list):
        type_var = "type{0}".format(idx)
        depth_var = "depth{0}".format(idx)
        # Index within the marker list. Though this variable is redundant, it
        # makes the code easier to understand and doesn't have a significant
        # performance penalty
        idx_var = "idx{0}".format(idx)

        typ_opts = [t for t in markers.types if marker in t]
        idx_opts = [i for t in typ_opts for i in range(len(t))
                    if t[i] == marker]
        problem.addVariable(type_var, typ_opts)
        problem.addVariable(idx_var, idx_opts)

        problem.addConstraint(rules.type_match(marker), [type_var, idx_var])
        all_vars.extend([type_var, idx_var, depth_var])

        if idx > 0:
            pairs = all_vars[3 * (idx - 1):]
            problem.addConstraint(pair_rules, pairs)

        if idx > 1:
            pairs = all_vars[3 * (idx - 2):]
            problem.addConstraint(rules.triplet_tests, pairs)

    # separate loop so that the simpler checks run first
    for idx in range(1, len(marker_list)):
        # start with the current idx
        params = all_vars[3 * idx:3 * (idx + 1)]
        # then add on all previous
        params += all_vars[:3 * idx]
        problem.addConstraint(rules.continue_previous_seq, params)

    # @todo: There's probably efficiency gains to making these rules over
    # prefixes (see above) rather than over the whole collection at once
    problem.addConstraint(rules.same_parent_same_type, all_vars)
    for constraint in additional_constraints:
        constraint(problem.addConstraint, all_vars)

    solutions = []
    for assignment in problem.getSolutionIter():
        assignment = _decompress_markerless(assignment, original_markers)
        solutions.append(Solution(assignment))
        if len(solutions) == 10:
            break # to prevent infinite solution loops
    return solutions
Пример #33
0
	def computeChannels(self, n, k=2):
		from constraint import Problem
		from constraint import SomeInSetConstraint
		found = False
		nodes = tuple(self.nodes())
		p = Problem()
		p.addVariables(list(self.nodes()), range(n,0,-1)) # reverse ordering the domain biases the constraint solver towards smaller numbers
		p.addConstraint(SomeInSetConstraint([1]))
		def addConstraint(node1, node2, dist, diff):
			if(node1 in node2.neighbors(dist)):
				p.addConstraint(lambda x, y: abs(x - y) >= diff,(node1, node2))
				return True
			return False

		for i in xrange(len(nodes)-1):
			n1 = nodes[i]
			for j in xrange(i+1,len(nodes)):
				n2 = nodes[j]
				if(not addConstraint(n1, n2, 2, k)): # each node pair needs no more than 1 constraint
					addConstraint(n1, n2, 4, 1)
		for rowIter in self.rows():
			row = tuple(rowIter)
			for i in xrange(len(row)-1):
				p.addConstraint(lambda x, y: y == (x + k) % n + 1,(row[i], row[i+1]))
		for colIter in self.columns():
			col = tuple(colIter)
			for i in xrange(len(col)-1):
				p.addConstraint(lambda x, y: y == (x + k - 1) % n + 1,(col[i], col[i+1]))
		solution = p.getSolution()
		if(solution == None):
			return found
		found = True
		for node,channel in p.getSolution().iteritems():
			node.channel = channel
		return True
Пример #34
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
Пример #35
0
def rank(tree):
    @extend(node.number)
    def _rank(self):
        problem.addVariable(id(self),[0])

    @extend(node.let)
    def _rank(self):
        if isinstance(self.ret,node.ident):
            # plain assignment -- not a field, lhs indexing
            vars = [id(self.ret), id(self.args)]
            try:
                problem.addVariables(vars,list(range(4)))
                problem.addConstraint(operator.__eq__,vars)
            except ValueError:
                pass
        else:
            # lhs indexing or field
            pass

    @extend(node.for_stmt)
    def _rank(self):
        vars =  [id(self.ident), id(self.expr)]
        problem.addVariables(vars,list(range(4)))
        problem.addConstraint((lambda u,v: u+1==v),vars)

    @extend(node.if_stmt)
    def _rank(self):
        # could use operator.__not__ instead of lambda expression
        problem.addVariable(id(self.cond_expr),list(range(4)))
        problem.addConstraint(lambda t: t==0, [id(self.cond_expr)])

    @extend(node.ident)
    def _rank(self):
        try:
            x = id(self)
            problem.addVariable(x,list(range(4)))
            for other in self.defs:
                y = id(other)
                try:
                    problem.addVariable(y,list(range(4)))
                except ValueError:
                    pass
                problem.addConstraint(operator.__eq__, [x,y])
        except:
            print("Ignored ",self)
    """

    @extend(funcall)
    def rank(self,problem):
        if not isinstance(self.func_expr,ident):
            # In MATLAB, chaining subscripts, such as size(a)(1)
            # is not allowed, so only fields and dot expressions
            # go here.  In Octave, chaining subscripts is allowed,
            # and such expressions go here.
            return
        try:
            if defs.degree(self.func_expr):
                # If a variable is defined, it is not a function,
                # except function handle usages, such as
                #    foo=@size; foo(17)
                # which is not handled properly yet.
                x = id(self.func_expr)
                n = len(self.args)
                problem.addVariable(x,range(4))
                problem.addConstraint((lambda u: u>=n),[x])
                return
        except TypeError: # func_expr is unhashable
            # For example [10 20 30](2)
            return
        except KeyError:
            # See tests/clear_margins.m
            return
        assert getattr(self.func_expr,"name",None)
        # So func_expr is an undefined variable, and we understand
        # it's a function call -- either builtin or user-defined.
        name = self.func_expr.name
#    if name not in builtins:
#        # User-defined function
#        return
#    builtins[name](self,problem)
#
#@extend(expr)
#def rank(self,problem):
#    try:
#        builtins[self.op](self,problem)
#    except:
#        pass
    """

    problem = Problem(RecursiveBacktrackingSolver())
    for v in node.postorder(tree):
        for u in v:
            try:
                u._rank()
            except AttributeError:
                pass
    s = problem.getSolution()
    if not s:
        print("No solutions")
    else:
        d = set()
        #for k in sorted(G.nodes(), key=lambda t: (t.name,t.lexpos)):
        for k in node.postorder(tree):
            if isinstance(k,node.ident):
                print(k.name,k.lineno, s.get(id(k),-1))
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
Пример #37
0
def solve():
    problem = Problem()
    for i in range(1, 6):
        problem.addVariable("color%d" % i,
                            ["red", "white", "green", "yellow", "blue"])
        problem.addVariable("nationality%d" % i,
                            ["brit", "swede", "dane", "norwegian", "german"])
        problem.addVariable("drink%d" % i,
                            ["tea", "coffee", "milk", "beer", "water"])
        problem.addVariable("smoke%d" % i,
                            ["pallmall", "dunhill", "blends",
                             "bluemaster", "prince"])
        problem.addVariable("pet%d" % i,
                            ["dogs", "birds", "cats", "horses", "fish"])

    problem.addConstraint(AllDifferentConstraint(),
                          ["color%d" % i for i in range(1, 6)])
    problem.addConstraint(AllDifferentConstraint(),
                          ["nationality%d" % i for i in range(1, 6)])
    problem.addConstraint(AllDifferentConstraint(),
                          ["drink%d" % i for i in range(1, 6)])
    problem.addConstraint(AllDifferentConstraint(),
                          ["smoke%d" % i for i in range(1, 6)])
    problem.addConstraint(AllDifferentConstraint(),
                          ["pet%d" % i for i in range(1, 6)])

    for i in range(1, 6):

        # Hint 1
        problem.addConstraint(lambda nationality, color:
                              nationality != "brit" or color == "red",
                              ("nationality%d" % i, "color%d" % i))

        # Hint 2
        problem.addConstraint(lambda nationality, pet:
                              nationality != "swede" or pet == "dogs",
                              ("nationality%d" % i, "pet%d" % i))

        # Hint 3
        problem.addConstraint(lambda nationality, drink:
                              nationality != "dane" or drink == "tea",
                              ("nationality%d" % i, "drink%d" % i))

        # Hint 4
        if i < 5:
            problem.addConstraint(lambda colora, colorb:
                                  colora != "green" or colorb == "white",
                                  ("color%d" % i, "color%d" % (i + 1)))
        else:
            problem.addConstraint(lambda color: color != "green",
                                  ("color%d" % i,))

        # Hint 5
        problem.addConstraint(lambda color, drink:
                              color != "green" or drink == "coffee",
                              ("color%d" % i, "drink%d" % i))

        # Hint 6
        problem.addConstraint(lambda smoke, pet:
                              smoke != "pallmall" or pet == "birds",
                              ("smoke%d" % i, "pet%d" % i))

        # Hint 7
        problem.addConstraint(lambda color, smoke:
                              color != "yellow" or smoke == "dunhill",
                              ("color%d" % i, "smoke%d" % i))

        # Hint 8
        if i == 3:
            problem.addConstraint(lambda drink: drink == "milk",
                                  ("drink%d" % i,))

        # Hint 9
        if i == 1:
            problem.addConstraint(lambda nationality:
                                  nationality == "norwegian",
                                  ("nationality%d" % i,))

        # Hint 10
        if 1 < i < 5:
            problem.addConstraint(lambda smoke, peta, petb:
                                  smoke != "blends" or peta == "cats" or
                                  petb == "cats",
                                  ("smoke%d" % i, "pet%d" % (i - 1),
                                                  "pet%d" % (i + 1)))
        else:
            problem.addConstraint(lambda smoke, pet:
                                  smoke != "blends" or pet == "cats",
                                  ("smoke%d" % i,
                                   "pet%d" % (i == 1 and 2 or 4)))

        # Hint 11
        if 1 < i < 5:
            problem.addConstraint(lambda pet, smokea, smokeb:
                                  pet != "horses" or smokea == "dunhill" or
                                  smokeb == "dunhill",
                                  ("pet%d" % i, "smoke%d" % (i - 1),
                                                "smoke%d" % (i + 1)))
        else:
            problem.addConstraint(lambda pet, smoke:
                                  pet != "horses" or smoke == "dunhill",
                                  ("pet%d" % i,
                                   "smoke%d" % (i == 1 and 2 or 4)))

        # Hint 12
        problem.addConstraint(lambda smoke, drink:
                              smoke != "bluemaster" or drink == "beer",
                              ("smoke%d" % i, "drink%d" % i))

        # Hint 13
        problem.addConstraint(lambda nationality, smoke:
                              nationality != "german" or smoke == "prince",
                              ("nationality%d" % i, "smoke%d" % i))

        # Hint 14
        if 1 < i < 5:
            problem.addConstraint(lambda nationality, colora, colorb:
                                  nationality != "norwegian" or
                                  colora == "blue" or colorb == "blue",
                                  ("nationality%d" % i, "color%d" % (i - 1),
                                                        "color%d" % (i + 1)))
        else:
            problem.addConstraint(lambda nationality, color:
                                  nationality != "norwegian" or
                                  color == "blue",
                                  ("nationality%d" % i,
                                   "color%d" % (i == 1 and 2 or 4)))

        # Hint 15
        if 1 < i < 5:
            problem.addConstraint(lambda smoke, drinka, drinkb:
                                  smoke != "blends" or
                                  drinka == "water" or drinkb == "water",
                                  ("smoke%d" % i, "drink%d" % (i - 1),
                                                  "drink%d" % (i + 1)))
        else:
            problem.addConstraint(lambda smoke, drink:
                                  smoke != "blends" or drink == "water",
                                  ("smoke%d" % i,
                                   "drink%d" % (i == 1 and 2 or 4)))

    solutions = problem.getSolutions()
    return solutions
Пример #38
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()
Пример #39
0
 def __init__(self):
     self._problem = Problem()
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
Пример #41
0
from constraint import Problem, AllEqualConstraint

problem = Problem()
problem.addVariables(["a", "b"], [[1,3], [2,4], [5,6]])
problem.addConstraint(AllEqualConstraint(), ["a", "b"])
solutions = problem.getSolutions()

print (solutions)
Пример #42
0
from constraint import AllDifferentConstraint, InSetConstraint, Problem

# variables
colors        = "blue red green white yellow".split()
nationalities = "Norwegian Ukranian Japanese Spaniard English".split()
pets          = "fox dog horse snails zebra".split()
drinks        = "tea coffee milk orange water".split()
fruits    = "grapes kiwi bananas peach grapefruit".split()

# There are five houses.
minn, maxn = 1, 5
problem = Problem()
# value of a variable is the number of a house with corresponding property
variables = colors + nationalities + pets + drinks + fruits
problem.addVariables(variables, range(minn, maxn+1))

# Each house has its own unique color.
# All house owners are of different nationalities.
# They all have different pets.
# They all drink different drinks.
# They all smoke different fruits.
for vars_ in (colors, nationalities, pets, drinks, fruits):
    problem.addConstraint(AllDifferentConstraint(), vars_)

# In the middle house they drink milk.
#NOTE: interpret "middle" in a numerical sense (not geometrical)
problem.addConstraint(InSetConstraint([(minn + maxn) // 2]), ["milk"])
# The Norwegian lives in the first house.
#NOTE: interpret "the first" as a house number
problem.addConstraint(InSetConstraint([minn]), ["Norwegian"])
# The green house is on the left side of the white house.
Пример #43
0
def problem_2():
    """Function for performing the work of problem 2."""
    # Initialize the problem.
    problem = Problem()

    # Add the variables.
    problem.addVariable('case', CASES)
    problem.addVariable('motherboard', MOTHERBOARDS)
    problem.addVariable('memory', MEMORY)
    problem.addVariable('GPU', GPUS)
    problem.addVariable('SSD', SSDS)
    problem.addVariable('CPU', CPUS)

    # Add constraints.
    problem.addConstraint(motherboard_case, ['motherboard', 'case'])
    problem.addConstraint(motherboard_memory, ['motherboard', 'memory'])
    problem.addConstraint(motherboard_ssd, ['motherboard', 'SSD'])
    problem.addConstraint(motherboard_cpu, ['motherboard', 'CPU'])
    problem.addConstraint(case_gpu, ['case', 'GPU'])

    return problem
Пример #44
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
Пример #45
0
def derive_depths(original_markers, additional_constraints=[]):
    """Use constraint programming to derive the paragraph depths associated
    with a list of paragraph markers. Additional constraints (e.g. expected
    marker types, etc.) can also be added. Such constraints are functions of
    two parameters, the constraint function (problem.addConstraint) and a
    list of all variables"""
    if not original_markers:
        return []
    problem = Problem()
    marker_list = _compress_markerless(original_markers)

    # Depth in the tree, with an arbitrary limit of 10
    problem.addVariables(["depth" + str(i) for i in range(len(marker_list))],
                         range(10))

    # Always start at depth 0
    problem.addConstraint(rules.must_be(0), ("depth0",))

    all_vars = []
    for idx, marker in enumerate(marker_list):
        type_var = "type{}".format(idx)
        depth_var = "depth{}".format(idx)
        # Index within the marker list. Though this variable is redundant, it
        # makes the code easier to understand and doesn't have a significant
        # performance penalty
        idx_var = "idx{}".format(idx)

        typ_opts = [t for t in markers.types if marker in t]
        idx_opts = [i for t in typ_opts for i in range(len(t))
                    if t[i] == marker]
        problem.addVariable(type_var, typ_opts)
        problem.addVariable(idx_var, idx_opts)

        problem.addConstraint(rules.type_match(marker), [type_var, idx_var])
        all_vars.extend([type_var, idx_var, depth_var])

        if idx > 0:
            pairs = all_vars[3*(idx-1):]
            problem.addConstraint(rules.depth_check, pairs)

        if idx > 1:
            pairs = all_vars[3*(idx-2):]
            problem.addConstraint(rules.markerless_sandwich, pairs)
            problem.addConstraint(rules.star_sandwich, pairs)

    # separate loop so that the simpler checks run first
    for idx in range(1, len(marker_list)):
        # start with the current idx
        params = all_vars[3*idx:3*(idx+1)]
        # then add on all previous
        params += all_vars[:3*idx]
        problem.addConstraint(rules.sequence, params)

    # @todo: There's probably efficiency gains to making these rules over
    # prefixes (see above) rather than over the whole collection at once
    problem.addConstraint(rules.same_parent_same_type, all_vars)
    problem.addConstraint(rules.stars_occupy_space, all_vars)

    for constraint in additional_constraints:
        constraint(problem.addConstraint, all_vars)

    solutions = []
    for assignment in problem.getSolutionIter():
        assignment = _decompress_markerless(assignment, original_markers)
        solutions.append(Solution(assignment))
    return solutions
Пример #46
0
# Magic Triangle Problem
from constraint import Problem
from constraint import ExactSumConstraint
from constraint import AllDifferentConstraint

# Magic triangle with 6 circles (3 on each side), so possible sum is 9,10,11 and 12
print('==========MAGIC TRIANGLE WITH 6 CIRCLES==========\n')
for S in range(9, 13):
    problem = Problem()

    # Variables
    problem.addVariable('C1', range(1, 7))  # Corner 1
    problem.addVariable('C2', range(1, 7))  # Corner 2
    problem.addVariable('C3', range(1, 7))  # Corner 3
    problem.addVariable('E1', range(1, 7))  # Edge 1
    problem.addVariable('E2', range(1, 7))  # Edge 2
    problem.addVariable('E3', range(1, 7))  # Edge 3

    # Constraints
    problem.addConstraint(ExactSumConstraint(S, [1, 1, 1]),
                          ['C1', 'E1', 'C3'])  # Side 1
    problem.addConstraint(ExactSumConstraint(S, [1, 1, 1]),
                          ['C2', 'E2', 'C1'])  # Side 2
    problem.addConstraint(ExactSumConstraint(S, [1, 1, 1]),
                          ['C3', 'E3', 'C2'])  # Side 3
    problem.addConstraint(AllDifferentConstraint(),
                          ['C1', 'C2', 'C3', 'E1', 'E2', 'E3'
                           ])  # Values in each circle are unique

    solutions = problem.getSolutions()
    print('Total Number of Possible Solutions for Sum', S, ':', len(solutions))
Пример #47
0
from constraint import Problem, AllDifferentConstraint
from itertools import product
from functools import partial

columns = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
rows = [1, 2, 3, 4, 5, 6, 7, 8]

mapping = dict((x, y) for x, y in zip(columns, rows))

def bishop_func(a, b, x, y): return abs(mapping[x] - mapping[y]) != abs(a - b) or a == b

problem = Problem()

problem.addVariables(columns, rows)
problem.addConstraint(AllDifferentConstraint())

for column1, column2 in product(columns, columns):
    problem.addConstraint(partial(bishop_func, x = column1, y = column2), (column1, column2))

for solution in problem.getSolutions():
    print sorted(solution.iteritems())


Пример #48
0
cellnames = sorted(cell for group in groupcells.values() for cell in group)

S = len(grid)  # size of the grid
assert all(len(row) == S for row in grid)
assert len(groupnames) == S

rownames = list(range(S))
columnnames = list(range(S))


def isadjacent(cell0, cell1):
    (i0, j0), (i1, j1) = cell0, cell1
    return abs(i0 - i1) <= 1 and abs(j0 - j1) <= 1


problem = Problem()
problem.addVariables(cellnames, [0, 1])  # 1 = has a star

# Each row, column, and group must have exactly N stars
for row in rownames:
    problem.addConstraint(ExactSumConstraint(N),
                          [(x, y) for x, y in cellnames if y == row])
for col in columnnames:
    problem.addConstraint(ExactSumConstraint(N),
                          [(x, y) for x, y in cellnames if x == col])
for cells in groupcells.values():
    problem.addConstraint(ExactSumConstraint(N), cells)

# Adjacent cells may not both have a star
for cell0 in cellnames:
    for cell1 in cellnames:
Пример #49
0
class Scheduler(object):
    """
	This class provides the constraint-based Scheduler.
	"""
    def __init__(self, plant, orderList):
        """
		plant is a Plant instance to run the Scheduler on.
		orderList is the OrderList instance of incoming orders to the Plant.
		problem is a python-constraint Problem instance where solver is used as 
		the constraint solver.
		"""
        assert plant != None
        assert orderList != None

        self.plant = plant
        self.orderList = orderList
        self.problem = Problem()
        self.endMargin = 1
        self.machineMargin = 1

    def createMachineQuantityVarName(self, machine):
        """
		Creates and returns a python-constraint Variable name from a Machine 
		instance.
		"""
        assert type(machine) != str or type(machine) != unicode
        return str(machine.name) + "-quantity"

    def createEnterTimeVarName(self, order, machine):
        """
		Creates and returns a python-constraint Variable name from an Order 
		instance and a Machine instance.
		"""
        if type(machine) == str or type(machine) == unicode:
            machineName = machine
        else:
            machineName = machine.name
        return str(str(order.id) + "-enter-" + machineName)

    def createTimeAtMachineVarName(self, order, machine):
        """
		Creates and returns a python-constraint Variable name from an Order 
		instance and a Machine instance.
		"""
        if type(machine) == str or type(machine) == unicode:
            machineName = machine
        else:
            machineName = machine.name
        return str(str(order.id) + "-spend-" + machineName)

    def addPrecedenceConstraint(self, enterVar, order, machineIndex):
        """
		Adds a python-constraint Variable and Constraint to an order for the 
		precedence of Machine instances. Meaning that an order cannot get into 
		Machine 2 before getting into Machine 1. The sequence is determined by 
		the Plant instance. 
		"""
        prevMachine = self.plant.machines[machineIndex - 1]
        enterVar2 = self.createEnterTimeVarName(order, prevMachine)
        spendVar2 = self.createTimeAtMachineVarName(order, prevMachine)
        if order.recipe[prevMachine.name] != 0:
            if prevMachine.quantity <= \
               self.plant.machines[machineIndex].quantity \
               and prevMachine.canUnhook == False:
                self.problem.addConstraint(lambda x, y, yt: x == y + yt + \
                 CraneMoveTime, [enterVar, enterVar2, spendVar2])
            else:
                self.problem.addConstraint(lambda x, y, yt: x >= y + yt + \
                 CraneMoveTime, [enterVar, enterVar2, spendVar2])

    def addFinishTimeVar(self, order):
        """
		Adds a python-constraint Variable and Constraint to an order for the 
		finish time on the Plant.
		"""
        var = str(order.id) + "-finish"
        lastMachine = self.plant.machines[-1]
        self.problem.addVariable(
            var,
            range(order.deadline - self.endMargin,
                  order.deadline + self.endMargin))
        self.problem.addConstraint(lambda x, y, yt: x == y + yt, [
            var,
            self.createEnterTimeVarName(order, lastMachine),
            self.createTimeAtMachineVarName(order, lastMachine)
        ])

    def addOrderEnterTimeAtMachineVar(self, order, machineName, machineIndex):
        """
		Adds a python-constraint Variable and Constraint to an order for the 
		entrance time at a Machine instance.
		"""
        var = self.createEnterTimeVarName(order, machineName)
        if order.recipe[machineName] != 0:
            machineStart = (order.deadline + self.endMargin) - \
             order.recipe.calcMinProcTime(machineName) - self.machineMargin
            machineEnd = machineStart + self.machineMargin + \
             min(self.endMargin, self.machineMargin)
            variableRange = range(max(machineStart, 0), machineEnd)
        else:
            variableRange = range(0, 1)

        self.problem.addVariable(var, variableRange)
        if machineIndex != 0:
            self.addPrecedenceConstraint(var, order, machineIndex)

    def machineQuantityConstraintFunc(self, *args):
        quantity = args[0]
        argsMiddle = (len(args) - 1) / 2
        enterTimes = args[1:argsMiddle + 1]
        spendTimes = args[argsMiddle + 1:]

        assert len(enterTimes) == len(spendTimes)

        numberOfCommons = 0

        for i, et in enumerate(enterTimes):
            range1 = range(et, et + spendTimes[i])
            numberOfCommons = 0
            for j, et2 in enumerate(enterTimes):
                if i != j:
                    range2 = range(et2, et2 + spendTimes[j])
                    for v1 in range1:
                        if v1 in range2:
                            numberOfCommons += 1
                            break
        return not (numberOfCommons >= quantity)

    def addMachineQuantityConstraint(self, machine):
        enterVars = []
        spendVars = []

        for order in self.orderList.orders:
            enterVars.append(self.createEnterTimeVarName(order, machine))
            spendVars.append(self.createTimeAtMachineVarName(order, machine))

        vars = [self.createMachineQuantityVarName(machine)] + \
         enterVars + spendVars
        self.problem.addConstraint(self.machineQuantityConstraintFunc, vars)

    def machineCapacityConstraintFunc(self, *args):
        argsMiddle = len(args) / 2
        enterTimes = args[0:argsMiddle]
        nextEnterTimes = args[argsMiddle:]

        for i, et in enumerate(enterTimes):
            for j, et2 in enumerate(enterTimes):
                if i != j:
                    if et > et2 and nextEnterTimes[i] < nextEnterTimes[j]:
                        return False
        return True

    def addCapacityConstraint(self, machine, machineIndex):
        enterVars = []
        nextEnterVars = []

        nextMachine = self.plant.machines[machineIndex + 1]

        for order in self.orderList.orders:
            enterVars.append(self.createEnterTimeVarName(order, machine))
            nextEnterVars.append(
                self.createEnterTimeVarName(order, nextMachine))

        self.problem.addConstraint(self.machineCapacityConstraintFunc,
                                   enterVars + nextEnterVars)

    def run(self):
        """
		Runs the main Scheduler logic.
		"""
        for order in self.orderList.orders:
            if order.currentMachine != "":
                for machineIndex, machine in enumerate(self.plant.machines):
                    if machine.name != order.currentMachine:
                        order.recipe[machine.name] = 0
                    else:
                        order.recipe[machine.name] = -int(
                            order.currentOvertime)
                        break

        for machine in self.plant.machines:
            var = self.createMachineQuantityVarName(machine)
            self.problem.addVariable(var, [machine.quantity])

        for machine in self.plant.machines:
            for order in self.orderList.orders:
                var = self.createTimeAtMachineVarName(order, machine)
                self.problem.addVariable(var, [order.recipe[machine.name]])

        for machineIndex, machine in enumerate(self.plant.machines):
            for order in self.orderList.orders:
                self.addOrderEnterTimeAtMachineVar(order, machine.name,
                                                   machineIndex)

        for machineIndex, machine in enumerate(self.plant.machines):
            if machine.precedence == True and \
               machineIndex != len(self.plant.machines) - 1:
                self.addCapacityConstraint(machine, machineIndex)
            self.addMachineQuantityConstraint(machine)

        for machineIndex, machine in enumerate(self.plant.machines):
            if len(machine.setOfBreaks()) != 0:
                for order in self.orderList.orders:
                    enterVar = self.createEnterTimeVarName(order, machine)
                    self.problem.addConstraint(
                        MachineBreaksConstraint(order, machine), [enterVar])

        for order in self.orderList.orders:
            self.addFinishTimeVar(order)

        return self.printSolutions()

    def printSolutions(self):
        """
		Properly prints the solutions coming from python-constraint.
		"""
        print "Computing solutions..."

        solutions = self.problem.getSolutions()
        numberOfSolutions = len(solutions)

        for i, solution in enumerate(solutions):
            items = solution.items()
            # sort by time
            items.sort(lambda a, b: cmp(a[1], b[1]))
            # sort by order
            items.sort(lambda a, b: cmp(a[0][0], b[0][0]))

            print "Solution number", i + 1

            i = 1
            for j in items:
                if j[0][0:1] != str(i):
                    if "enter" in j[0] or "finish" in j[0]:
                        print j,
                else:
                    print "\n",
                    print "Order no:", i
                    if "enter" in j[0] or "finish" in j[0]:
                        print j,
                    i += 1
            print "\n==============================================\n",
        print "Number of solutions:", numberOfSolutions
        return solutions, numberOfSolutions

    def start(self, endMarginLimit=10, machineMarginLimit=2):
        self.endMargin = 1
        while self.endMargin <= endMarginLimit:
            self.machineMargin = 1
            while self.machineMargin <= machineMarginLimit:
                try:
                    print "End Margin: %d, Machine Margin: %d" % \
                     (self.endMargin, self.machineMargin)
                    self.problem.reset()
                    solutions, numberOfSolutions = self.run()
                    if numberOfSolutions > 0:
                        return solutions
                except Exception as e:
                    print e

                self.machineMargin += 1
            self.endMargin += 1
        print "No solutions found."
        return None
Пример #50
0
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()
        ll = len(line)
        if ll in wordsbylen:
            wordsbylen[ll].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")