Skip to content

Commit 89ca95c

Browse files
committed
bugfix/feature: support values <1 for weighted graphs
1 parent 71fee0b commit 89ca95c

File tree

8 files changed

+29
-20
lines changed

8 files changed

+29
-20
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# 1.0.13
2+
## Features/Bugfix
3+
- allow for path finding with float values as cost.
4+
15
# 1.0.12
26
## Bugfixes
37
- fix for passable borders (see #62, merges #63)

pathfinding/core/graph.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ def neighbors(self, node: GraphNode, **kwargs):
4949
if edge[1] == node]
5050
return nodes
5151

52-
def calc_cost(self, node_a, node_b, weighted=False):
52+
def calc_cost(self, node_a, node_b, _weighted=False):
5353
for edge in self.edges:
5454
if edge[0].node_id == node_a.node_id and \
5555
edge[1].node_id == node_b.node_id:

pathfinding/core/grid.py

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,12 @@ def build_nodes(
2525
for x in range(width):
2626
# 0, '0', False will be obstacles
2727
# all other values mark walkable cells.
28-
# you can use values bigger then 1 to assign a weight.
28+
# you can use values bigger then 0 to assign a weight.
2929
# If inverse is False it changes
3030
# (1 and up becomes obstacle and 0 or everything negative marks a
3131
# free cells)
32-
weight = int(matrix[y][x]) if use_matrix else 1
33-
walkable = weight <= 0 if inverse else weight >= 1
32+
weight = float(matrix[y][x]) if use_matrix else 1
33+
walkable = weight <= 0.0 if inverse else weight > 0
3434

3535
nodes[y].append(GridNode(
3636
x=x, y=y, walkable=walkable, weight=weight, grid_id=grid_id))
@@ -121,9 +121,6 @@ def neighbors(
121121
neighbors = []
122122
north = nw = east = ne = south = se = west = sw = False
123123

124-
lr = self.passable_left_right_border
125-
ud = self.passable_up_down_border
126-
127124
# ↑
128125
if y == 0 and self.passable_up_down_border:
129126
north_y = self.height - 1
@@ -143,7 +140,7 @@ def neighbors(
143140
if self.walkable(east_x, y):
144141
neighbors.append(self.nodes[y][east_x])
145142
east = True
146-
143+
147144
# ↓
148145
if y == self.height - 1 and self.passable_up_down_border:
149146
south_y = 0
@@ -207,7 +204,7 @@ def neighbors(
207204
ne_y = y - 1
208205
if self.walkable(ne_x, ne_y):
209206
neighbors.append(self.nodes[ne_y][ne_x])
210-
207+
211208
# ↘
212209
if se:
213210
if x == self.width - 1 and self.passable_left_right_border:
@@ -273,9 +270,9 @@ def grid_str(self, path=None, start=None, end=None,
273270
data = ''
274271
if border:
275272
data = f'+{"-" * len(self.nodes[0])}+'
276-
for y in range(len(self.nodes)):
273+
for y, _ in enumerate(self.nodes):
277274
line = ''
278-
for x in range(len(self.nodes[y])):
275+
for x, _ in enumerate(self.nodes[y]):
279276
node = self.nodes[y][x]
280277
if node == start:
281278
line += start_chr

pathfinding/core/node.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ class GridNode(Node):
7777
walkable: bool = True
7878

7979
# used for weighted algorithms
80-
weight: float = 1.0
80+
weight: float = 0.0
8181

8282
# grid_id is used if we have more than one grid,
8383
# normally we just count our grids by number

pathfinding/finder/finder.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import heapq # used for the so colled "open list" that stores known nodes
21
import time # for time limitation
32
from ..core.grid import Grid
43
from ..core.diagonal_movement import DiagonalMovement
@@ -74,7 +73,14 @@ def apply_heuristic(self, node_a, node_b, heuristic=None, graph=None):
7473
if graph.passable_up_down_border and dy > graph.height / 2:
7574
dy = graph.height - dy
7675

77-
return heuristic(dx, dy)
76+
nh = heuristic(dx, dy)
77+
# in a weighted graph we also need to multiply the calculated
78+
# value with the weight of the node
79+
if self.weighted:
80+
nh *= node_a.weight
81+
return nh
82+
else:
83+
return heuristic(dx, dy)
7884

7985
def find_neighbors(self, grid, node, diagonal_movement=None):
8086
'''

setup.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,16 @@
22
from setuptools import find_packages, setup
33

44

5-
with open("README.md", "r") as fh:
5+
with open("README.md", "r", encoding='utf-8') as fh:
66
long_description = fh.read()
77

88
setup(
99
name="pathfinding",
10-
description="Pathfinding algorithms (based on Pathfinding.JS)",
10+
description="Path finding algorithms (based on Pathfinding.JS)",
1111
long_description=long_description,
1212
long_description_content_type="text/markdown",
1313
url="https://github.com/brean/python-pathfinding",
14-
version="1.0.12",
14+
version="1.0.13",
1515
license="MIT",
1616
author="Andreas Bresser",
1717
packages=find_packages(),

test/path_test_scenarios.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,12 +102,13 @@
102102
"passableLeftRightBorder": true
103103
},
104104
{
105+
"name": "s7",
105106
"startX": 0,
106107
"startY": 0,
107108
"endX": 4,
108109
"endY": 0,
109110
"matrix": [
110-
[0.01, 0.02, 0.99, 0.09, 0.01],
111+
[0.01, 0.02, 0.09, 0.19, 0.01],
111112
[0.01, 0.02, 0, 0, 0.01],
112113
[0.01, 0.01, 0, 0.01, 0.01],
113114
[0.08, 0.03, 0, 0.01, 0.01],

test/test_path.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ def test_path():
5353
if weighted and not finder.weighted:
5454
continue
5555
path, _ = finder.find_path(start, end, grid)
56-
print(find.__name__)
56+
print(scenario['name'], find.__name__)
5757
print(grid.grid_str(path=path, start=start, end=end,
5858
show_weight=weighted))
5959
print('path: {}'.format(path))
@@ -75,7 +75,8 @@ def test_path_diagonal():
7575
continue
7676

7777
path, runs = finder.find_path(start, end, grid)
78-
print(find.__name__, runs, len(path))
78+
print(scenario['name'], find.__name__, runs, len(path))
79+
print(grid.grid_str(start=start, end=end))
7980
print(grid.grid_str(path=path, start=start, end=end,
8081
show_weight=weighted))
8182
print('path: {}'.format(path))

0 commit comments

Comments
 (0)