IDA* 迭代加深A star算法解决15数码问题——python实现

 

1 IDA* Algorithm

1.1 Description
Iterative deepening A* (IDA*) was first described by Richard Korf in 1985, which is a graph traversal
and path search algorithm that can find the shortest path between a designated start node and any
member of a set of goal nodes in a weighted graph.
It is a variant of iterative deepening depth-first search that borrows the idea to use a
heuristic function to evaluate the remaining cost to get to the goal from the A* search algorithm.
Since it is a depth-first search algorithm, its memory usage is lower than in A*, but unlike ordinary
iterative deepening search, it concentrates on exploring the most promising nodes and thus does not
go to the same depth everywhere in the search tree.
Iterative-deepening-A* works as follows: at each iteration, perform a depth-first search,
cutting off a branch when its total cost f( n) = g( n) + h( n) exceeds a given threshold. This threshold
starts at the estimate of the cost at the initial state, and increases for each iteration of the algorithm.
At each iteration, the threshold used for the next iteration is the minimum cost of all values that
exceeded the current threshold.

1.2 Pseudo code

 

2 Tasks

Please solve 15-Puzzle problem by using IDA* . You can use one of the two commonly used heuristic functions: h1 = the number of misplaced tiles. h2 = the sum of the distances of the tiles from their goal positions.

 

3 Codes
 

target = {}
num = 1
for i in range(4):
	for j in range(4):
		target[num] = (i, j)
		num += 1
		
	target[0] = (3, 3)

def h(node):
	cost = 0
	for i in range(4):
		for j in range(4):
			num = node[i][j]
			x, y = target[num]
			cost += abs(x-i) + abs(y-j)
	
	return cost
	
def successors(node):
	x, y = 0, 0
	for i in range(4):
		for j in range(4):
			if(node[i][j] == 0):
				x, y = i, j
	success = []
	moves = [(1, 0), (-1, 0), (0, 1), (0, -1)]
	for i, j in moves:
		a, b = x+i, y+j
		if(a<4 and a>-1 and b<4 and b>-1):
			temp = [[num for num in col] for col in node]
			temp[x][y] = temp[a][b]
			temp[a][b] = 0
			success.append(temp)
			
	return sorted(success, key=lambda x: h(x))
	
def is_goal(node):
	index = 1
	for row in node:
		for col in row:
			if(index != col):
				break
			index += 1
	return index == 16
		
def search(path, g, bound):
	node = path[-1]
	f = g + h(node)
	if(f > bound):
		return f
	if(is_goal(node)):
		return -1
	
	Min = 9999
	for succ in successors(node):
		if succ not in path:
			path.append(succ)
			t = search(path, g+1, bound)
			if(t == -1):
				return -1
			if(t < Min):
				Min = t;
			path.pop()
			
	return Min

def ida_star(root):
	bound = h(root)
	path = [root]
	
	while(True):
		t = search(path, 0, bound)
		if(t == -1):
			return (path, bound)
		if(t > 70):
			return ([], bound)
		
		bound = t
		
def load():
	# root = [2,  7,  5,  3], [11, 10,  9, 14], [4,  0,  1,  6], [4,  0,  1,  6]
	# root = [[11, 3, 1, 7], [4, 6, 8, 2], [15, 9, 10, 13], [14, 12, 5, 0]]
	root = [[5, 1, 3, 4], [2, 7, 8, 12], [9, 6, 11, 15], [0, 13, 10, 14]]
	# root = [[6, 10, 3, 15], [14, 8, 7, 11], [5, 1, 0, 2], [13, 12, 9, 4]]
	return root

root = load()	
(path, bound) = ida_star(root)
step = 0
for p in path:
	print('step', step)
	step += 1
	for row in p:
		print(row)
		
print('bound', bound)

 

 

4 Results

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值