题目描述
有一个6*6的棋盘,每个棋盘上都有一个数值,现在又一个起始位置和终止位置,请找出一个从起始位置到终止位置代价最小的路径: 1、只能沿上下左右四个方向移动 2、总代价是没走一步的代价之和 3、每步(从a,b到c,d)的代价是c,d上的值与其在a,b上的状态的乘积 4、初始状态为1 每走一步,状态按如下公式变化:(走这步的代价%4)+1。
输入描述:
每组数据一开始为6*6的矩阵,矩阵的值为大于等于1小于等于10的值,然后四个整数表示起始坐标和终止坐标。
输出描述:
输出最小代价。
示例1
输入
复制
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 5 5
输出
复制
23
有俩种方法,第一种直接广搜,第二种启发式搜索,优先搜索代价小的路径。不过最后比较搜索的节点变化不大,就当练习使用优先级队列和A*算法了。
广搜:
import Queue
class state():
def __init__(self,row,col,s):
self.row=row
self.col=col
self.s=s
def get_input():
chart=[]
for i in range(6):
num=raw_input()
tem=[]
for each in num.split(" "):
tem.append(int(each))
chart.append(tem)
num=raw_input().split(" ")
start_r,start_c,end_r,end_c=int(num[0]),int(num[1]),int(num[2]),int(num[3])
return chart,start_r,start_c,end_r,end_c
def min_cost():
#chart, start_r, start_c, end_r, end_c=get_input()
chart=[]
for i in range(6):
tem=[]
for j in range(6):
tem.append(1)
chart.append(tem)
start_r, start_c, end_r, end_c=0,0,5,5
each_state=[]
for i in range(6):
tem0=[]
for j in range(6):
tem0.append([-1]*5)
each_state.append(tem0)
q=Queue.Queue()
direction=[[0,1],[1,0],[-1,0],[0,-1]]
start_node=state(start_r,start_c,1)
each_state[start_node.row][start_node.col][start_node.s]=0
q.put(start_node)
time=0
while not q.empty():
tem_node=q.get()
time+=1
#print tem_node.row,tem_node.col,tem_node.s,each_state[tem_node.row][tem_node.col][tem_node.s]
for each in direction:
new_row,new_col=tem_node.row+each[0],tem_node.col+each[1]
if new_row>=0 and new_row<6 and new_col>=0 and new_col<6:
cost=tem_node.s*chart[new_row][new_col]
new_cost=cost+each_state[tem_node.row][tem_node.col][tem_node.s]
new_s = cost%4 + 1
if each_state[new_row][new_col][new_s]<0 or new_cost<each_state[new_row][new_col][new_s]:
new_s=tem_node.s*chart[new_row][new_col]%4+1
new_node=state(new_row,new_col,new_s)
q.put(new_node)
each_state[new_row][new_col][new_s]=new_cost
min_c=-1
for each in each_state[end_r][end_c]:
if each>=0 and (min_c==-1 or (min_c>=0 and each<min_c)):
min_c=each
print min_c
print time
min_cost()
A*:
import Queue
class state():
def __init__(self,row,col,s,cost):
self.row=row
self.col=col
self.s=s
self.cost=cost
def __cmp__(self, other):
return cmp(self.cost,other.cost)
def get_input():
chart=[]
for i in range(6):
num=raw_input()
tem=[]
for each in num.split(" "):
tem.append(int(each))
chart.append(tem)
num=raw_input().split(" ")
start_r,start_c,end_r,end_c=int(num[0]),int(num[1]),int(num[2]),int(num[3])
return chart,start_r,start_c,end_r,end_c
def min_cost():
#chart, start_r, start_c, end_r, end_c=get_input()
chart=[]
for i in range(6):
tem=[]
for j in range(6):
tem.append(1)
chart.append(tem)
start_r, start_c, end_r, end_c=0,0,5,5
each_cost=[]
for i in range(6):
tem0=[]
for j in range(6):
tem0.append([-1]*5)
each_cost.append(tem0)
q=Queue.PriorityQueue()
direction=[[0,1],[1,0],[-1,0],[0,-1]]
start_node=state(start_r,start_c,1,0)
each_cost[start_node.row][start_node.col][start_node.s]=0
q.put(start_node)
minimal_cost=-1
time=0
while not q.empty():
current_node=q.get()
time+=1
if (current_node.row == end_r and current_node.col == end_c) and (minimal_cost < 0 or current_node.cost < minimal_cost):
minimal_cost = current_node.cost
#print current_node.row,current_node.col,current_node.s,current_node.cost
for each in direction:
new_row, new_col = current_node.row + each[0], current_node.col + each[1]
if new_row >= 0 and new_row < 6 and new_col >= 0 and new_col < 6:
cost = current_node.s * chart[new_row][new_col]
new_cost = cost + each_cost[current_node.row][current_node.col][current_node.s]
new_s = cost % 4 + 1
if minimal_cost<0 or (minimal_cost>=0 and new_cost<minimal_cost):
if each_cost[new_row][new_col][new_s] < 0 or new_cost < each_cost[new_row][new_col][new_s]:
new_node = state(new_row, new_col, new_s,new_cost)
q.put(new_node)
each_cost[new_row][new_col][new_s] = new_cost
print minimal_cost
print time
min_cost()
本文介绍了一种寻找从起点到终点代价最小路径的方法,适用于6*6棋盘,每格有固定数值,路径代价由行走方向和当前位置数值决定。提供了广度优先搜索和A*算法两种解决方案。
581

被折叠的 条评论
为什么被折叠?



