Futoshiki solving wih GAC using Python

代码实现:

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()

输出结果:

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值