def solve(self): self.boundary_conditions() n = len(self.input_grid) conditions = self.boundary_conditions() + condition1(n) + condition2( n) + condition3(n) BineroIO.write_dimacs( self.PATH + "/output/" + self.filename + ".dimacs", conditions)
def solve(self): # get puzzle dimensions num_rows = len(self.input_grid) num_cols = len(self.input_grid[0]) # declaring matrix of Bool variables X = [[z3.Bool("x_%s_%s" % (i, j)) for i in range(num_rows)] for j in range(num_cols)] # boundary conditions instance_c = [z3.If(self.input_grid[i][j] == None, True, X[i][j] == self.input_grid[i][j]) for i in range(num_rows) for j in range(num_cols)] # sur chaque colonne ou ligne de la grille, il ne peut y avoir plus de deux 0 ou deux 1 consécutifs row_combo = [z3.Implies(X[i][j] == X[i][j + 1], z3.Not(X[i][j + 2] == X[i][j])) for j in range(num_cols - 2) for i in range(num_rows)] ''' TODO not working row_combo = [ z3.And( z3.Or(z3.Not(X[i][j+1]), z3.Not(X[i][j+2])), z3.Or(X[i][j], X[i][j+1], z3.Not(X[i][j+2])), z3.Or(z3.Not(X[i][j]), z3.Not(X[i][j+1]), X[i][j+2]), z3.Or(X[i][j+1], X[i][j+2]) ) for j in range(num_cols-2) for i in range(num_rows)] ''' col_combo = [z3.Implies(X[i][j] == X[i + 1][j], z3.Not(X[i + 2][j] == X[i][j])) for i in range(num_cols - 2) for j in range(num_rows)] # il y a le même nombre de 0 et de 1 sur chaque ligne et chaque colonne combs = set(itertools.permutations( [0 for _ in range(num_rows // 2)] + [1 for _ in range(num_rows // 2)], r=num_rows)) row_par = [z3.Or([z3.And([X[i][j] if coefs[j] == 1 else z3.Not(X[i][j]) for j in range(num_cols)]) for coefs in combs]) for i in range(num_rows)] col_par = [True] # il n’y a pas deux lignes (ou deux colonnes) remplies identiquement row_eg = [True] col_eg = [True] # add condition to the solver binero_c = row_combo + col_combo + row_par + col_par + row_eg + col_eg self.solver.add(instance_c + binero_c) # solve if self.solver.check() == z3.sat: m = self.solver.model() r = [[m.evaluate(X[i][j]) for j in range(num_cols)] for i in range(num_rows)] output_grid = [[1 if r[i][j] == True else 0 for j in range(num_cols)] for i in range(num_rows)] BineroIO.write_binero(self.PATH + "/output/" + self.filename, output_grid) else: print("failed to solve")
def solve(self, cond=[0, 1, 2, 3]): self.boundary_conditions() n = len(self.input_grid) conditions_dict = { 0: self.boundary_conditions(), 1: condition1(n), 2: condition2(n), 3: condition3(n) } binero_c = [] for i in cond: binero_c += conditions_dict[i] BineroIO.write_dimacs(self.PATH + "/output/" + self.fout, binero_c)
def run_minsat(self, fname): start_time = time.time() dimacs = fname + ".dimacs" bin = binero_fnc.Binero_fnc(fname, dimacs) bin.solve() minsat = fname + "_minsat" bashCommand = "minisat" + " " \ + self.PATH + "/output/" + dimacs + " " \ + self.PATH + "/output/" + minsat process = subprocess.Popen(bashCommand.split(), stdout=subprocess.PIPE) output, error = process.communicate() print(output) grid = io.read_minsat(self.PATH + "/output/" + minsat, len(bin.input_grid)) io.write_binero(self.PATH + "/output/" + fname + "_solved", grid) return time.time() - start_time
def test(self, fname, cond=[0, 1, 2, 3]): # write conditions start_time = time.time() dimacs = fname + ".dimacs" bin = binero_fnc.Binero_fnc(fname, dimacs) bin.solve(cond) # solve with minisat minsat = fname + "_minsat" bashCommand = "minisat" + " " \ + self.PATH + "/output/" + dimacs + " " \ + self.PATH + "/output/" + minsat process = subprocess.Popen(bashCommand.split(), stdout=subprocess.PIPE) minsat_time = time.time() - start_time output, error = process.communicate() print(output) # test result if is_sat(output): grid = io.read_minsat(self.PATH + "/output/" + minsat, len(bin.input_grid)) io.write_binero(self.PATH + "/output/" + fname + "_solved", grid) # Solve with z3 tak = Takuzu.Takuzu("../output/" + fname + "_solved") tak.solve(cond=cond) #compare grids print("comperison succesful? " + str(tak.sat)) else: print("unsat")
def __init__(self, filename): # self.filename = filename # abs path of this file self.PATH = os.path.dirname(os.path.abspath(__file__)) # trim file name last_slash = 0 for i, char in enumerate(self.PATH): if char == "/": last_slash = i self.PATH = self.PATH[:last_slash] # dataIn file abs path filename = self.PATH + "/dataIn/" + filename self.input_grid = BineroIO.read_binero(filename)
def solve(self, cond=[0, 1, 2, 3]): # get puzzle dimensions num_rows = len(self.input_grid) num_cols = len(self.input_grid[0]) # declaring matrix of Bool variables X = [[z3.Bool("x_%s_%s" % (i, j)) for i in range(num_rows)] for j in range(num_cols)] # boundary conditions instance_c = [ z3.If(self.input_grid[i][j] == None, True, X[i][j] == self.input_grid[i][j]) for i in range(num_rows) for j in range(num_cols) ] # sur chaque colonne ou ligne de la grille, il ne peut y avoir plus de deux 0 ou deux 1 consécutifs row_combo = [ z3.Implies(X[i][j] == X[i][j + 1], z3.Not(X[i][j + 2] == X[i][j])) for j in range(num_cols - 2) for i in range(num_rows) ] col_combo = [ z3.Implies(X[i][j] == X[i + 1][j], z3.Not(X[i + 2][j] == X[i][j])) for i in range(num_cols - 2) for j in range(num_rows) ] # il y a le même nombre de 0 et de 1 sur chaque ligne et chaque colonne row_par = [ z3.Sum([z3.If(X[i][j], 1, 0) for j in range(num_cols)]) == num_cols / 2 for i in range(num_rows) ] col_par = [ z3.Sum([z3.If(X[j][i], 1, 0) for j in range(num_rows)]) == num_rows / 2 for i in range(num_cols) ] # il n’y a pas deux lignes (ou deux colonnes) remplies identiquement row_eg = [ z3.Or([z3.Not(X[i][k] == X[j][k]) for k in range(num_cols)]) for j in range(num_rows) for i in range(num_rows) if i != j ] col_eg = [ z3.Or([z3.Not(X[k][i] == X[k][j]) for k in range(num_rows)]) for j in range(num_cols) for i in range(num_cols) if i != j ] # add condition to the solver conditions_dict = { 0: instance_c, 1: row_par + col_par, 2: row_combo + col_combo, 3: row_eg + col_eg } # select and conditions binero_c = [] for i in cond: binero_c += conditions_dict[i] self.solver.add(binero_c) # solve if self.solver.check() == z3.sat: self.sat = True m = self.solver.model() r = [[m.evaluate(X[i][j]) for j in range(num_cols)] for i in range(num_rows)] output_grid = [[ 1 if r[i][j] == True else 0 for j in range(num_cols) ] for i in range(num_rows)] BineroIO.write_binero( self.PATH + "/output/" + self.filename + "_solutionSMT", output_grid) else: print("failed to solve")