예제 #1
0
def at_most(eq):
    eq = eq.strip()[1:-1]
    lst = []

    token, eq = solveToken(eq)
    while token is not None:
        lst.append(token)
        token, eq = solveToken(eq)

    ret = Cnf()
    for a in lst:
        tmp = Cnf()
        for b in lst:
            if a == b:
                tmp = tmp & b
            else:
                tmp = tmp & (-b)
        ret = ret | tmp
        # Same as xor_all till here

    tmp = Cnf()
    # One extra case in which all are negative
    for b in lst:
        tmp = tmp & (-b)
    ret = ret | tmp

    return ret
예제 #2
0
파일: dimacs_cnf.py 프로젝트: motus/satispy
    def fromstring(self, s):
        self.varname_dict = {}
        self.varobj_dict = {}

        lines = s.split("\n")
        # Throw away comments and empty lines
        new_lines = []
        for l in lines:
            l = l.strip()
            if l[0] != 'c' and l != "":
                new_lines.append(l)

        _, _, varz, clauses = new_lines[0].split(" ")
        varz, clauses = int(varz), int(clauses)

        c = Cnf()

        lines = new_lines[1:]
        c.dis = frozenset(
            frozenset(
                map(
                    lambda vn: Variable("v" + vn.strip(" \t\r\n-"), vn[0] ==
                                        '-'),
                    line.split(" ")[:-1])) for line in lines)

        for i in xrange(1, varz + 1):
            stri = str(i)
            vo = Variable('v' + stri)
            self.varname_dict[vo] = stri
            self.varobj_dict[stri] = vo

        return c
예제 #3
0
def all_xor(eq):
    # Remove the parentheses
    eq = eq.strip()[1:-1]
    # List to hold all SOLVED tokens: [aa, bb, (cc & dd)]
    lst = []

    token, eq = solveToken(eq)
    while token is not None:
        lst.append(token)
        token, eq = solveToken(eq)

    ret = Cnf()
    # Best explained by example: for [a, b, c]
    # it would create
    # (a & -b & -c) | (-a & b & -c) | (-a & -b & c)
    # EXACTLY one of [a, b, c]
    for a in lst:
        tmp = Cnf()
        for b in lst:
            if a == b:
                tmp = tmp & b
            else:
                tmp = tmp & (-b)
        ret = ret | tmp
    return ret
예제 #4
0
파일: dimacs_cnf.py 프로젝트: netom/satispy
    def fromstring(self, s):
        self.varname_dict = {}
        self.varobj_dict = {}

        lines = s.split("\n")
        # Throw away comments and empty lines
        new_lines = []
        for l in lines:
            l = l.strip()
            if l[0] != 'c' and l != "":
                new_lines.append(l)

        _,_,varz,clauses = new_lines[0].split(" ")
        varz, clauses = int(varz), int(clauses)

        c = Cnf()

        lines = new_lines[1:]
        c.dis = frozenset(
            frozenset([Variable("v"+vn.strip(" \t\r\n-"), vn[0] == '-') for vn in line.split(" ")[:-1]])
            for line in lines
        )

        for i in range(1,varz+1):
            stri = str(i)
            vo = Variable('v'+stri)
            self.varname_dict[vo] = stri
            self.varobj_dict[stri] = vo

        return c
예제 #5
0
    def solve(self):
        # Build CNF
        cnf = Cnf()
        for clause in self.formula:

            # Build DNF
            dnf = Cnf()
            for literal in clause:
                # Get variable using literal index
                variable = self.variables[literal / 2]

                # Again, negate variable as described above
                dnf |= variable if literal % 2 == 0 else -variable

            # Append DNF clause
            cnf &= dnf

        solver = Minisat()
        solution = solver.solve(cnf)

        # TODO: consider external representation for 'formula'
        if solution.success:
            self.solution = [(i, solution[self.variables[i]])
                             for i in self.variablesInFormula]
        else:
            self.solution = []

        return self.solution
예제 #6
0
def orientation(lits, i1, j1, i2, j2, i3, j3, k):
    for index in [i1, j1, i2, j2, i3, j3]:
        if index < 0:
            return Cnf()
    try:
        return (lits[i1][j1][k][1] & lits[i2][j2][k][2] & lits[i3][j3][k][3])
    except IndexError:
        return Cnf()
예제 #7
0
	def __init__(self, i,j):
        	self.i = i
		self.j = j
		self.p = []
		self.f = Cnf()	
		self.s = Cnf()	
		for d in range(9):
			temp = 'p' + str(i) + str(j) + str(d+1)
			#print temp
			self.p.append(Variable(temp))
			#create first case -- it must be filled
			self.f |= self.p[d]
예제 #8
0
def reduceCnf(cnf):
    """
    I just found a remarkably large bug in my
    SAT solver and found an interesting solution.
    Remove all b | -b
    (-b | b) & (b | -a) & (-b | a) & (a | -a)
    becomes 
    (b | -a) & (-b | a)
    Remove all (-e) & (-e)
    (-e | a) & (-e | a) & (-e | a) & (-e | a)
    becomes
    (-e | a)
    (-b | b | c) becomes nothing, not (c)
    """
    if type(cnf) is str:
        return cnf

    output = Cnf()
    for x in cnf.dis:
        dont_add = False
        for y in x:
            for z in x:
                if z == -y:
                    dont_add = True
                    break
            if dont_add: break
        if dont_add: continue
        if x not in output.dis:
            output.dis.append(x)
    return output
예제 #9
0
def original_solver(constraints):
    variables = {}

    def get_variable(name):
        if name in variables:
            var = variables[name]
        else:
            var = Variable(name)
            variables[name] = var
        return var

    exp = Cnf()
    for constraint in constraints:
        a, b, c = constraint
        x_1 = get_variable('%s<%s' % (a, c))
        x_2 = get_variable('%s<%s' % (c, a))
        x_3 = get_variable('%s<%s' % (b, c))
        x_4 = get_variable('%s<%s' % (c, b))
        exp &= (x_1 | x_2) & (x_3 | x_4) & (-x_1 | -x_4) & (-x_2 | -x_3)

    solver = Minisat()
    solution = solver.solve(exp)

    valid = []
    if solution.success:
        for var in variables:
            key = variables[var]
            if solution[key]:
                valid.append(var)
    else:
        print('No solution')
        return []

    return valid
예제 #10
0
파일: sat1.py 프로젝트: mosconi/inf3000
    def __init__(self, instance):

        self._instance = instance
        self.global_expr = Cnf()

        #self.solver = Minisat('minisat %s %s')
        self.solver = Minisat()
예제 #11
0
파일: sat1.py 프로젝트: mosconi/inf3000
    def exclude_column(self, mach, col):
        expr = Cnf()

        for p in self._instance.P:
            if col[p] == 1:
                expr |= -self.x[p, mach]
            else:
                expr |= self.x[p, mach]

        self.global_expr &= expr
예제 #12
0
def generate(numVariables, k, numClauses):
    # TODO: assert numVariables < k * numClauses?
    # Total number of possible literals
    numLiterals = 2 * numVariables

    # Literal 2n represents variable n, whereas literal (2n + 1) represents variable -n
    formula = [sample(range(numLiterals), k) for _ in range(numClauses)]

    # Get total number of variables actually used in formula
    variablesInFormula = set([literal / 2 for clause in formula for literal in clause])

    variables = [Variable(str(i)) for i in range(numVariables)]

    # Build CNF
    cnf = Cnf()
    for clause in formula:

        # Build DNF
        dnf = Cnf()
        for literal in clause:

            # Get variable using literal index
            variable = variables[literal / 2]

            # Again, negate variable as described above
            dnf |= variable if literal % 2 == 0 else -variable

        # Append DNF clause
        cnf &= dnf

    solver = Minisat()
    solution = solver.solve(cnf)
    for dis in cnf.dis:
        for var in dis:
            print var.name
            print var.inverted

    # TODO: consider external representation for 'formula'
    if solution.success:
        return (formula, [solution[variables[i]] for i in variablesInFormula])
    else:
        return (formula, None)
예제 #13
0
def ExactlyOnce(l):
    global expression

    atLeast = Cnf()
    for i in l:
        atLeast |= i
    expression &= atLeast
    for i in range(len(l)):
        for j in range(len(l)):
            if i != j:
                expression &= -l[i] | -l[j]
예제 #14
0
파일: sat1.py 프로젝트: mosconi/inf3000
    def exclude_solution(self, solution):

        expr = Cnf()

        for p in self._instance.P:
            for m in self._instance.P:
                if solution.assignment[p, m] == 1:
                    expr |= -self.x[p, m]
                else:
                    expr |= self.x[p, m]

        self.global_expr &= expr
예제 #15
0
def interpret(solution, *args):
    assignment = []
    conflictexpr = Cnf()
    for arg in args:
        assignment.append(solution[arg])
        if solution[arg]:
            conflictexpr &= arg
        else:
            conflictexpr &= -arg

    conflictexpr = -(conflictexpr)

    return (assignment, conflictexpr)
예제 #16
0
def all_xor(eq):
    """
    This is the case of:
        "^^ (aa bb (cc dd))"
    The input eq in above case would be:
        "(aa bb (cc dd))"

    Output would be corresponding to
    EXACTLY one out of:
        aa, bb, (cc dd)
    """

    # Remove the parentheses
    eq = eq.strip()[1:-1]

    # List to hold all SOLVED tokens: [aa, bb, (cc & dd)]
    lst = []

    token, eq = solveToken(eq)
    while token is not None:
        lst.append(token)
        token, eq = solveToken(eq)

    ret = Cnf()

    # Best explained by example: for [a, b, c]
    # it would create
    # (a & -b & -c) | (-a & b & -c) | (-a & -b & c)
    # EXACTLY one of [a, b, c]
    for a in lst:
        tmp = Cnf()
        for b in lst:
            if a == b:
                tmp = tmp & b
            else:
                tmp = tmp & (-b)
        ret = ret | tmp
    return ret
예제 #17
0
def at_most(eq):
    """
    This is the case of:
        "?? (aa bb (cc dd))"
    The input eq in above case would be:
        "(aa bb (cc dd))"

    Output would be corresponding to
    AT MOST one out of:
        aa, bb, (cc dd)
    """

    eq = eq.strip()[1:-1]
    lst = []

    token, eq = solveToken(eq)
    while token is not None:
        lst.append(token)
        token, eq = solveToken(eq)

    ret = Cnf()
    for a in lst:
        tmp = Cnf()
        for b in lst:
            if str(a) == str(b):
                tmp = tmp & b
            else:
                tmp = tmp & (-b)
        ret = ret | tmp
        # Same as xor_all till here

    tmp = Cnf()
    # One extra case in which all are negative
    for b in lst:
        tmp = tmp & (-b)
    ret = ret | tmp

    return ret
예제 #18
0
def all_or(eq):
    # Remove the parentheses
    eq = eq.strip()[1:-1]
    # Create a blank Cnf object
    ret = Cnf()

    # Extract next token and OR with ret variable until you
    # run out of tokens
    token, eq = solveToken(eq)
    while token is not None:
        ret = ret | token
        token, eq = solveToken(eq)

    return ret
예제 #19
0
파일: sat1.py 프로젝트: mosconi/inf3000
    def build_model(self):

        nproc = self._instance.nproc
        nmach = self._instance.nmach
        nserv = self._instance.nserv
        nneigh = len(self._instance.N)
        nloc = len(self._instance.L)

        P = self._instance.P
        M = self._instance.M
        S = self._instance.S
        N = self._instance.N
        L = self._instance.L

        io = DimacsCnf()

        self.x = np.empty((nproc, nmach), dtype=object)
        for p in P:
            for m in M:
                self.x[p, m] = Variable('x[%d,%d]' % (p, m))

        # proc alloc
        all_proc_expr = Cnf()

        for p in P:
            p_expr1 = Cnf()
            p_expr2 = Cnf()
            p_expr3 = Cnf()

            for m1 in M:
                if any(self._instance.R[p] > self._instance.C[m1]):
                    p_expr1 &= -self.x[p, m1]
                else:
                    p_expr1 |= self.x[p, m1]

                    for m2 in range(m1 + 1, nmach):
                        p_expr2 &= self.x[p, m1] >> -self.x[p, m2]

            all_proc_expr &= p_expr1 & p_expr2 & p_expr3

        self.global_expr &= all_proc_expr

        # conflict
        all_conflict_expr = Cnf()

        for m in M:
            for s in S:
                if len(S[s]) == 1: continue
                conflict_expr = Cnf()
                for p1 in range(len(S[s])):
                    for p2 in range(p1 + 1, len(S[s])):
                        conflict_expr &= self.x[S[s][p1],
                                                m] >> -self.x[S[s][p2], m]
                all_conflict_expr &= conflict_expr

        self.global_expr &= all_conflict_expr
예제 #20
0
def reduce_satispy(constraints):
    """
    Reduce constraints from wizards problem into CNF form for our SAT instance.
    :param constraints: inputs from wizard problem
    :return: Cnf object
    """
    mapping = {}
    exp = Cnf()
    for constraint in constraints:
        a, b, c = constraint
        x_1 = touch_variable('%s < %s' % (a, c), mapping)
        x_2 = touch_variable('%s < %s' % (c, a), mapping)
        x_3 = touch_variable('%s < %s' % (b, c), mapping)
        x_4 = touch_variable('%s < %s' % (c, b), mapping)

        exp &= (x_1 | x_2) & (x_3 | x_4) & (-x_1 | -x_4) & (-x_2 | -x_3)

    return exp
예제 #21
0
    def test_sat_lib(self):
        """Sanity check: (x1 v -x2), (-x2), (-x1), (x3 v x1 x x2)"""
        cnf = Cnf()
        x1 = Variable('x1')
        x2 = Variable('x2')
        x3 = Variable('x3')

        solver = Minisat()
        solution = solver.solve(cnf)

        if not solution.success:
            self.fail("Something seriously wrong with this library.")

        true_literals = [x3]
        false_literals = [x1, x2]

        for lit in true_literals:
            self.assertTrue(solution[lit])
        for lit in false_literals:
            self.assertFalse(solution[lit])
예제 #22
0
def all_or(eq):
    """
    This is the case of:
        "|| (aa bb (cc dd))"
    The input eq in above case would be:
        "(aa bb (cc dd))"
    """
    # Remove the parentheses
    eq = eq.strip()[1:-1]
    # Create a blank Cnf object
    ret = Cnf()

    # Extract next token and OR with ret variable until you
    # run out of tokens
    token, eq = solveToken(eq)
    while token is not None:
        ret = ret | token
        token, eq = solveToken(eq)

    return ret
예제 #23
0
def solve(eq):
    eq = eq.strip()
    if eq == '': return Cnf()

    op = re.findall(r'^(\^\^|\|\||\?\?)', eq)
    if op:
        op = op[0]
        if op == '||':
            var, eq = getToken(eq[2:])
            assert var[0] == '(' and var[-1] == ')'
            result = all_or(var)
        elif op == '^^':
            var, eq = getToken(eq[2:])
            assert var[0] == '(' and var[-1] == ')'
            result = all_xor(var)
        elif op == '??':
            var, eq = getToken(eq[2:])
            assert var[0] == '(' and var[-1] == ')'
            result = at_most(var)
        return result & solve(eq)

    op = re.findall(r'^[\w]+\s*\?', eq)
    if op:
        op = op[0]
        eq = eq[len(op):]
        var1 = Variable(op[:-1].strip())
        var2, eq = solveToken(eq)
        return (var1 >> var2) & solve(eq)

    op = re.findall(r'^[\w]+', eq)
    if op:
        op = op[0]
        eq = eq[len(op):]
        var = Variable(op.strip())
        return var & solve(eq)

        # This should ideally never be encountered
    print("I failed", eq)
    exit(1)
    def solve(self, expr):
        """Takes a list of dependent and conflicting packages
        and returns whether the current configuration is satisfiable."""

        dependent = [p for p in expr if '-' not in p]
        conflicting = [p[1:] for p in expr if '-' in p]

        # Generate set of unique package variables.
        variables = {}
        for var in set(dependent + conflicting):
            variables[var] = Variable(var)

        # Generate 'CNF' logical expression from dependencies
        # and conflicts.
        expr = Cnf()

        for con in dependent:
            v = variables[con]
            expr = expr & v

        for con in conflicting:
            v = variables[con]
            expr = expr & -v

        # Calculate the satisfiability of the input variables.
        valid, param = self._check_satisfiability(variables, expr)

        if valid:
            logging.debug(
                "Logical expression, {}, is satisfiable with parameters, {}.".
                format(expr, param))
        else:
            logging.debug(
                "Logical expression, {} , is unsatisfiable.".format(expr))

        return valid, param
예제 #25
0
def readGraphFile():
    graph_file = open('graph.txt', 'r')
    graph = []
    for line in graph_file:
        if line[0] != '#':
            nums = list(map(int, line[:-1].split(' ')))
            graph.append(nums)

    graph_file.close()
    return graph


graph = readGraphFile()

exp = Cnf()
c1 = dict()
c2 = dict()
c3 = dict()

# one of the three colors for a vertex
for vertex in range(VERTICES):
    c1[vertex] = Variable('edge%dhasColor1' % vertex)
    c2[vertex] = Variable('edge%dhasColor2' % vertex)
    c3[vertex] = Variable('edge%dhasColor3' % vertex)

    # one of three
    exp &= c1[vertex] | c2[vertex] | c3[vertex]
    exp &= c1[vertex] | -c2[vertex] | -c3[vertex]
    exp &= -c1[vertex] | c2[vertex] | -c3[vertex]
    exp &= -c1[vertex] | -c2[vertex] | c3[vertex]
예제 #26
0
sudoku = file.readline()

n = 1

while sudoku != '':

########################################################################################
########################################################################################
## Escreva aqui o código gerador da formula CNF que representa o Sudoku codificado na ##
## variavel 'sudoku'. Nao se esqueca que o codigo deve estar no escopo do 'while'     ##
## acima e deve guardar a formula CNF na variavel 'cnf'.                              ##
########################################################################################
########################################################################################

    cnf = Cnf()   
    
    #Configurando o sudoku como uma matriz dos números passados
    sudoku = sudoku.split(';')
    #Quantidade de números passados (Eliminando os dois últimos que são vazios)
    nums=len(sudoku) - 2
    for i in range(nums):
      #Transformando cada número num vetor [i, j, k]
      sudoku[i]=sudoku[i].split(' ')
      #Deixando int
      sudoku[i]=[int(sudoku[i][0]), int(sudoku[i][1]), int(sudoku[i][2])]
      #Colocando os números no tabuleiro
      cnf &= (x[sudoku[i][0]][sudoku[i][1]][sudoku[i][2]])

    #Verificando linha 
      for i in range(4):
예제 #27
0
from satispy import Variable, Cnf
from satispy.solver import Minisat
from math import sqrt

SIZE = 0
expression = Cnf()


def readSudoku(filename):
    global SIZE
    mat = []
    with open(filename) as f:
        lines = f.readlines()
        SIZE = int(lines[0])
        lines = lines[1:]
        for i in range(SIZE):
            l = lines[i]
            mat.append([int(i) for i in l.split()])
    return mat


def ExactlyOnce(l):
    global expression

    atLeast = Cnf()
    for i in l:
        atLeast |= i
    expression &= atLeast
    for i in range(len(l)):
        for j in range(len(l)):
            if i != j:
예제 #28
0
def knight(N=8):
    white_knight_at = [[
        Variable("W_{" + str(i) + str(j) + "}") for i in range(N)
    ] for j in range(N)]
    black_knight_at = [[
        Variable("B_{" + str(i) + str(j) + "}") for i in range(N)
    ] for j in range(N)]

    formula = Cnf()  # the overall formula

    # at least one black and white knight in each row
    for i in range(N):
        oneinthisrow_w = Cnf()
        oneinthisrow_b = Cnf()
        for j in range(N):
            oneinthisrow_w |= white_knight_at[i][j]
            oneinthisrow_b |= black_knight_at[i][j]
        formula &= (oneinthisrow_w & oneinthisrow_b)

    # at least one black and white knight in each column
    for j in range(N):
        oneinthiscolumn_w = Cnf()
        oneinthiscolumn_b = Cnf()
        for i in range(N):
            oneinthiscolumn_w |= white_knight_at[i][j]
            oneinthiscolumn_b |= black_knight_at[i][j] & (
                -white_knight_at[i][j])
        formula &= (oneinthiscolumn_w & oneinthiscolumn_b)

    # Each row and column has exactly 1 black and white knight
    for i1 in range(N):
        for j1 in range(N):
            for i2 in range(N):
                for j2 in range(N):
                    if N * i1 + j1 < N * i2 + j2:  # Eliminate mirrors
                        if (i1 == i2) | (
                                j1 == j2
                        ):  # If two possible placements share the same row or column
                            formula &= ((-white_knight_at[i1][j1]) |
                                        (-white_knight_at[i2][j2])) & (
                                            (-black_knight_at[i1][j1]) |
                                            (-black_knight_at[i2][j2]))

    # Can't attack same color
    for i1 in range(N):
        for j1 in range(N):
            for i2 in range(N):
                for j2 in range(N):
                    if N * i1 + j1 < N * i2 + j2:  # Eliminate mirrors
                        if ((i1 - i2)**2 + (j1 - j2)**2 == 5) & (
                            (i1 - i2 <= 2) &
                            (j1 - j2 <= 2)):  # "L" shape attack
                            formula &= ((-white_knight_at[i1][j1]) |
                                        (-white_knight_at[i2][j2])) & (
                                            (-black_knight_at[i1][j1]) |
                                            (-black_knight_at[i2][j2]))

    # White must attack at least one enemy
    for i1 in range(N):
        for j1 in range(N):
            white_must_attack_one = Cnf()
            for i2 in range(N):
                for j2 in range(N):
                    if ((i1 - i2)**2 + (j1 - j2)**2 == 5) & (
                        (i1 - i2 <= 2) & (j1 - j2 <= 2)):  # "L" shape attack
                        white_must_attack_one |= (white_knight_at[i1][j1]) & (
                            black_knight_at[i2][j2])
            formula &= (white_knight_at[i1][j1] >> white_must_attack_one)

    # Black must attack at least one enemy
    for i1 in range(N):
        for j1 in range(N):
            black_must_attack_one = Cnf()
            for i2 in range(N):
                for j2 in range(N):
                    if ((i1 - i2)**2 + (j1 - j2)**2 == 5) & (
                        (i1 - i2 <= 2) & (j1 - j2 <= 2)):  # "L" shape attack
                        black_must_attack_one |= (black_knight_at[i1][j1]) & (
                            white_knight_at[i2][j2])
            formula &= (black_knight_at[i1][j1] >> black_must_attack_one)

    solution = Minisat().solve(formula)

    if solution.error is True:
        print("Error: " + solution.error)
    elif solution.success:
        chessboard = ""
        for i in range(N):
            for j in range(N):
                if solution[white_knight_at[i][j]]:
                    chessboard += "1"
                elif solution[black_knight_at[i][j]]:
                    chessboard += "2"
                else:
                    chessboard += "0"
            chessboard += "\n"
        print(chessboard)
    else:
        print("No valid solution")
예제 #29
0
from satispy import Variable, Cnf
from satispy.solver import Minisat
import random
import math
n=8
team= n
week =n-1
period=int(n/2)

exp = Cnf()


sol={}
#Creation des variables :
for w in range(week):
    sol[w]={}
    for p in range(period):
        sol[w][p]=[]

        for length_team in range(team):
            v0 = Variable(str(w)+str(p)+str(length_team))
            sol[w][p].append(v0)




#C1 Une équipe joue contre une autre
for w in range(week):
    for p in range(period):
        c = Cnf()
        for t in range(team):
예제 #30
0
def solve(nrow, ncol, pieces):
    t0 = time.time()
    npieces = len(pieces)
    formula = Cnf()

    # create literals
    lits = []
    for i in range(nrow):
        row = []
        for j in range(ncol):
            col = []
            for k in range(npieces):
                piece = []
                for l in range(4):
                    piece.append(
                        Variable("x_{0}_{1}_{2}_{3}".format(i, j, k, l)))
                col.append(piece)
            row.append(col)
        lits.append(row)
    t1 = time.time()
    print("Time spent to create the literals:", t1 - t0)

    # construct formula

    # constraints set 1 : exactly one square by case
    for i in range(nrow):
        for j in range(ncol):
            squares = []
            for piece in lits[i][j]:
                for square in piece:
                    squares.append(square)
            formula &= exactly_one(squares)
    t2 = time.time()
    print("Time spent to build the first constraint set", t2 - t1)

    # constraints set 2 : exactly one case by square
    for k in range(len(pieces)):
        for l in range(4):
            cases = []
            for row in lits:
                for col in row:
                    cases.append(col[k][l])
            formula &= exactly_one(cases)
    t3 = time.time()
    print("Time spent to build the second constraint set", t3 - t2)

    # constraints set 3 : pieces shapes
    for i in range(nrow):
        for j in range(ncol):
            for k in range(npieces):
                if pieces[k] == 1:  # bar
                    orientation1 = orientation(lits, i, j + 1, i, j + 2, i,
                                               j + 3, k)
                    orientation2 = orientation(lits, i + 1, j, i + 2, j, i + 3,
                                               j, k)
                    clause = lits[i][j][k][0] >> (orientation1 | orientation2)
                elif pieces[k] == 2:  # 2*2 square
                    orientation1 = orientation(lits, i, j + 1, i + 1, j, i + 1,
                                               j + 1, k)
                    clause = lits[i][j][k][0] >> orientation1
                elif pieces[k] == 3:  # L
                    orientation1 = orientation(lits, i + 1, j, i + 2, j, i + 2,
                                               j + 1, k)
                    orientation2 = orientation(lits, i, j + 1, i, j + 2, i - 1,
                                               j + 2, k)
                    orientation3 = orientation(lits, i - 1, j, i - 2, j, i - 2,
                                               j - 1, k)
                    orientation4 = orientation(lits, i, j - 1, i, j - 2, i + 1,
                                               j - 2, k)
                    clause = lits[i][j][k][0] >> (orientation1 | orientation2 |
                                                  orientation3 | orientation4)
                elif pieces[k] == 4:  # reversed L
                    orientation1 = orientation(lits, i + 1, j, i + 2, j, i + 2,
                                               j - 1, k)
                    orientation2 = orientation(lits, i, j + 1, i, j + 2, i + 1,
                                               j + 2, k)
                    orientation3 = orientation(lits, i - 1, j, i - 2, j, i - 2,
                                               j + 1, k)
                    orientation4 = orientation(lits, i, j - 1, i, j - 2, i - 1,
                                               j - 2, k)
                    clause = lits[i][j][k][0] >> (orientation1 | orientation2 |
                                                  orientation3 | orientation4)
                elif pieces[k] == 5:  # snake
                    orientation1 = orientation(lits, i, j + 1, i - 1, j + 1,
                                               i - 1, j + 2, k)
                    orientation2 = orientation(lits, i + 1, j, i + 1, j + 1,
                                               i + 2, j + 1, k)
                    clause = lits[i][j][k][0] >> (orientation1 | orientation2)
                elif pieces[k] == 6:  # reversed snake
                    orientation1 = orientation(lits, i, j + 1, i + 1, j + 1,
                                               i + 1, j + 2, k)
                    orientation2 = orientation(lits, i + 1, j, i + 1, j - 1,
                                               i + 2, j - 1, k)
                    clause = lits[i][j][k][0] >> (orientation1 | orientation2)
                elif pieces[k] == 7:  # castle
                    orientation1 = orientation(lits, i + 1, j - 1, i + 1, j,
                                               i + 1, j + 1, k)
                    orientation2 = orientation(lits, i - 1, j - 1, i, j - 1,
                                               i + 1, j - 1, k)
                    orientation3 = orientation(lits, i - 1, j - 1, i - 1, j,
                                               i - 1, j + 1, k)
                    orientation4 = orientation(lits, i - 1, j + 1, i, j + 1,
                                               i + 1, j + 1, k)
                    clause = lits[i][j][k][0] >> (orientation1 | orientation2 |
                                                  orientation3 | orientation4)
                formula &= clause
    t2 = time.time()
    print("Time spent to build the third constraint set", t2 - t1)

    # solve using minisat
    solver = Minisat()
    t3 = time.time()
    print("Time spent to solve the SAT problem", t3 - t2)
    print("Total time", t3 - t0)
    return solver.solve(formula), lits
예제 #31
0
def sat(instance):
    expr = Cnf()

    nproc = instance.nproc
    nmach = instance.nmach
    nserv = instance.nserv
    nneigh = len(instance.N)
    nloc = len(instance.L)

    P = instance.P
    M = instance.M
    S = instance.S
    N = instance.N
    L = instance.L

    print(" %10.3f creating vars - x" % (time() - all_start))
    x = np.empty((nproc, nmach), dtype=object)
    for p in P:
        for m in M:
            x[p, m] = Variable('x[%d,%d]' % (p, m))

    print(" %10.3f creating vars - h" % (time() - all_start))
    h = np.empty((nserv, nneigh), dtype=object)
    for s in S:
        for n in N:
            h[s, n] = Variable('h[%d,%d]' % (s, n))

    print(" %10.3f creating vars - o" % (time() - all_start))
    o = np.empty((nserv, nloc), dtype=object)
    for s in S:
        for l in L:
            o[s, l] = Variable('o[%d,%d]' % (s, l))

    print(" %10.3f H[s,n]" % (time() - all_start))
    for s in S:
        #print(" %10.3f H[%6d,n]" %( time() - all_start,s))
        for n in N:
            pres_expr = Cnf()
            for p in S[s]:
                for m in N[n]:
                    pres_expr |= x[p, m]

            expr &= h[s, n] >> pres_expr
            expr &= pres_expr >> h[s, n]
            for sd in instance.sdep[s]:
                expr &= h[s, n] >> h[sd, n]

    print(" %10.3f O[s,l]" % (time() - all_start))
    for s in S:
        #print(" %10.3f O[%6d,l]" %( time() - all_start,s))
        if instance.delta[s] == 1: continue
        for l in L:
            pres_expr = Cnf()
            for p in S[s]:
                for m in L[l]:
                    pres_expr |= x[p, m]

            expr &= o[s, l] >> pres_expr
            expr &= pres_expr >> o[s, l]

    print(" %10.3f X[p,m]" % (time() - all_start))

    for p in P:
        #print(" %10.3f X[%6d, m]" %( time() - all_start, p))
        p_constr1 = Cnf()
        p_constr2 = Cnf()
        for m in M:
            p_constr1 |= x[p, m]

            for m2 in range(m + 1, nmach):
                p_constr2 &= x[p, m] >> -x[p, m2]
        expr &= p_constr1 & p_constr2

    print(" %10.3f X[p,m] - conflito" % (time() - all_start))

    for m in M:
        for s in S:
            conf_constr = Cnf()
            if len(S[s]) == 1: continue
            for i1 in range(len(S[s])):
                for i2 in range(i1 + 1, len(S[s])):
                    conf_constr &= x[S[s][i1], m] >> -x[S[s][i2], m]
            expr &= conf_constr

    print(" %10.3f solving" % (time() - all_start))

    io = DimacsCnf()
    #s = io.tostring(expr)
    #print(s)
    solver = Minisat('minisat %s %s')

    solution = solver.solve(expr)
    print(" %10.3f done" % (time() - all_start))

    if not solution.success:
        print(" %10.3f sem solucao" % (time() - all_start))
        exit(0)

    print(" %10.3f solucao" % (time() - all_start))

    xsol = np.empty((nproc, nmach), dtype=np.int32)
    for p in P:
        for m in M:
            #print(p,m,solution[x[p,m]])
            #print(io.varname(x[p,m]))
            xsol[p, m] = solution[x[p, m]]

    print(xsol)
    print(np.all(xsol.sum(axis=1) == 1))
    for m in M:
        print(instance.mach_validate(m, xsol[:, m]))