new A* optimization: worst-case pruning
i'm not sure if this has been described in the literature exactly but it is similar to existing branch-and-bound techniques. it doesn't speed up the search directly (the number of visited nodes is the same) but it does cut the queue length down by an order of magnitude and shave a couple seconds off of day 16, presumably due to reduced memory pressure or something.main
parent
e9ada04aa9
commit
910da239c0
|
@ -152,6 +152,10 @@ def solve():
|
||||||
m -= 1
|
m -= 1
|
||||||
return c
|
return c
|
||||||
|
|
||||||
|
def worst2(node):
|
||||||
|
_, _, min1, min2, closed = node
|
||||||
|
return min(min1,min2) * pressure(closed)
|
||||||
|
|
||||||
def is_goal2(node):
|
def is_goal2(node):
|
||||||
_, _, min1, min2, closed = node
|
_, _, min1, min2, closed = node
|
||||||
return min1 == 0 and min2 == 0 or closed == all_open
|
return min1 == 0 and min2 == 0 or closed == all_open
|
||||||
|
@ -209,7 +213,7 @@ def solve():
|
||||||
minutes = 26
|
minutes = 26
|
||||||
start2 = (AA, AA, minutes, minutes, all_closed)
|
start2 = (AA, AA, minutes, minutes, all_closed)
|
||||||
info.clear()
|
info.clear()
|
||||||
c, _, path = astar.search(start2, is_goal2, neighbors2, heuristic2)
|
c, _, path = astar.search(start2, is_goal2, neighbors2, heuristic2, worst=worst2)
|
||||||
print(c)
|
print(c)
|
||||||
print(max_pressure*minutes - c)
|
print(max_pressure*minutes - c)
|
||||||
|
|
||||||
|
|
13
lib/astar.py
13
lib/astar.py
|
@ -1,6 +1,6 @@
|
||||||
from heapq import heappush, heappop
|
from heapq import heappush, heappop
|
||||||
|
|
||||||
def search(start, is_goal, neighbors, heuristic=None):
|
def search(start, is_goal, neighbors, heuristic=None, worst=None):
|
||||||
if heuristic == None:
|
if heuristic == None:
|
||||||
def heuristic(x):
|
def heuristic(x):
|
||||||
return 0
|
return 0
|
||||||
|
@ -16,6 +16,8 @@ def search(start, is_goal, neighbors, heuristic=None):
|
||||||
i += 1
|
i += 1
|
||||||
heappush(q, (heuristic(s), i, s, None))
|
heappush(q, (heuristic(s), i, s, None))
|
||||||
done = {}
|
done = {}
|
||||||
|
if worst:
|
||||||
|
best_worst = min(worst(s) for s in start)
|
||||||
while q:
|
while q:
|
||||||
z, _, this, prev = heappop(q)
|
z, _, this, prev = heappop(q)
|
||||||
if this in done:
|
if this in done:
|
||||||
|
@ -41,8 +43,15 @@ def search(start, is_goal, neighbors, heuristic=None):
|
||||||
c = cost_so_far + c
|
c = cost_so_far + c
|
||||||
if n not in done or c < done[n][0]:
|
if n not in done or c < done[n][0]:
|
||||||
h = heuristic(n)
|
h = heuristic(n)
|
||||||
if h is None:
|
if worst:
|
||||||
|
if c+h > best_worst:
|
||||||
|
# if the best possible cost for this node
|
||||||
|
# is worse than the lowest worst-case cost we've seen
|
||||||
|
# then don't even bother exploring it
|
||||||
continue
|
continue
|
||||||
|
w = worst(n)
|
||||||
|
if c+w < best_worst:
|
||||||
|
best_worst = c+w
|
||||||
i += 1
|
i += 1
|
||||||
heappush(q, (c+h, i, n, this))
|
heappush(q, (c+h, i, n, this))
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue