代码实现:
import time
import queue
size = 0
def read(string):
global size
board = []
small, large = {}, {}
with open(string) as f:
line = f.readline()
size = int(line)
for _ in range(size):
line = f.readline()
nums = [int(num) for num in line.rstrip().split(' ')]
board.append(nums)
lines = f.readlines()
for line in lines:
a, b, c, d = [int(num) for num in line.rstrip().split(' ')]
left, right = (a, b), (c, d)
if(left in small):
small[left].append(right)
else:
small[left] = [right]
if(right in large):
large[right].append(left)
else:
large[right] = [left]
relation = (small, large)
return board, relation
def relation_fail(values, relation, x, y, now):
small, large = relation
if((x, y) in small):
for a, b in small[(x, y)]:
for value in values[a][b]:
if(now < value):
return False
return True
if((x, y) in large):
for a, b in large[(x, y)]:
for value in values[a][b]:
if(now > value):
return False
return True
return False
def dfs(values, relation, index, n, now, visited):
if now == size:
return True
if(index == 0):
x, y = n, now
else:
x, y = now, n
for value in values[x][y]:
if(visited[value-1] or relation_fail(values, relation, x, y, value)):
continue
visited[value-1] = True
if(dfs(values, relation, index, n, now+1, visited)):
return True
visited[value-1] = False
return False
def A(values, relation, index, n, x, y, value):
visited = [False for _ in range(size)]
before = list(values[x][y])
values[x][y] = [value]
flag = dfs(values, relation, index, n, 0, visited)
values[x][y] = before
return flag
def DWO(values, relation, x, y, num):
constraints = [[False for _ in range(size)] for _ in range(2)]
GACQueue = queue.Queue()
# 0 means row, 1 means column
GACQueue.put((0, x))
GACQueue.put((1, y))
constraints[0][x] = True
constraints[1][y] = True
while(not GACQueue.empty()):
index, n = GACQueue.get()
constraints[index][n] = False
for a in range(size):
if(index == 0):
x, y = n, a
else:
x, y = a, n
temp = list(values[x][y])
for now in temp:
if(A(values, relation, index, n, x, y, now) == False):
values[x][y] = [value for value in values[x][y] if value != now]
if(not values[x][y]):
return True
else:
GACQueue.put((index, n))
constraints[index][n] = True
if(constraints[1-index][a] == False):
GACQueue.put((1-index, a))
constraints[1-index][a] = True
return False
def deepcopy(a):
b = []
for row in a:
temp_row = []
for col in row:
temp = list(col)
temp_row.append(temp)
b.append(temp_row)
return b
def initial(board, relation):
values = []
assign = [[False for _ in range(size)] for _ in range(size)]
for row in board:
value_row = []
for index in row:
if(index == 0):
value = [a for a in range(1, size+1)]
value_row.append(value)
else:
value_row.append([index])
values.append(value_row)
for a in range(size):
for b in range(size):
if(board[a][b] != 0):
assign[a][b] = True
DWO(values, relation, a, b, board[a][b])
return (values, assign)
def all_assigned(values, assign):
Min = 999
x, y = -1, -1
for a in range(size):
for b in range(size):
l = len(values[a][b])
if(assign[a][b]==False and l<Min):
Min = l
x = a
y = b
return (x, y)
def printf(board):
for row in board:
for index in row:
print(str(index), end = ' ')
print('')
def GAC(values, relation, assign, board):
(x, y) = all_assigned(values, assign)
if((x, y) == (-1, -1)):
return True
assign[x][y] = True
members = list(values[x][y])
for num in members:
board[x][y] = num
temp_values = deepcopy(values)
values[x][y] = [num]
if(DWO(values, relation, x, y, num) == False):
flag = GAC(values, relation, assign, board)
if(flag):
return True
values = deepcopy(temp_values)
assign[x][y] = False
return False
def run_test(string):
board, relation = read(string)
begin = time.time()
values, assign = initial(board, relation)
flag = GAC(values, relation, assign, board)
end = time.time()
if(flag):
printf(board)
print('Time:', end-begin, 's')
else:
print('No Solution!')
print('')
for a in range(1, 6):
print('Test case', a, ':')
string = 'data_test_case_'+str(a)+'.txt'
run_test(string)
Case1:
4
0 0 3 0
0 0 0 0
0 0 0 0
0 0 0 0
0 1 1 1
0 3 0 2
1 2 2 2
3 1 3 0
3 2 3 1
Case2:
5
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 4
0 1 0 0
0 0 1 0
1 1 1 2
1 2 1 3
1 3 1 4
2 1 2 2
4 1 4 0
Case3:
6
0 0 0 0 2 6
0 0 0 0 0 3
3 0 0 0 0 0
0 0 4 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 1 0 0
2 1 1 1
1 4 1 3
1 5 2 5
2 0 2 1
3 3 3 2
3 4 3 3
5 3 5 4
5 4 5 5
Case4:
7
0 0 0 0 0 0 6
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 2
0 0 0 0 0 0 0
0 5 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 1
0 2 0 1
0 6 0 5
2 2 1 2
1 5 1 4
2 0 2 1
2 1 2 2
2 4 3 4
2 6 2 5
3 1 3 2
4 1 3 1
3 3 4 3
3 5 3 4
4 2 4 1
5 2 4 2
5 0 5 1
5 4 6 4
6 5 5 5
6 6 6 5
Case5:
8
0 0 0 0 0 0 0 0
0 0 0 0 6 0 7 0
0 0 0 4 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 6
0 0 0 0 0 4 0 0
0 0 0 0 0 0 0 3
0 0 0 0 0 0 0 0
0 2 0 1
0 3 0 2
0 4 0 5
0 5 0 6
0 6 0 7
1 0 1 1
1 2 2 2
1 3 2 3
2 5 1 5
1 5 1 6
2 6 1 6
2 2 2 3
3 3 2 3
3 1 3 0
3 2 3 1
4 3 3 3
4 7 3 7
4 1 4 0
4 5 5 5
4 6 4 7
4 7 5 7
6 4 5 4
5 4 5 5
5 6 5 5
6 3 6 2
数据生成:
def generate():
size = 8
strings = [[0 for _ in range(size)] for _ in range(size)]
strings[1][4] = 6
strings[1][6] = 7
strings[2][3] = 4
strings[4][7] = 6
strings[5][5] = 4
strings[6][7] = 3
# 1 < 2 > 3 ^ 4 V
relation = [[[] for _ in range(size)] for _ in range(size)]
relation[0][1].append(2)
relation[0][2].append(2)
relation[0][4].append(1)
relation[0][5].append(1)
relation[0][6].append(1)
relation[1][0].append(1)
relation[1][2].append(3)
relation[1][3].append(3)
relation[1][5].append(4)
relation[1][5].append(1)
relation[1][6].append(4)
# 1 < 2 > 3 ^ 4 V
relation[2][2].append(1)
relation[2][3].append(4)
relation[3][0].append(2)
relation[3][1].append(2)
relation[3][3].append(4)
relation[3][7].append(4)
relation[4][0].append(2)
relation[4][5].append(3)
relation[4][6].append(1)
relation[4][7].append(3)
relation[5][4].append(4)
relation[5][4].append(1)
relation[5][5].append(2)
relation[6][2].append(2)
string = 'data_test_case_5.txt'
with open(string, 'w') as f:
f.write(str(size)+'\n')
for string in strings:
string = ' '.join([str(e) for e in string])
f.write(string+'\n')
for a in range(size):
for b in range(size):
for index in relation[a][b]:
sequence = []
if(index == 0):
continue
elif(index == 1):
sequence = [a, b, a, b+1]
elif(index == 2):
sequence = [a, b+1, a, b]
elif(index == 3):
sequence = [a, b, a+1, b]
else:
sequence = [a+1, b, a, b]
string = ' '.join([str(e) for e in sequence])
f.write(string+'\n')
generate()
输出结果: