-
Notifications
You must be signed in to change notification settings - Fork 74
Expand file tree
/
Copy pathmsp.py
More file actions
66 lines (53 loc) · 2.12 KB
/
msp.py
File metadata and controls
66 lines (53 loc) · 2.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# -*- coding: utf-8 -*-
import heapq
import time
from collections import deque, namedtuple
from ..core import heuristic
from ..finder.finder import Finder
class MinimumSpanningTree(Finder):
"""
Minimum Spanning Tree implementation by Brad Beattie
(see https://github.com/brean/python-pathfinding/issues/18)
The wikipedia page has a nice description about MSP:
https://en.wikipedia.org/wiki/Minimum_spanning_tree
"""
def __init__(self, *args, **kwargs):
super(MinimumSpanningTree, self).__init__(*args, **kwargs)
self.heuristic = heuristic.null
def tree(self, grid, start):
return list(self.itertree(grid, start))
def itertree(self, grid, start):
# Finder.process_node requires an end node, which we don't have.
# The following value tricks the call to Finder.apply_heuristic.
# Though maybe we want to generate a limited spanning tree that
# trends in a certain direction? In which case we'd want a more
# nuanced solution.
end = namedtuple("FakeNode", ["x", "y"])(-1, -1)
start.opened = True
open_list = [start]
while len(open_list) > 0:
self.runs += 1
self.keep_running()
node = heapq.nsmallest(1, open_list)[0]
open_list.remove(node)
node.closed = True
yield node
neighbors = self.find_neighbors(grid, node)
for neighbor in neighbors:
if not neighbor.closed:
self.process_node(
neighbor, node, end, open_list, open_value=True)
def find_path(self, start, end, grid):
self.start_time = time.time() # execution time limitation
self.runs = 0 # count number of iterations
for node in self.itertree(grid, start):
if node == end:
path = deque()
step = node
while step.parent:
path.appendleft(step)
step = step.parent
path.appendleft(step)
return path, self.runs
else:
return [], self.runs