人材獲得なんちゃらとかいう少し前に流行った問題を解いてみる。時代おくれの人間。
といっても書いたコードはPythonでA*(A-Star)アルゴリズムに多くを負っている。
ソースコード
# -*- coding: utf-8 -*- problem = """************************** *S* * * * * * * ************* * * * * ************ * * * * ************** *********** * * ** *********************** * * G * * * *********** * * * * ******* * * * * * **************************""".split("\n") problem = map(list, problem) class Node(): start = None goal = None def __init__(self, x, y): self.x = x self.y = y self.pos = (x, y) self.parent_node = None self.h_star = abs(x - self.goal[0]) + abs(y - self.goal[1]) self.f_star = 0 class NodeList(list): def find(self, n): l = [t for t in self if t.pos==n.pos] return l[0] if l != [] else None def remove(self,node): del self[self.index(node)] def searchPoint(problem, point): x = y = 0 for indexY, line in enumerate(problem): for indexX, char in enumerate(line): if char is point: x = indexX y = indexY break return (x, y) directions = [(0, 1), (1, 0), (-1, 0), (0, -1)] Node.start = searchPoint(problem, 'S') Node.goal = searchPoint(problem, 'G') Start = Node(*Node.start) Start.f_star = Start.h_star Goal = Node(*Node.goal) openList = NodeList() closeList = NodeList() def fPrime(n, m): gStar = lambda n, m: n.f_star - n.h_star hStar = lambda m: m.h_star cost = lambda n, m: (m.x - n.x) + (m.y - n.y) return gStar(n, m) + hStar(m) + cost(n, m) openList.append(Start) while openList: n = min(openList, key=lambda x: x.f_star) openList.remove(n) closeList.append(n) if n.pos == Node.goal: end_node = n break for direction in directions: m = Node(n.x + direction[0], n.y + direction[1]) if problem[m.y][m.x] is '*': continue om = openList.find(m) cm = closeList.find(m) fp = fPrime(n, m) om_fp = fPrime(n, om) if om else None cm_fp = fPrime(n, cm) if cm else None if om is None and cm is None: m.parent_node = n m.f_star = fp openList.append(m) elif not om is None and om_fp < om.f_star: om.parent_node = n om.f_star = om_fp elif not cm is None and cm_fp < cm.f_star: cm.f_star = cm_fp closeList.remove(cm) openList.append(cm) n = end_node.parent_node while n: problem[n.y][n.x] = '$' n = n.parent_node for p in problem: print "".join(p)