Skip to content

Commit 74daa07

Browse files
authored
Merge pull request #93 from APLA-Toolbox/critical-path
Added critical path heuristic
2 parents d8ab4d4 + 9c49e22 commit 74daa07

13 files changed

Lines changed: 332 additions & 64 deletions

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,4 +136,5 @@ data.json
136136
pddl-examples/*
137137
data/*
138138
scripts/*
139+
*.txt
139140
!scripts/ipc.py

example-run.txt

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
A* - Delete Relaxation - H_Max
2+
======PLAN (Nodes)=======
3+
['Node { object(NewYork), object(Pittsburgh), object(Toronto), object(Boston), object(Albany), connected(Pittsburgh, Boston), connected(Toronto, Albany), visited(Boston), connected(NewYork, Albany), connected(NewYork, Toronto), connected(Toronto, Pittsburgh), connected(NewYork, Boston), connected(Boston, Pittsburgh), connected(Albany, NewYork), connected(NewYork, Pittsburgh), connected(Albany, Toronto), connected(Boston, NewYork), connected(Pittsburgh, NewYork), at(Boston), connected(Toronto, NewYork), total-cost = 3 | g = 3.00 | h = inf | open = False | closed = True }', 'Node { object(NewYork), object(Pittsburgh), object(Toronto), object(Boston), object(Albany), connected(Pittsburgh, Boston), connected(Toronto, Albany), visited(Boston), connected(NewYork, Albany), connected(NewYork, Toronto), connected(Toronto, Pittsburgh), connected(NewYork, Boston), connected(Boston, Pittsburgh), connected(Albany, NewYork), connected(NewYork, Pittsburgh), connected(Albany, Toronto), connected(Boston, NewYork), connected(Pittsburgh, NewYork), connected(Toronto, NewYork), at(NewYork), visited(NewYork), total-cost = 6 | g = 6.00 | h = inf | open = False | closed = True }', 'Node { object(NewYork), object(Pittsburgh), object(Toronto), object(Boston), object(Albany), connected(Pittsburgh, Boston), connected(Toronto, Albany), visited(Boston), connected(NewYork, Albany), connected(NewYork, Toronto), connected(Toronto, Pittsburgh), at(Albany), connected(NewYork, Boston), connected(Boston, Pittsburgh), connected(Albany, NewYork), visited(Albany), connected(NewYork, Pittsburgh), connected(Albany, Toronto), connected(Boston, NewYork), connected(Pittsburgh, NewYork), connected(Toronto, NewYork), visited(NewYork), total-cost = 9 | g = 9.00 | h = inf | open = False | closed = True }', 'Node { object(NewYork), object(Pittsburgh), object(Toronto), object(Boston), object(Albany), at(Toronto), connected(Pittsburgh, Boston), connected(Toronto, Albany), visited(Boston), connected(NewYork, Albany), connected(NewYork, Toronto), connected(Toronto, Pittsburgh), connected(NewYork, Boston), connected(Boston, Pittsburgh), visited(Toronto), connected(Albany, NewYork), visited(Albany), connected(NewYork, Pittsburgh), connected(Albany, Toronto), connected(Boston, NewYork), connected(Pittsburgh, NewYork), connected(Toronto, NewYork), visited(NewYork), total-cost = 12 | g = 12.00 | h = inf | open = False | closed = True }', 'Node { object(NewYork), object(Pittsburgh), object(Toronto), object(Boston), object(Albany), connected(Pittsburgh, Boston), connected(Toronto, Albany), visited(Boston), connected(NewYork, Albany), connected(NewYork, Toronto), connected(Toronto, Pittsburgh), connected(NewYork, Boston), visited(Pittsburgh), connected(Boston, Pittsburgh), at(Pittsburgh), visited(Toronto), connected(Albany, NewYork), visited(Albany), connected(NewYork, Pittsburgh), connected(Albany, Toronto), connected(Boston, NewYork), connected(Pittsburgh, NewYork), connected(Toronto, NewYork), visited(NewYork), total-cost = 15 | g = 15.00 | h = 15.00 | open = True | closed = False }']
4+
======PLAN (Actions)=======
5+
('move(Pittsburgh, Boston)>', 'total-cost = 3')
6+
('move(Boston, NewYork)>', 'total-cost = 6')
7+
('move(NewYork, Albany)>', 'total-cost = 9')
8+
('move(Albany, Toronto)>', 'total-cost = 12')
9+
('move(Toronto, Pittsburgh)>', 'total-cost = 15')
10+
11+
======METRICS=======
12+
Expanded 17 state(s).
13+
Opened 27 state(s).
14+
Reopened 0 state(s).
15+
Evaluated 21 state(s).
16+
Generated 28 state(s).
17+
Dead ends: 3 state(s).
18+
Runtime: 1.46s.
19+
Total heuristic runtime: 2.37s
20+
Computational weight of heuristic in the search: 162.00%
21+
22+
A* - Delete Relaxation - H_Add
23+
======PLAN (Nodes)=======
24+
['Node { object(NewYork), object(Pittsburgh), object(Toronto), object(Boston), object(Albany), connected(Pittsburgh, Boston), connected(Toronto, Albany), visited(Boston), connected(NewYork, Albany), connected(NewYork, Toronto), connected(Toronto, Pittsburgh), connected(NewYork, Boston), connected(Boston, Pittsburgh), connected(Albany, NewYork), connected(NewYork, Pittsburgh), connected(Albany, Toronto), connected(Boston, NewYork), connected(Pittsburgh, NewYork), at(Boston), connected(Toronto, NewYork), total-cost = 3 | g = 3.00 | h = inf | open = False | closed = True }', 'Node { object(NewYork), object(Pittsburgh), object(Toronto), object(Boston), object(Albany), connected(Pittsburgh, Boston), connected(Toronto, Albany), visited(Boston), connected(NewYork, Albany), connected(NewYork, Toronto), connected(Toronto, Pittsburgh), connected(NewYork, Boston), connected(Boston, Pittsburgh), connected(Albany, NewYork), connected(NewYork, Pittsburgh), connected(Albany, Toronto), connected(Boston, NewYork), connected(Pittsburgh, NewYork), connected(Toronto, NewYork), at(NewYork), visited(NewYork), total-cost = 6 | g = 6.00 | h = inf | open = False | closed = True }', 'Node { object(NewYork), object(Pittsburgh), object(Toronto), object(Boston), object(Albany), connected(Pittsburgh, Boston), connected(Toronto, Albany), visited(Boston), connected(NewYork, Albany), connected(NewYork, Toronto), connected(Toronto, Pittsburgh), at(Albany), connected(NewYork, Boston), connected(Boston, Pittsburgh), connected(Albany, NewYork), visited(Albany), connected(NewYork, Pittsburgh), connected(Albany, Toronto), connected(Boston, NewYork), connected(Pittsburgh, NewYork), connected(Toronto, NewYork), visited(NewYork), total-cost = 9 | g = 9.00 | h = inf | open = False | closed = True }', 'Node { object(NewYork), object(Pittsburgh), object(Toronto), object(Boston), object(Albany), at(Toronto), connected(Pittsburgh, Boston), connected(Toronto, Albany), visited(Boston), connected(NewYork, Albany), connected(NewYork, Toronto), connected(Toronto, Pittsburgh), connected(NewYork, Boston), connected(Boston, Pittsburgh), visited(Toronto), connected(Albany, NewYork), visited(Albany), connected(NewYork, Pittsburgh), connected(Albany, Toronto), connected(Boston, NewYork), connected(Pittsburgh, NewYork), connected(Toronto, NewYork), visited(NewYork), total-cost = 12 | g = 12.00 | h = inf | open = False | closed = True }', 'Node { object(NewYork), object(Pittsburgh), object(Toronto), object(Boston), object(Albany), connected(Pittsburgh, Boston), connected(Toronto, Albany), visited(Boston), connected(NewYork, Albany), connected(NewYork, Toronto), connected(Toronto, Pittsburgh), connected(NewYork, Boston), visited(Pittsburgh), connected(Boston, Pittsburgh), at(Pittsburgh), visited(Toronto), connected(Albany, NewYork), visited(Albany), connected(NewYork, Pittsburgh), connected(Albany, Toronto), connected(Boston, NewYork), connected(Pittsburgh, NewYork), connected(Toronto, NewYork), visited(NewYork), total-cost = 15 | g = 15.00 | h = 15.00 | open = True | closed = False }']
25+
======PLAN (Actions)=======
26+
('move(Pittsburgh, Boston)>', 'total-cost = 3')
27+
('move(Boston, NewYork)>', 'total-cost = 6')
28+
('move(NewYork, Albany)>', 'total-cost = 9')
29+
('move(Albany, Toronto)>', 'total-cost = 12')
30+
('move(Toronto, Pittsburgh)>', 'total-cost = 15')
31+
32+
======METRICS=======
33+
Expanded 17 state(s).
34+
Opened 27 state(s).
35+
Reopened 0 state(s).
36+
Evaluated 21 state(s).
37+
Generated 28 state(s).
38+
Dead ends: 3 state(s).
39+
Runtime: 1.31s.
40+
Total heuristic runtime: 1.22s
41+
Computational weight of heuristic in the search: 93.45%
42+

jupyddl/a_star.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
class AStarBestFirstSearch:
1010
def __init__(self, automated_planner, heuristic_function):
11+
self.time_start = now()
1112
self.automated_planner = automated_planner
1213
self.metrics = Metrics()
1314
self.init = Node(
@@ -30,7 +31,6 @@ def __hash(self, node):
3031
return string.split(sep, 1)[0] + ")"
3132

3233
def search(self, node_bound=float("inf")):
33-
time_start = now()
3434
self.automated_planner.logger.debug(
3535
"Search started at: " + str(timestamp.now())
3636
)
@@ -45,7 +45,7 @@ def search(self, node_bound=float("inf")):
4545
if self.automated_planner.satisfies(
4646
self.automated_planner.problem.goal, current_node.state
4747
):
48-
self.metrics.runtime = now() - time_start
48+
self.metrics.runtime = now() - self.time_start
4949
self.automated_planner.logger.debug(
5050
"Search finished at: " + str(timestamp.now())
5151
)
@@ -95,6 +95,6 @@ def search(self, node_bound=float("inf")):
9595
self.nodes[child_hash] = child
9696
self.open_nodes_n += 1
9797
self.metrics.n_opened += 1
98-
self.metrics.runtime = now() - time_start
98+
self.metrics.runtime = now() - self.time_start
9999
self.automated_planner.logger.warning("!!! No path found !!!")
100100
return None, self.metrics

jupyddl/automated_planner.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,12 @@
44
from .a_star import AStarBestFirstSearch
55
from .greedy_best_first import GreedyBestFirstSearch
66
from .metrics import Metrics
7-
from .heuristics import BasicHeuristic, DeleteRelaxationHeuristic, CriticalPathHeuristic
7+
from .heuristics import (
8+
BasicHeuristic,
9+
DeleteRelaxationHeuristic,
10+
RelaxedCriticalPathHeuristic,
11+
CriticalPathHeuristic,
12+
)
813
import coloredlogs
914
import logging
1015
import julia
@@ -31,6 +36,9 @@ def __init__(self, domain_path, problem_path, log_level="DEBUG"):
3136
"basic/goal_count",
3237
"delete_relaxation/h_add",
3338
"delete_relaxation/h_max",
39+
"relaxed_critical_path/1",
40+
"relaxed_critical_path/2",
41+
"relaxed_critical_path/3",
3442
"critical_path/1",
3543
"critical_path/2",
3644
"critical_path/3",
@@ -166,6 +174,8 @@ def astar_best_first_search(
166174
heuristic = BasicHeuristic(self, heuristic_key)
167175
elif "delete_relaxation" in heuristic_key:
168176
heuristic = DeleteRelaxationHeuristic(self, heuristic_key)
177+
elif "relaxed_critical_path" in heuristic_key:
178+
heuristic = RelaxedCriticalPathHeuristic(self, int(heuristic_key[-1]))
169179
elif "critical_path" in heuristic_key:
170180
heuristic = CriticalPathHeuristic(self, int(heuristic_key[-1]))
171181
else:
@@ -188,6 +198,8 @@ def greedy_best_first_search(
188198
heuristic = BasicHeuristic(self, "basic/goal_count")
189199
elif "delete_relaxation" in heuristic_key:
190200
heuristic = DeleteRelaxationHeuristic(self, heuristic_key)
201+
elif "relaxed_critical_path" in heuristic_key:
202+
heuristic = RelaxedCriticalPathHeuristic(self, int(heuristic_key[-1]))
191203
elif "critical_path" in heuristic_key:
192204
heuristic = CriticalPathHeuristic(self, int(heuristic_key[-1]))
193205
else:

jupyddl/bfs.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@
66

77
class BreadthFirstSearch:
88
def __init__(self, automated_planner):
9+
self.time_start = now()
910
self.visited = []
1011
self.automated_planner = automated_planner
1112
self.init = Node(self.automated_planner.initial_state, automated_planner)
1213
self.queue = [self.init]
1314
self.metrics = Metrics()
1415

1516
def search(self, node_bound=float("inf")):
16-
time_start = now()
1717
self.automated_planner.logger.debug(
1818
"Search started at: " + str(timestamp.now())
1919
)
@@ -25,7 +25,7 @@ def search(self, node_bound=float("inf")):
2525
if self.automated_planner.satisfies(
2626
self.automated_planner.problem.goal, current_node.state
2727
):
28-
self.metrics.runtime = now() - time_start
28+
self.metrics.runtime = now() - self.time_start
2929
self.automated_planner.logger.debug(
3030
"Search finished at: " + str(timestamp.now())
3131
)
@@ -54,6 +54,6 @@ def search(self, node_bound=float("inf")):
5454
continue
5555
self.metrics.n_opened += 1
5656
self.queue.append(child)
57-
self.metrics.runtime = now() - time_start
57+
self.metrics.runtime = now() - self.time_start
5858
self.automated_planner.logger.warning("!!! No path found !!!")
5959
return None, self.metrics

jupyddl/data_analyst.py

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -509,10 +509,7 @@ def comparative_astar_heuristic_plot(
509509
times_y.append(data[node_opened])
510510

511511
ax.plot(
512-
nodes_sorted,
513-
times_y,
514-
"-o",
515-
label=h,
512+
nodes_sorted, times_y, "-o", label=h,
516513
)
517514

518515
plt.title("A* heuristics complexity comparison")
@@ -544,10 +541,7 @@ def comparative_greedy_bfs_heuristic_plot(
544541
times_y.append(data[node_opened])
545542

546543
ax.plot(
547-
nodes_sorted,
548-
times_y,
549-
"-o",
550-
label=h,
544+
nodes_sorted, times_y, "-o", label=h,
551545
)
552546

553547
plt.title("Greedy Best First heuristics complexity comparison")
@@ -622,10 +616,7 @@ def comparative_data_plot(
622616
for node_opened in nodes_sorted:
623617
times_y.append(data[node_opened])
624618
ax.plot(
625-
nodes_sorted,
626-
times_y,
627-
"-o",
628-
label=planner,
619+
nodes_sorted, times_y, "-o", label=planner,
629620
)
630621
plt.title("Planners complexity comparison")
631622
plt.legend(loc="upper left")
@@ -753,9 +744,7 @@ def compute_planners_efficiency(self):
753744
plt.ylabel("Cost to goal")
754745
for key, val in costs.items():
755746
ax.plot(
756-
val,
757-
"-o",
758-
label=key,
747+
val, "-o", label=key,
759748
)
760749
costs[key] = [i for i in costs[key] if i != 0]
761750
plt.title("Planners efficiency (costs)")

jupyddl/dfs.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@
66

77
class DepthFirstSearch:
88
def __init__(self, automated_planner):
9+
self.time_start = now()
910
self.visited = []
1011
self.automated_planner = automated_planner
1112
self.init = Node(self.automated_planner.initial_state, automated_planner)
1213
self.stack = [self.init]
1314
self.metrics = Metrics()
1415

1516
def search(self, node_bound=float("inf")):
16-
time_start = now()
1717
self.automated_planner.logger.debug(
1818
"Search started at: " + str(timestamp.now())
1919
)
@@ -25,7 +25,7 @@ def search(self, node_bound=float("inf")):
2525
if self.automated_planner.satisfies(
2626
self.automated_planner.problem.goal, current_node.state
2727
):
28-
self.metrics.runtime = now() - time_start
28+
self.metrics.runtime = now() - self.time_start
2929
self.automated_planner.logger.debug(
3030
"Search finished at: " + str(timestamp.now())
3131
)
@@ -54,6 +54,6 @@ def search(self, node_bound=float("inf")):
5454
continue
5555
self.metrics.n_opened += 1
5656
self.stack.append(child)
57-
self.metrics.runtime = now() - time_start
57+
self.metrics.runtime = now() - self.time_start
5858
self.automated_planner.logger.warning("!!! No path found !!!")
5959
return None, self.metrics

jupyddl/dijkstra.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ def zero_heuristic():
1212

1313
class DijkstraBestFirstSearch:
1414
def __init__(self, automated_planner):
15+
self.time_start = now()
1516
self.automated_planner = automated_planner
1617
self.metrics = Metrics()
1718
self.init = Node(
@@ -35,7 +36,6 @@ def search(self, node_bound=float("inf")):
3536
self.automated_planner.logger.debug(
3637
"Search started at: " + str(timestamp.now())
3738
)
38-
time_start = now()
3939
while self.open_nodes_n > 0:
4040
current_key = min(
4141
[n for n in self.nodes if self.nodes[n].is_open],
@@ -46,7 +46,7 @@ def search(self, node_bound=float("inf")):
4646
if self.automated_planner.satisfies(
4747
self.automated_planner.problem.goal, current_node.state
4848
):
49-
self.metrics.runtime = now() - time_start
49+
self.metrics.runtime = now() - self.time_start
5050
self.automated_planner.logger.debug(
5151
"Search finished at: " + str(timestamp.now())
5252
)
@@ -96,6 +96,6 @@ def search(self, node_bound=float("inf")):
9696
self.nodes[child_hash] = child
9797
self.metrics.n_opened += 1
9898
self.open_nodes_n += 1
99-
self.metrics.runtime = now() - time_start
99+
self.metrics.runtime = now() - self.time_start
100100
self.automated_planner.logger.warning("!!! No path found !!!")
101101
return None, self.metrics

jupyddl/greedy_best_first.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
class GreedyBestFirstSearch:
1010
def __init__(self, automated_planner, heuristic_function):
11+
self.time_start = now()
1112
self.automated_planner = automated_planner
1213
self.metrics = Metrics()
1314
self.init = Node(
@@ -30,7 +31,6 @@ def __hash(self, node):
3031
return string.split(sep, 1)[0] + ")"
3132

3233
def search(self, node_bound=float("inf")):
33-
time_start = now()
3434
self.automated_planner.logger.debug(
3535
"Search started at: " + str(timestamp.now())
3636
)
@@ -45,7 +45,7 @@ def search(self, node_bound=float("inf")):
4545
if self.automated_planner.satisfies(
4646
self.automated_planner.problem.goal, current_node.state
4747
):
48-
self.metrics.runtime = now() - time_start
48+
self.metrics.runtime = now() - self.time_start
4949
self.automated_planner.logger.debug(
5050
"Search finished at: " + str(timestamp.now())
5151
)
@@ -96,6 +96,6 @@ def search(self, node_bound=float("inf")):
9696
self.nodes[child_hash] = child
9797
self.open_nodes_n += 1
9898
self.metrics.n_opened += 1
99-
self.metrics.runtime = now() - time_start
99+
self.metrics.runtime = now() - self.time_start
100100
self.automated_planner.logger.warning("!!! No path found !!!")
101101
return None, self.metrics

0 commit comments

Comments
 (0)