def ai_player_csp(state, board):
    csp = constraint.Problem()
    rows, cols = len(state[0]), len(state[0][0])
    fringe_cells = set()
    for i, j in np.ndindex((rows, cols)):
        if state[0][i][j].isdigit():
            n = int(state[0][i][j])
            neighbors = [(x, y)
                         for x, y in surrounding_cells(i, j, rows, cols)
                         if state[0][x][y] == '#']
            fringe_cells.update(neighbors)
            csp.addConstraint(constraint.ExactSumConstraint(n), neighbors)
    csp.addVariables(fringe_cells, [0, 1])
    solutions = csp.getSolutions()
    print(len(solutions))
    if solutions:
        fringe_dict = defaultdict(float)
        for solution in solutions:
            for cell in solution.keys():
                fringe_dict[cell] += solution[cell]
        safe = min(fringe_dict, key=fringe_dict.get)
        mine = max(fringe_dict, key=fringe_dict.get)
        if fringe_dict[safe] != fringe_dict[mine]:
            return safe
    return ai_player(state, board)
Exemplo n.º 2
0
def round_seq_preserving_sum(seq: Seq[float], minval=1, maxval:int=None) -> Opt[List[int]]:
    """
    Round the elements of seq preserving the sum so that

    sum(seq_rounded) == sum(seq)

    given: sum(seq) will be rounded
    """

    seqsum = round(sum(seq))
    if maxval is None:
        maxval = int(min(max(seq) + 1, seqsum))
    p = constraint.Problem()
    numvars = len(seq)
    variables = list(range(numvars))
    domain = list(range(minval, maxval+1))
    p.addVariables(variables, domain)

    for var, optimalval in zip(variables, seq):
        func = lambda intval, floatval: abs(intval - floatval) <= 1
        p.addConstraint(partial(func, optimalval), [var])
    p.addConstraint(constraint.ExactSumConstraint(seqsum), variables)

    solutions = p.getSolutions()
    if not solutions:
        return None
    solutions.sort(key=lambda sol: sum(abs(v-x) for v, x in zip(list(sol.values()), seq)))
    solution = list(solutions[0].items())
    solution.sort()
    varnames, values = list(zip(*solution))
    return values
Exemplo n.º 3
0
def puzzle_as_CP(fixed, boxsize, solver=constraint.BacktrackingSolver()):
    """puzzle_as_CP(fixed, boxsize) -> constraint.Problem

    Returns a constraint problem representing a Sudoku puzzle, based on 
    'fixed' cell dictionary."""
    p = empty_puzzle_as_CP(boxsize, solver)
    for cell in fixed:
        p.addConstraint(constraint.ExactSumConstraint(fixed[cell]), [cell])
    return p
Exemplo n.º 4
0
def p(n):
    p = constraint.Problem()
    p.addVariables(range(n), N)
    p.addConstraint(constraint.AllDifferentConstraint())
    p.addConstraint(constraint.ExactSumConstraint(2020))
    
    try:
        print(prod(p.getSolution().values()))
    except:
        print("")
    def post_randomize(self):
        last_level = self.stack_level[self.program_cnt - 1]
        for i in range(len(self.program_h)):
            self.program_h[i].program_id = i
            self.program_h[i].call_stack_level = self.stack_level[i]

        # Top-down generate the entire call stack.
        # A program can only call the programs in the next level.
        for i in range(last_level):
            program_list = []
            next_program_list = []
            idx = 0
            # sub_program_id_pool = []
            # sub_program_cnt = []
            for j in range(len(self.stack_level)):
                if self.stack_level[j] == i:
                    program_list.append(j)
                if self.stack_level[j] == i + 1:
                    next_program_list.append(j)

            # Randomly duplicate some sub programs in the pool to create a case that
            # one sub program is called by multiple caller. Also it's possible to call
            # the same sub program in one program multiple times.
            total_sub_program_cnt = random.randint(len(next_program_list),
                                                   len(next_program_list) + 1)
            sub_program_id_pool = [None] * total_sub_program_cnt
            for j in range(len(sub_program_id_pool)):
                if j < len(next_program_list):
                    sub_program_id_pool[j] = next_program_list[j]
                else:
                    sub_program_id_pool[j] = random.choice(next_program_list)

            random.shuffle(sub_program_id_pool)
            sub_program_cnt = [None] * len(program_list)
            for i in range(len(program_list)):
                sub_program_cnt[i] = i
            # Distribute the programs of the next level among the programs of current level
            # Make sure all program has a caller so that no program is obsolete.
            problem = constraint.Problem(constraint.MinConflictsSolver())
            problem.addVariables(sub_program_cnt,
                                 range(0,
                                       len(sub_program_id_pool) + 1))
            problem.addConstraint(
                constraint.ExactSumConstraint(len(sub_program_id_pool)),
                [item for item in sub_program_cnt])
            solution = problem.getSolution()
            for j in range(len(program_list)):
                id = program_list[j]
                self.program_h[id].sub_program_id = [
                    None
                ] * solution[sub_program_cnt[j]]
                for i in range(len(self.program_h[id].sub_program_id)):
                    self.program_h[id].sub_program_id[i] = sub_program_id_pool[
                        idx]
                    idx += 1
def p3():  # ways of making 60
    problem = constraint.Problem()
    problem.addVariable("1p", range(61))  # range 0-60
    problem.addVariable("3p", range(21))
    problem.addVariable("5p", range(13))
    problem.addVariable("10p", range(7))
    problem.addVariable("20p", range(4))

    problem.addConstraint(constraint.ExactSumConstraint(60, [1, 3, 5, 10, 20]),
                          ["1p", "3p", "5p", "10p", "20p"])

    def print_solutions(solutions):
        for s in solutions:
            print(format(s["1p"], s["3p"], s["5p"], s["10p"], s["20p"]))

    solutions = problem.getSolutions()
    #print_solutions(solutions)
    print("Total number of ways: {}".format(len(solutions)))
Exemplo n.º 7
0
import constraint

problem = constraint.Problem()

# The maximum amount of each coin type can't be more than 60
# (coin_value*num_of_coints) <= 60

problem.addVariable("1 cent", range(61))
problem.addVariable("3 cent", range(21))
problem.addVariable("5 cent", range(13))
problem.addVariable("10 cent", range(7))
problem.addVariable("20 cent", range(4))

problem.addConstraint(
    constraint.ExactSumConstraint(60,[1,3,5,10,20]),
    ["1 cent", "3 cent", "5 cent","10 cent", "20 cent"]
)
# Where we explicitly give the order in which the weights should be allocated

# We could've used a custom constraint instead, BUT in this case the program will
# run slightly slower - this is because built-in functions are optimized and
# they find the solution more quickly
# def custom_constraint(a, b, c, d, e):
#     if a + 3*b + 5*c + 10*d + 20*e == 60:
#         return True
#     problem.addConstraint(o, ["1 cent", "3 cent", "5 cent","10 cent", "20 cent"])


# A function that prints out the amount of each coin
# in every acceptable combination
def print_solutions(solutions):
Exemplo n.º 8
0
for i in Block_List:
    filter_neighbours = []
    if (i[3] != -1):

        row_temp = i[1]
        col_temp = i[2]

        if (row_temp == 0 and col_temp == 0):
            if (checkDown(row_temp, col_temp, matrix)):
                temp_coord = str(row_temp + 1) + str(col_temp)
                filter_neighbours.append(temp_coord)
            if (checkRight(row_temp, col_temp, matrix)):
                temp_coord = str(row_temp) + str(col_temp + 1)
                filter_neighbours.append(temp_coord)
            if (len(filter_neighbours) > 0):
                problem.addConstraint(constraint.ExactSumConstraint(i[3]),
                                      filter_neighbours)

        elif (row_temp == 0 and col_temp == cols - 1):
            if (checkDown(row_temp, col_temp, matrix)):
                temp_coord = str(row_temp + 1) + str(col_temp)
                filter_neighbours.append(temp_coord)
            if (checkLeft(row_temp, col_temp, matrix)):
                temp_coord = str(row_temp) + str(col_temp - 1)
                filter_neighbours.append(temp_coord)
            if (len(filter_neighbours) > 0):
                problem.addConstraint(constraint.ExactSumConstraint(i[3]),
                                      filter_neighbours)

        elif (row_temp == rows - 1 and col_temp == 0):
            if (checkUp(row_temp, col_temp, matrix)):
Exemplo n.º 9
0
# Dati su novcici od 1, 2, 5, 10, 20 dinara. Napisati program koji
# pronalazi sve moguce kombinacije tako da zbir svih novcica bude 50. 
# Sve rezultate ispisati na standardni izlaz koristeci datu komandu ispisa.

import constraint

problem = constraint.Problem()

problem.addVariable("1 din", range(0, 51))
problem.addVariable("2 din", range(0, 26))
problem.addVariable("5 din", range(0, 11))
problem.addVariable("10 din", range(0, 6))
problem.addVariable("20 din", range(0, 3))

problem.addConstraint(constraint.ExactSumConstraint(50, [1, 2, 5, 10, 20]), ["1 din", "2 din", "5 din", "10 din", "20 din"])

resenje = problem.getSolutions()

for r in resenje:
    print("-----------------")
    print("""1 din: {0:d}\n2 din: {1:d}\n5 din: {2:d}\n10 din: {3:d}\n20 din: {4:d}""".format(r["1 din"], r["2 din"], r["5 din"], r["10 din"], r["20 din"]))
Exemplo n.º 10
0
import termcolor

GOOD = 0
EVIL = 1

players = list(range(1, 11))
players_evil = 4
players_good = len(players) - players_evil

problem = constraint.Problem()

# Every player is good or evil
problem.addVariables(players, [GOOD, EVIL])

# There are always an exact number of evil players
problem.addConstraint(constraint.ExactSumConstraint(players_evil))

# Assume no evil players if a mission passes
mission_passed = known_good_player = constraint.ExactSumConstraint(GOOD)

# Assume at most 1 evil player if the 4th mission passes
mission_4_passed = constraint.MaxSumConstraint(EVIL)

# Know at least 1 evil player is on every failed mission
mission_failed = known_evil_player = constraint.MinSumConstraint(EVIL)

# problem.addConstraint(known_good_player, [1])

# The following is a simulated game
# Players 1, 2, 3, 4 are evil, but we don't "know" this
problem.addConstraint(mission_failed, [1, 2, 3])
Exemplo n.º 11
0
def partition_curvedspace(x, numpart, curve, minval=1, maxdev=1, accuracy=1):
    """
    Partition a curved space defined by curve into `numpart` partitions,
    each with a min. value of `minval`

    curve: a bpf curve where y goes from 0 to some integer (this values is not important)
           NB: curve must be a monotonically growing curve starting at 0.
           See the example using .integrated() to learn how to make a monotonically growing
           curve out of any distribution

    NB: returns None if no solution is possible

    Example 1
    =========

    Divide 23 into 6 partitions following an exponential curve

    curve = bpf.expon(3, 0, 0, 1, 1)
    partition_curvedspace_int(23, 6, curve)
    --> [1, 1, 2, 4, 6, 9]

    Example 2
    =========

    Partition a distance following, an arbitraty curve, where the y defines the
    relative duration of the partitions. In this case, the curve defined the
    derivative of our space.

    curve = bpf.linear(
        0, 1,
        0.5, 0,
        1, 1)
    partition_curvedspace_int(21, 7, curve.integrated())
    --> [5, 3, 2, 1, 2, 3, 5]

    Example 3
    =========

    Partition a distance following an arbitrary curve, with fractional values with
    a precission of 0.001

    curve = bpf.linear(0, 1, 0.5, 0, 1, 1)
    dist = 21
    numpart = 7
    upscale = 1000
    parts = partition_curvedspace_int(dist*upscale, numpart, curve.integrated())
    parts = [part/upscale for part in parts]
    --> [5.143, 3.429, 1.714, 0.428, 1.714, 3.429, 5.143]
    """
    assert curve(curve.x0) == 0 and curve(curve.x1) > 0, \
        "The curve should be a monotonically growing curve, starting at 0"
    if accuracy > 1:
        raise ValueError("0 < accuracy <= 1")
    elif 0 < accuracy < 1:
        scale = int(1.0/accuracy)
        parts = partition_curvedspace(x*scale, numpart, curve, minval=minval*scale,
                                      maxdev=maxdev, accuracy=1)
        if not parts:
            scale += 1
            parts = partition_curvedspace(x*scale, numpart, curve, minval=minval*scale,
                                      maxdev=maxdev, accuracy=1)
            if not parts:
                warnings.warn("No parts with this accuracy")
                return None
        fscale = float(scale)

        def roundgrid(x, grid):
            numdig = len(str(grid).split(".")[1])
            return round(round(x*(1.0/grid))*grid, numdig)
        return [roundgrid(part/fscale, accuracy) for part in parts]
    normcurve = curve.fit_between(0, 1)
    normcurve = (normcurve / normcurve(1)) * x
    optimal_results = np.diff(normcurve.map(numpart+1))
    maxval = min(int(max(optimal_results) + 1), x-(numpart-1)*minval)

    # maxval = x - minval * (numpart - 1)
    V = list(range(numpart))
    p = constraint.Problem()
    p.addVariables(V, list(range(minval, maxval)))

    def objective(solution):
        values = list(solution.values())
        return sum(abs(val-res) for val, res in zip(values, optimal_results))

    for var, res in zip(V, optimal_results):
        func = lambda x, res: abs(x-res) <= maxdev
        p.addConstraint(partial(func, res), [var])
    p.addConstraint(constraint.ExactSumConstraint(x), V)

    solutions = p.getSolutions()
    if not solutions:
        logger.warning("No solutions")
        return None
    solutions.sort(key=objective)
    # each solution is a dict with integers as keys
    best = [value for name, value in sorted(solutions[0].items())]
    return best
Exemplo n.º 12
0
# Calculate in how many ways you can return change for 60 cents.

import constraint

problem = constraint.Problem()

# The maximum amount of each coin type can't be more than 60
# (coin_value*num_of_coints) <= 60

problem.addVariable("1 cent", range(61))
problem.addVariable("3 cent", range(21))
problem.addVariable("5 cent", range(13))
problem.addVariable("10 cent", range(7))
problem.addVariable("20 cent", range(4))

problem.addConstraint(constraint.ExactSumConstraint(60, [1, 3, 5, 10, 20]),
                      ["1 cent", "3 cent", "5 cent", "10 cent", "20 cent"])

# Where we explicitly give the order in which the weights should be allocated

# We could've used a custom constraint instead, BUT in this case the program will
# run slightly slower - this is because built-in functions are optimized and
# they find the solution more quickly
# def custom_constraint(a, b, c, d, e):
#     if a + 3*b + 5*c + 10*d + 20*e == 60:
#         return True
#     problem.addConstraint(o, ["1 cent", "3 cent", "5 cent","10 cent", "20 cent"])


# A function that prints out the amount of each coin
# in every acceptable combination
Exemplo n.º 13
0
def backend(r: int,
            c: int,
            r_num: List[List[int]],
            c_num: List[List[int]],
            crossed_cells: List[Tuple[int, int]] = None):
    # Setup CP problem object
    problem = cp.Problem()

    # Create variables
    variables = [f"A_{row}_{col}" for row in range(r) for col in range(c)]
    problem.addVariables(variables, [0, 1])

    # Create starting constraints (crossed-out cells)
    if crossed_cells and len(crossed_cells) != 0:
        crossed_variables = [f"A_{row}_{col}" for row, col in crossed_cells]
        problem.addConstraint(cp.InSetConstraint({0}), crossed_variables)

    # Create row-sum and column-sum constraints
    for row in range(r):
        constraint_vars = [v for v in variables if re.search(f"_{row}_", v)]
        row_sum = sum(r_num[row])

        # Add constraint to CP object
        # Doesn't work because of https://github.com/python-constraint/python-constraint/issues/48
        # Understand what's happening ToDo
        # problem.addConstraint(lambda *args: sum(args) == row_sum, constraint_vars)

        problem.addConstraint(cp.ExactSumConstraint(row_sum), constraint_vars)

        # multi-group constraints
        group_details = r_num[row]
        constraint_group = partial(detect_groups, group_details)
        problem.addConstraint(constraint_group, constraint_vars)

        # Constraints to speed-up processing
        if row_sum == c:
            # The whole row must be 1's
            problem.addConstraint(cp.InSetConstraint({1}), constraint_vars)

    for col in range(c):
        constraint_vars = [v for v in variables if re.search(f"_{col}$", v)]
        col_sum = sum(c_num[col])

        # Add constraint to CP object
        # problem.addConstraint(lambda *args: sum(args) == col_sum, constraint_vars)
        problem.addConstraint(cp.ExactSumConstraint(col_sum), constraint_vars)

        # multi-group constraints
        group_details = c_num[col]
        constraint_group = partial(detect_groups, group_details)
        problem.addConstraint(constraint_group, constraint_vars)

        # Constraints to speed-up processing
        if col_sum == r:
            # The whole column must be 1's
            problem.addConstraint(cp.InSetConstraint({1}), constraint_vars)

    # Solve
    # Convert dict solution into array ToDO
    solutions = problem.getSolutions()
    solutions_array = []
    for solution in solutions:
        variables_in_order = [solution[k] for k in sorted(solution)]
        solutions_array.append(np.array(variables_in_order).reshape((r, c)))

    return solutions_array
Exemplo n.º 14
0
import constraint

# 10e = 1170din

problem = constraint.Problem()

problem.addVariable("#brasno", range(0, 11))
problem.addVariable("#plazma", range(0, 21))
problem.addVariable("#jaja", range(0, 8))
problem.addVariable("#mleko", range(0, 6))
problem.addVariable("#visnja", range(0, 4))
problem.addVariable("#nutela", range(0, 9))

problem.addConstraint(constraint.ExactSumConstraint(10))
problem.addConstraint(
    constraint.MaxSumConstraint(1170, [30, 300, 50, 170, 400, 450]))
problem.addConstraint(
    constraint.MaxSumConstraint(500, [30, 10, 150, 32, 3, 15]))
problem.addConstraint(constraint.MaxSumConstraint(150, [5, 30, 2, 15, 45, 68]))

best_protein = -1
for solution in problem.getSolutions():
    kolicina_proteina = 20 * solution["#brasno"]\
                      + 15 * solution["#plazma"]\
                      + 70 * solution["#jaja"]\
                      + 40 * solution["#mleko"]\
                      + 40 * solution["#visnja"]\
                      + 7 * solution["#nutela"]
    if best_protein < kolicina_proteina:
        best_protein = kolicina_proteina
Exemplo n.º 15
0
import constraint

coins = [1, 2, 5, 10, 20, 50, 100, 200]

CSP = constraint.Problem()
for coin in coins:
    CSP.addVariable(coin, range(0, 201, coin))
CSP.addConstraint(constraint.ExactSumConstraint(200))
print len(CSP.getSolutions())
Exemplo n.º 16
0
# mora uvek da odgovara redosledu kojim smo mi definisali promenljive,
# u konkretnom primeru (videti oblik u kom ispisuje resenje),
# promenljive ce se dodati u sledecem redosledu:
# '1 din', '2 din', '10 din', '20 din', '5 din'
# (nacin na koji se kljucevi organizuju u recniku nije striktno definisan,
# primetimo da niske nisu sortirane)
# posledica je da postavljanje ogranicenja
#	problem.addConstraint(constraint.ExactSumConstraint(50,[1,2,5,10,20]))
# nece ispravno dodeliti tezine, na primer,
# tezinu 5 dodeli promenljivoj '10 din' umesto '5 din' kako bismo ocekivali

# I nacin da se resi ovaj problem je da redosled promenljivih
# koji odgovara redosledu tezina za ExactSumConstraint prosledimo
# kao dodatni argument za funkciju addConstraint

problem.addConstraint(constraint.ExactSumConstraint(50, [1, 2, 5, 10, 20]),
                      ["1 din", "2 din", "5 din", "10 din", "20 din"])

# II nacin je da definisemo svoju funkciju koja predstavlja ogranicenje, samo ce sada solver nesto sporije da radi posto ugradjene funkcije imaju optimizovanu pretragu i brze dolaze do resenja
#
#def o(a, b, c, d, e):
#	if a + 2*b + 5*c + 10*d + 20*e == 50:
#		return True
#
#problem.addConstraint(o, ["1 din", "2 din", "5 din","10 din", "20 din"])
#
resenja = problem.getSolutions()

for r in resenja:
    print("---")
    print("""1 din: {0:d}
Exemplo n.º 17
0
def solve(board):
    problem = constraint.Problem(constraint.BacktrackingSolver())
    
    # Build Variables
    for y in range(SIZE):
        for x in range(SIZE):
            if board[y,x] == -1:
                problem.addVariable(str([y,x]), [1, 100])

    # Constraints for variables near numbers
    for y in range(SIZE):
        for x in range(SIZE):
            if board[y,x] in [0,1,2,3,4]:
                val = 0
                adj_vars = []
                if y>0 and board[y-1,x] == -1: adj_vars.append(str([y-1,x]))
                if y<SIZE-1 and board[y+1,x] == -1: adj_vars.append(str([y+1,x]))
                if x>0 and board[y,x-1] == -1: adj_vars.append(str([y,x-1]))
                if x<SIZE-1 and board[y,x+1] == -1: adj_vars.append(str([y,x+1]))
                val += 100*board[y,x] + len(adj_vars) - board[y,x]
                problem.addConstraint(constraint.ExactSumConstraint(val), adj_vars)

    # Sum of each scan must be less than 200, since only 1 light per scan
    # For horizontal scans 
    for y in range(SIZE):
        curr_scan = []
        for x in range(SIZE):
            if board[y,x] == -1: curr_scan.append(str([y,x]))
            else:
                if len(curr_scan) > 0:
                    problem.addConstraint(constraint.MaxSumConstraint(199), curr_scan)
                curr_scan = []
        if len(curr_scan) > 0:
            problem.addConstraint(constraint.MaxSumConstraint(199), curr_scan)
    # For vertical scans 
    for x in range(SIZE):
        curr_scan = []
        for y in range(SIZE):
            if board[y,x] == -1: curr_scan.append(str([y,x]))
            else:
                if len(curr_scan) > 0:
                    problem.addConstraint(constraint.MaxSumConstraint(199), curr_scan)
                curr_scan = []
        if len(curr_scan) > 0:
            problem.addConstraint(constraint.MaxSumConstraint(199), curr_scan)

    # For each point, pair of scans passing through point must contain 100 at least once
    scans = []
    for y in range(SIZE):
        for x in range(SIZE):
            if board[y,x] != -1: continue
            scan = []
            scan.append(str([y,x]))
            # Up
            for i in reversed(range(y)):
                if board[i,x] >= 0: break
                else: scan.append(str([i,x]))
            # Down
            for i in range(y+1,SIZE):
                if board[i,x] >= 0: break
                else: scan.append(str([i,x]))
            # Left
            for i in reversed(range(x)):
                if board[y,i] >= 0: break
                else: scan.append(str([y,i]))
            # Right
            for i in range(x+1,SIZE):
                if board[y,i] >= 0: break
                else: scan.append(str([y,i]))
            scan.sort()
            if scan not in scans: scans.append(scan)
    for scan in scans:
        problem.addConstraint(constraint.SomeInSetConstraint([100]), scan)
    
    solution = problem.getSolution()

    for y in range(SIZE):
        for x in range(SIZE):
            if str([y,x]) in solution:
                board[y,x] = -1 if solution[str([y,x])] == 1 else 100
    return board
Exemplo n.º 18
0
Arquivo: ex.py Projeto: keyber/RP
# Cŕeation d’une variable python de dimension n
cols = range(n)
# Cŕeation d’une variable cols dont le domaine est {1, ..., n}
pb.addVariables(cols, range(n))
# Ajout de la contrainte AllDiff
pb.addConstraint(constraint.AllDifferentConstraint())
# Ŕecuṕeration de l’ensemble des solutions possibles
s = pb.getSolution()

print(s)


n = 3
p = constraint.Problem()
x = range(1, n**2 + 1)
p.addVariables(x, x)
p.addConstraint(constraint.AllDifferentConstraint())
# Variable contenant la somme de chaque ligne/colonne/diagonale
s = n**2 * (n**2 + 1) / 6
# Ajout des contraintes du carŕe magique
for k in range(n):
    # ligne k
    p.addConstraint(constraint.ExactSumConstraint(s), [x[k*n+i] for i in range(n)])
    # colonne k
    p.addConstraint(constraint.ExactSumConstraint(s), [x[k+n*i] for i in range(n)])
    # première diagonale
    p.addConstraint(constraint.ExactSumConstraint(s), [x[n*i+i] for i in range(n)])
    # deuxième diagonale
    p.addConstraint(constraint.ExactSumConstraint(s), [x[(n-1)*i] for i in range(1, n+1)])
s = p.getSolution()
print(s)