Tmp
This commit is contained in:
parent
01300e23b2
commit
ddebd26db2
547
2022/day19.py
547
2022/day19.py
@ -3,9 +3,13 @@
|
|||||||
import heapq
|
import heapq
|
||||||
import math
|
import math
|
||||||
import sys
|
import sys
|
||||||
|
import time
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from typing import Literal, TypedDict
|
from typing import Literal, TypedDict
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
|
from tqdm import tqdm
|
||||||
|
|
||||||
Reagent = Literal["ore", "clay", "obsidian", "geode"]
|
Reagent = Literal["ore", "clay", "obsidian", "geode"]
|
||||||
REAGENTS: tuple[Reagent] = (
|
REAGENTS: tuple[Reagent] = (
|
||||||
"ore",
|
"ore",
|
||||||
@ -63,7 +67,7 @@ class State:
|
|||||||
def __lt__(self, other) -> bool:
|
def __lt__(self, other) -> bool:
|
||||||
return isinstance(other, State) and tuple(
|
return isinstance(other, State) and tuple(
|
||||||
(self.robots[r], self.reagents[r]) for r in REAGENTS
|
(self.robots[r], self.reagents[r]) for r in REAGENTS
|
||||||
) < tuple((other.robots[r], other.reagents[r]) for r in REAGENTS)
|
) > tuple((other.robots[r], other.reagents[r]) for r in REAGENTS)
|
||||||
|
|
||||||
def __hash__(self) -> int:
|
def __hash__(self) -> int:
|
||||||
return hash(tuple((self.robots[r], self.reagents[r]) for r in REAGENTS))
|
return hash(tuple((self.robots[r], self.reagents[r]) for r in REAGENTS))
|
||||||
@ -85,224 +89,245 @@ def dominates(lhs: State, rhs: State):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
MAX_TIME = 24
|
||||||
|
blueprint = blueprints[1]
|
||||||
|
|
||||||
|
# parents: dict[State, tuple[State | None, int]] = {State(): (None, 0)}
|
||||||
|
# queue = [(0, State())]
|
||||||
|
# visited: set[State] = set()
|
||||||
|
# at_time: dict[int, list[State]] = defaultdict(lambda: [])
|
||||||
|
|
||||||
|
# while queue:
|
||||||
|
# time, state = heapq.heappop(queue)
|
||||||
|
# if state in visited:
|
||||||
|
# continue
|
||||||
|
|
||||||
|
# print(time, state)
|
||||||
|
|
||||||
|
# visited.add(state)
|
||||||
|
|
||||||
|
# at_time[time].append(state)
|
||||||
|
|
||||||
|
# if time > MAX_TIME:
|
||||||
|
# continue
|
||||||
|
|
||||||
|
# if len(queue) % 200 == 0:
|
||||||
|
# print(len(queue), len(visited), time)
|
||||||
|
|
||||||
|
# can_build_any: bool = False
|
||||||
|
# for reagent in REAGENTS:
|
||||||
|
# needed = blueprint[reagent]
|
||||||
|
|
||||||
|
# if any(state.robots[r] == 0 for r in needed):
|
||||||
|
# continue
|
||||||
|
|
||||||
|
# time_to_complete = max(
|
||||||
|
# max(
|
||||||
|
# math.ceil((needed[r] - state.reagents[r]) / state.robots[r])
|
||||||
|
# for r in needed
|
||||||
|
# ),
|
||||||
|
# 0,
|
||||||
|
# )
|
||||||
|
|
||||||
|
# # if time_to_complete != 0:
|
||||||
|
# # continue
|
||||||
|
|
||||||
|
# if time + time_to_complete + 1 > MAX_TIME:
|
||||||
|
# continue
|
||||||
|
|
||||||
|
# wait = time_to_complete + 1
|
||||||
|
|
||||||
|
# reagents = {
|
||||||
|
# r: state.reagents[r] + wait * state.robots[r] - needed.get(r, 0)
|
||||||
|
# for r in REAGENTS
|
||||||
|
# }
|
||||||
|
|
||||||
|
# robots = state.robots.copy()
|
||||||
|
# robots[reagent] += 1
|
||||||
|
|
||||||
|
# state_2 = State(reagents=reagents, robots=robots)
|
||||||
|
|
||||||
|
# if state_2 in visited:
|
||||||
|
# continue
|
||||||
|
|
||||||
|
# if any(dominates(state_v, state_2) for state_v in at_time[time + wait]):
|
||||||
|
# continue
|
||||||
|
|
||||||
|
# # print(time + wait)
|
||||||
|
# # if any(dominates(state_3, state_2) for state_3 in at_time[time + wait]):
|
||||||
|
# # print("?")
|
||||||
|
# # continue
|
||||||
|
|
||||||
|
# if state_2 not in parents or parents[state_2][1] > time + wait:
|
||||||
|
# parents[state_2] = (state, time + wait)
|
||||||
|
# heapq.heappush(queue, (time + wait, state_2))
|
||||||
|
# can_build_any = True
|
||||||
|
# at_time[time + wait].append(state_2)
|
||||||
|
|
||||||
|
# if not can_build_any:
|
||||||
|
# state_2 = State(
|
||||||
|
# reagents={
|
||||||
|
# r: state.reagents[r] + state.robots[r] * (MAX_TIME - time)
|
||||||
|
# for r in REAGENTS
|
||||||
|
# },
|
||||||
|
# robots=state.robots,
|
||||||
|
# )
|
||||||
|
|
||||||
|
# if state_2 in visited:
|
||||||
|
# continue
|
||||||
|
|
||||||
|
# if state_2 not in parents or parents[state_2][1] > time + wait:
|
||||||
|
# parents[state_2] = (state, MAX_TIME)
|
||||||
|
# heapq.heappush(queue, (MAX_TIME, state_2))
|
||||||
|
|
||||||
|
# print(len(visited))
|
||||||
|
# print(max(state.reagents["geode"] for state in visited))
|
||||||
|
|
||||||
|
# exit()
|
||||||
|
|
||||||
|
# while states:
|
||||||
|
# state = states.pop()
|
||||||
|
# processed.append(state)
|
||||||
|
|
||||||
|
# if state.time > MAX_TIME:
|
||||||
|
# continue
|
||||||
|
|
||||||
|
# if len(states) % 100 == 0:
|
||||||
|
# print(len(states), len(processed), min((s.time for s in states), default=1))
|
||||||
|
|
||||||
|
# can_build_any: bool = False
|
||||||
|
# for reagent in REAGENTS:
|
||||||
|
# needed = blueprint[reagent]
|
||||||
|
|
||||||
|
# if any(state.robots[r] == 0 for r in needed):
|
||||||
|
# continue
|
||||||
|
|
||||||
|
# time_to_complete = max(
|
||||||
|
# max(
|
||||||
|
# math.ceil((needed[r] - state.reagents[r]) / state.robots[r])
|
||||||
|
# for r in needed
|
||||||
|
# ),
|
||||||
|
# 0,
|
||||||
|
# )
|
||||||
|
|
||||||
|
# if state.time + time_to_complete + 1 > MAX_TIME:
|
||||||
|
# continue
|
||||||
|
|
||||||
|
# wait = time_to_complete + 1
|
||||||
|
|
||||||
|
# reagents = {
|
||||||
|
# r: state.reagents[r] + wait * state.robots[r] - needed.get(r, 0)
|
||||||
|
# for r in REAGENTS
|
||||||
|
# }
|
||||||
|
|
||||||
|
# robots = state.robots.copy()
|
||||||
|
# robots[reagent] += 1
|
||||||
|
|
||||||
|
# can_build_any = True
|
||||||
|
# state_2 = State(time=state.time + wait, reagents=reagents, robots=robots)
|
||||||
|
# # print(f"{state} -> {state_2}")
|
||||||
|
# states.add(state_2)
|
||||||
|
|
||||||
|
# if not any(dominates(s2, state_2) for s2 in states):
|
||||||
|
# states.add(state)
|
||||||
|
|
||||||
|
# # print(f"can build {reagent} in {time_to_complete}")
|
||||||
|
|
||||||
|
# if not can_build_any:
|
||||||
|
# states.add(
|
||||||
|
# State(
|
||||||
|
# time=MAX_TIME + 1,
|
||||||
|
# reagents={
|
||||||
|
# r: state.reagents[r] + state.robots[r] * (MAX_TIME - state.time)
|
||||||
|
# for r in REAGENTS
|
||||||
|
# },
|
||||||
|
# robots=state.robots,
|
||||||
|
# )
|
||||||
|
# )
|
||||||
|
|
||||||
|
# if len(states) % 1000 == 0:
|
||||||
|
# print("filtering")
|
||||||
|
# states = {
|
||||||
|
# s1
|
||||||
|
# for s1 in states
|
||||||
|
# if not any(dominates(s2, s1) for s2 in states if s2 is not s1)
|
||||||
|
# }
|
||||||
|
|
||||||
|
# # if len(states) > 4:
|
||||||
|
# # break
|
||||||
|
|
||||||
|
# # break
|
||||||
|
|
||||||
|
# print(len(processed))
|
||||||
|
# print(max(state.reagents["geode"] for state in processed))
|
||||||
|
|
||||||
|
# exit()
|
||||||
|
|
||||||
|
# for t in range(1, 25):
|
||||||
|
# states = set()
|
||||||
|
# for state in state_after_t[t - 1]:
|
||||||
|
# robots_that_can_be_built = [
|
||||||
|
# robot
|
||||||
|
# for robot in REAGENTS
|
||||||
|
# if all(
|
||||||
|
# state.reagents[reagent] >= blueprint[robot].get(reagent, 0)
|
||||||
|
# for reagent in REAGENTS
|
||||||
|
# )
|
||||||
|
# ]
|
||||||
|
|
||||||
|
# new_states = set()
|
||||||
|
|
||||||
|
# # new reagents
|
||||||
|
# reagents = {
|
||||||
|
# reagent: state.reagents[reagent] + state.robots[reagent]
|
||||||
|
# for reagent in REAGENTS
|
||||||
|
# }
|
||||||
|
|
||||||
|
# # if we can build anything, there is no point in waiting
|
||||||
|
# if len(robots_that_can_be_built) != len(REAGENTS):
|
||||||
|
# new_states.add(State(robots=state.robots, reagents=reagents))
|
||||||
|
|
||||||
|
# for robot in robots_that_can_be_built:
|
||||||
|
# robots = state.robots.copy()
|
||||||
|
# robots[robot] += 1
|
||||||
|
# reagents = {
|
||||||
|
# reagent: state.reagents[reagent]
|
||||||
|
# + state.robots[reagent]
|
||||||
|
# - blueprint[robot].get(reagent, 0)
|
||||||
|
# for reagent in REAGENTS
|
||||||
|
# }
|
||||||
|
# new_states.add(State(robots=robots, reagents=reagents))
|
||||||
|
|
||||||
|
# new_states = [
|
||||||
|
# s1
|
||||||
|
# for s1 in new_states
|
||||||
|
# if not any(s1 is not s2 and dominates(s2, s1) for s2 in new_states)
|
||||||
|
# ]
|
||||||
|
|
||||||
|
# states = {
|
||||||
|
# s1 for s1 in states if not any(dominates(s2, s1) for s2 in new_states)
|
||||||
|
# }
|
||||||
|
# states.update(new_states)
|
||||||
|
|
||||||
|
# state_after_t[t] = states
|
||||||
|
|
||||||
|
# exit()
|
||||||
|
|
||||||
|
|
||||||
MAX_TIME = 24
|
MAX_TIME = 24
|
||||||
blueprint = blueprints[0]
|
blueprint = blueprints[0]
|
||||||
|
|
||||||
parents: dict[State, tuple[State | None, int]] = {State(): (None, 0)}
|
state_after_t: dict[int, list[State]] = {0: [State()]}
|
||||||
queue = [(0, State())]
|
|
||||||
visited: set[State] = set()
|
|
||||||
at_time: dict[int, list[State]] = defaultdict(lambda: [])
|
|
||||||
|
|
||||||
while queue:
|
|
||||||
time, state = heapq.heappop(queue)
|
|
||||||
if state in visited:
|
|
||||||
continue
|
|
||||||
|
|
||||||
visited.add(state)
|
|
||||||
|
|
||||||
# if any(dominates(state_3, state) for state_3 in at_time[time]):
|
|
||||||
# continue
|
|
||||||
|
|
||||||
at_time[time].append(state)
|
|
||||||
|
|
||||||
if time > MAX_TIME:
|
|
||||||
continue
|
|
||||||
|
|
||||||
if len(queue) % 500 == 0:
|
|
||||||
print(len(queue), len(visited), time)
|
|
||||||
|
|
||||||
can_build_any: bool = False
|
|
||||||
for reagent in REAGENTS:
|
|
||||||
needed = blueprint[reagent]
|
|
||||||
|
|
||||||
if any(state.robots[r] == 0 for r in needed):
|
|
||||||
continue
|
|
||||||
|
|
||||||
time_to_complete = max(
|
|
||||||
max(
|
|
||||||
math.ceil((needed[r] - state.reagents[r]) / state.robots[r])
|
|
||||||
for r in needed
|
|
||||||
),
|
|
||||||
0,
|
|
||||||
)
|
|
||||||
|
|
||||||
if time + time_to_complete + 1 > MAX_TIME:
|
|
||||||
continue
|
|
||||||
|
|
||||||
wait = time_to_complete + 1
|
|
||||||
|
|
||||||
reagents = {
|
|
||||||
r: state.reagents[r] + wait * state.robots[r] - needed.get(r, 0)
|
|
||||||
for r in REAGENTS
|
|
||||||
}
|
|
||||||
|
|
||||||
robots = state.robots.copy()
|
|
||||||
robots[reagent] += 1
|
|
||||||
|
|
||||||
state_2 = State(reagents=reagents, robots=robots)
|
|
||||||
|
|
||||||
print(time + wait)
|
|
||||||
if any(dominates(state_3, state_2) for state_3 in at_time[time + wait]):
|
|
||||||
continue
|
|
||||||
|
|
||||||
if state_2 not in parents or parents[state_2][1] > time + wait:
|
|
||||||
parents[state_2] = (state, time + wait)
|
|
||||||
heapq.heappush(queue, (time + wait, state_2))
|
|
||||||
can_build_any = True
|
|
||||||
|
|
||||||
if not can_build_any:
|
|
||||||
state_2 = State(
|
|
||||||
reagents={
|
|
||||||
r: state.reagents[r] + state.robots[r] * (MAX_TIME - time)
|
|
||||||
for r in REAGENTS
|
|
||||||
},
|
|
||||||
robots=state.robots,
|
|
||||||
)
|
|
||||||
|
|
||||||
if state_2 not in parents or parents[state_2][1] > time + wait:
|
|
||||||
parents[state_2] = (state, time + wait)
|
|
||||||
heapq.heappush(queue, (time + wait, state_2))
|
|
||||||
|
|
||||||
print(len(visited))
|
|
||||||
print(max(state.reagents["geode"] for state in visited))
|
|
||||||
|
|
||||||
exit()
|
|
||||||
|
|
||||||
while states:
|
|
||||||
state = states.pop()
|
|
||||||
processed.append(state)
|
|
||||||
|
|
||||||
if state.time > MAX_TIME:
|
|
||||||
continue
|
|
||||||
|
|
||||||
if len(states) % 100 == 0:
|
|
||||||
print(len(states), len(processed), min((s.time for s in states), default=1))
|
|
||||||
|
|
||||||
can_build_any: bool = False
|
|
||||||
for reagent in REAGENTS:
|
|
||||||
needed = blueprint[reagent]
|
|
||||||
|
|
||||||
if any(state.robots[r] == 0 for r in needed):
|
|
||||||
continue
|
|
||||||
|
|
||||||
time_to_complete = max(
|
|
||||||
max(
|
|
||||||
math.ceil((needed[r] - state.reagents[r]) / state.robots[r])
|
|
||||||
for r in needed
|
|
||||||
),
|
|
||||||
0,
|
|
||||||
)
|
|
||||||
|
|
||||||
if state.time + time_to_complete + 1 > MAX_TIME:
|
|
||||||
continue
|
|
||||||
|
|
||||||
wait = time_to_complete + 1
|
|
||||||
|
|
||||||
reagents = {
|
|
||||||
r: state.reagents[r] + wait * state.robots[r] - needed.get(r, 0)
|
|
||||||
for r in REAGENTS
|
|
||||||
}
|
|
||||||
|
|
||||||
robots = state.robots.copy()
|
|
||||||
robots[reagent] += 1
|
|
||||||
|
|
||||||
can_build_any = True
|
|
||||||
state_2 = State(time=state.time + wait, reagents=reagents, robots=robots)
|
|
||||||
# print(f"{state} -> {state_2}")
|
|
||||||
states.add(state_2)
|
|
||||||
|
|
||||||
if not any(dominates(s2, state_2) for s2 in states):
|
|
||||||
states.add(state)
|
|
||||||
|
|
||||||
# print(f"can build {reagent} in {time_to_complete}")
|
|
||||||
|
|
||||||
if not can_build_any:
|
|
||||||
states.add(
|
|
||||||
State(
|
|
||||||
time=MAX_TIME + 1,
|
|
||||||
reagents={
|
|
||||||
r: state.reagents[r] + state.robots[r] * (MAX_TIME - state.time)
|
|
||||||
for r in REAGENTS
|
|
||||||
},
|
|
||||||
robots=state.robots,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
if len(states) % 1000 == 0:
|
|
||||||
print("filtering")
|
|
||||||
states = {
|
|
||||||
s1
|
|
||||||
for s1 in states
|
|
||||||
if not any(dominates(s2, s1) for s2 in states if s2 is not s1)
|
|
||||||
}
|
|
||||||
|
|
||||||
# if len(states) > 4:
|
|
||||||
# break
|
|
||||||
|
|
||||||
# break
|
|
||||||
|
|
||||||
print(len(processed))
|
|
||||||
print(max(state.reagents["geode"] for state in processed))
|
|
||||||
|
|
||||||
exit()
|
|
||||||
|
|
||||||
for t in range(1, 25):
|
|
||||||
states = set()
|
|
||||||
for state in state_after_t[t - 1]:
|
|
||||||
robots_that_can_be_built = [
|
|
||||||
robot
|
|
||||||
for robot in REAGENTS
|
|
||||||
if all(
|
|
||||||
state.reagents[reagent] >= blueprint[robot].get(reagent, 0)
|
|
||||||
for reagent in REAGENTS
|
|
||||||
)
|
|
||||||
]
|
|
||||||
|
|
||||||
new_states = set()
|
|
||||||
|
|
||||||
# new reagents
|
|
||||||
reagents = {
|
|
||||||
reagent: state.reagents[reagent] + state.robots[reagent]
|
|
||||||
for reagent in REAGENTS
|
|
||||||
}
|
|
||||||
|
|
||||||
# if we can build anything, there is no point in waiting
|
|
||||||
if len(robots_that_can_be_built) != len(REAGENTS):
|
|
||||||
new_states.add(State(robots=state.robots, reagents=reagents))
|
|
||||||
|
|
||||||
for robot in robots_that_can_be_built:
|
|
||||||
robots = state.robots.copy()
|
|
||||||
robots[robot] += 1
|
|
||||||
reagents = {
|
|
||||||
reagent: state.reagents[reagent]
|
|
||||||
+ state.robots[reagent]
|
|
||||||
- blueprint[robot].get(reagent, 0)
|
|
||||||
for reagent in REAGENTS
|
|
||||||
}
|
|
||||||
new_states.add(State(robots=robots, reagents=reagents))
|
|
||||||
|
|
||||||
new_states = [
|
|
||||||
s1
|
|
||||||
for s1 in new_states
|
|
||||||
if not any(s1 is not s2 and dominates(s2, s1) for s2 in new_states)
|
|
||||||
]
|
|
||||||
|
|
||||||
states = {
|
|
||||||
s1 for s1 in states if not any(dominates(s2, s1) for s2 in new_states)
|
|
||||||
}
|
|
||||||
states.update(new_states)
|
|
||||||
|
|
||||||
state_after_t[t] = states
|
|
||||||
|
|
||||||
exit()
|
|
||||||
|
|
||||||
|
|
||||||
for t in range(1, 25):
|
for t in range(1, 25):
|
||||||
print(t, len(state_after_t[t - 1]))
|
print(t, len(state_after_t[t - 1]))
|
||||||
state_after_t[t] = set()
|
|
||||||
|
|
||||||
bests_for_robots: dict[tuple[int, ...], set[State]] = {}
|
bests_for_robots: dict[tuple[int, ...], list[State]] = {}
|
||||||
bests_for_reagents: dict[tuple[int, ...], set[State]] = {}
|
bests_for_reagents: dict[tuple[int, ...], list[State]] = {}
|
||||||
|
|
||||||
|
state_after_t[t] = []
|
||||||
|
|
||||||
|
t1 = time.time()
|
||||||
|
|
||||||
for state in state_after_t[t - 1]:
|
for state in state_after_t[t - 1]:
|
||||||
robots_that_can_be_built = [
|
robots_that_can_be_built = [
|
||||||
@ -324,11 +349,9 @@ for t in range(1, 25):
|
|||||||
}
|
}
|
||||||
|
|
||||||
# if we can build anything, there is no point in waiting
|
# if we can build anything, there is no point in waiting
|
||||||
new_states.add(State(robots=state.robots, reagents=reagents, last=None))
|
new_states.add(State(robots=state.robots, reagents=reagents))
|
||||||
|
|
||||||
for robot in robots_that_can_be_built:
|
for robot in robots_that_can_be_built:
|
||||||
if robot == state.last:
|
|
||||||
continue
|
|
||||||
robots = state.robots.copy()
|
robots = state.robots.copy()
|
||||||
robots[robot] += 1
|
robots[robot] += 1
|
||||||
reagents = {
|
reagents = {
|
||||||
@ -337,12 +360,12 @@ for t in range(1, 25):
|
|||||||
- blueprint[robot].get(reagent, 0)
|
- blueprint[robot].get(reagent, 0)
|
||||||
for reagent in REAGENTS
|
for reagent in REAGENTS
|
||||||
}
|
}
|
||||||
new_states.add(State(robots=robots, reagents=reagents, last=robot))
|
new_states.add(State(robots=robots, reagents=reagents))
|
||||||
|
|
||||||
for s1 in new_states:
|
for s1 in new_states:
|
||||||
r1 = tuple(s1.robots[r] for r in REAGENTS)
|
r1 = tuple(s1.robots[r] for r in REAGENTS)
|
||||||
if r1 not in bests_for_robots:
|
if r1 not in bests_for_robots:
|
||||||
bests_for_robots[r1] = {s1}
|
bests_for_robots[r1] = [s1]
|
||||||
else:
|
else:
|
||||||
is_dominated = False
|
is_dominated = False
|
||||||
for s2 in bests_for_robots[r1]:
|
for s2 in bests_for_robots[r1]:
|
||||||
@ -350,11 +373,11 @@ for t in range(1, 25):
|
|||||||
is_dominated = True
|
is_dominated = True
|
||||||
break
|
break
|
||||||
if not is_dominated:
|
if not is_dominated:
|
||||||
bests_for_robots[r1].add(s1)
|
bests_for_robots[r1].append(s1)
|
||||||
|
|
||||||
r2 = tuple(s1.reagents[r] for r in REAGENTS)
|
r2 = tuple(s1.reagents[r] for r in REAGENTS)
|
||||||
if r2 not in bests_for_reagents:
|
if r2 not in bests_for_reagents:
|
||||||
bests_for_reagents[r2] = {s1}
|
bests_for_reagents[r2] = [s1]
|
||||||
else:
|
else:
|
||||||
is_dominated = False
|
is_dominated = False
|
||||||
for s2 in bests_for_reagents[r2]:
|
for s2 in bests_for_reagents[r2]:
|
||||||
@ -362,20 +385,22 @@ for t in range(1, 25):
|
|||||||
is_dominated = True
|
is_dominated = True
|
||||||
break
|
break
|
||||||
if not is_dominated:
|
if not is_dominated:
|
||||||
bests_for_reagents[r2].add(s1)
|
bests_for_reagents[r2].append(s1)
|
||||||
|
# state_after_t[t].extend(new_states)
|
||||||
|
|
||||||
|
t2 = time.time()
|
||||||
|
|
||||||
state_after_t[t] = set()
|
|
||||||
for bests in bests_for_robots.values():
|
for bests in bests_for_robots.values():
|
||||||
dominated = [False for _ in range(len(bests))]
|
dominated = [False for _ in range(len(bests))]
|
||||||
for i_s1, s1 in enumerate(bests):
|
for i_s1, s1 in enumerate(bests):
|
||||||
if dominated[i_s1]:
|
if dominated[i_s1]:
|
||||||
continue
|
continue
|
||||||
for i_s2, s2 in enumerate(bests):
|
for i_s2, s2 in enumerate(bests[i_s1 + 1 :], start=i_s1 + 1):
|
||||||
if s1 is s2 or dominated[i_s2]:
|
if dominated[i_s2]:
|
||||||
continue
|
continue
|
||||||
if all(s1.reagents[r] >= s2.reagents[r] for r in REAGENTS):
|
if all(s1.reagents[r] >= s2.reagents[r] for r in REAGENTS):
|
||||||
dominated[i_s2] = True
|
dominated[i_s2] = True
|
||||||
state_after_t[t].update(
|
state_after_t[t].extend(
|
||||||
s1 for i_s1, s1 in enumerate(bests) if not dominated[i_s1]
|
s1 for i_s1, s1 in enumerate(bests) if not dominated[i_s1]
|
||||||
)
|
)
|
||||||
for bests in bests_for_reagents.values():
|
for bests in bests_for_reagents.values():
|
||||||
@ -383,31 +408,77 @@ for t in range(1, 25):
|
|||||||
for i_s1, s1 in enumerate(bests):
|
for i_s1, s1 in enumerate(bests):
|
||||||
if dominated[i_s1]:
|
if dominated[i_s1]:
|
||||||
continue
|
continue
|
||||||
for i_s2, s2 in enumerate(bests):
|
for i_s2, s2 in enumerate(bests[i_s1 + 1 :], start=i_s1 + 1):
|
||||||
if s1 is s2 or dominated[i_s2]:
|
if dominated[i_s2]:
|
||||||
continue
|
continue
|
||||||
if all(s1.robots[r] >= s2.robots[r] for r in REAGENTS):
|
if all(s1.robots[r] >= s2.robots[r] for r in REAGENTS):
|
||||||
dominated[i_s2] = True
|
dominated[i_s2] = True
|
||||||
state_after_t[t].update(
|
state_after_t[t].extend(
|
||||||
s1 for i_s1, s1 in enumerate(bests) if not dominated[i_s1]
|
s1 for i_s1, s1 in enumerate(bests) if not dominated[i_s1]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
t3 = time.time()
|
||||||
|
|
||||||
|
np_states = np.array(
|
||||||
|
[
|
||||||
|
[state.robots[r] for r in REAGENTS] + [state.reagents[r] for r in REAGENTS]
|
||||||
|
for state in state_after_t[t]
|
||||||
|
]
|
||||||
|
)
|
||||||
|
dominated = np.zeros(len(np_states), dtype=bool)
|
||||||
|
|
||||||
|
t4 = time.time()
|
||||||
|
|
||||||
|
# c = (np_states[None, :, :] <= np_states[:, None, :]).all(axis=-1)
|
||||||
|
# c[np.arange(len(np_states)), np.arange(len(np_states))] = False
|
||||||
|
# dominated = c.any(axis=0)
|
||||||
|
|
||||||
|
for i in range(len(np_states)):
|
||||||
|
if dominated[i]:
|
||||||
|
continue
|
||||||
|
dominated[i] = not (np_states[i + 1 :] <= np_states[i]).any(axis=1)
|
||||||
|
|
||||||
|
dominated[i + 1 :] = (np_states[i + 1 :] <= np_states[i]).all(axis=1)
|
||||||
|
|
||||||
|
t5 = time.time()
|
||||||
|
|
||||||
|
state_after_t[t] = list(np.array(state_after_t[t])[~dominated])
|
||||||
|
|
||||||
|
t6 = time.time()
|
||||||
|
|
||||||
|
print(
|
||||||
|
"->",
|
||||||
|
t,
|
||||||
|
len(state_after_t[t]),
|
||||||
|
dominated.sum(),
|
||||||
|
t2 - t1,
|
||||||
|
t3 - t2,
|
||||||
|
t4 - t3,
|
||||||
|
t5 - t4,
|
||||||
|
t6 - t5,
|
||||||
|
)
|
||||||
|
|
||||||
|
# print("->", len(state_after_t[t]))
|
||||||
|
|
||||||
# dominated = [False for _ in range(len(state_after_t[t]))]
|
# dominated = [False for _ in range(len(state_after_t[t]))]
|
||||||
# print(t, "->", len(state_after_t[t]))
|
# keep = set()
|
||||||
# for i_s1, s1 in enumerate(state_after_t[t]):
|
# for i_s1, s1 in enumerate(tqdm(state_after_t[t])):
|
||||||
# if dominated[i_s1]:
|
# if dominated[i_s1]:
|
||||||
# continue
|
# continue
|
||||||
# for i_s2, s2 in enumerate(state_after_t[t]):
|
# for i_s2, s2 in enumerate(state_after_t[t][i_s1 + 1 :], start=i_s1 + 1):
|
||||||
# if s1 is s2 or dominated[i_s2]:
|
# if dominated[i_s2]:
|
||||||
# continue
|
# continue
|
||||||
# if all(s1.robots[r] >= s2.robots[r] for r in REAGENTS) and all(
|
|
||||||
# s1.reagents[r] >= s2.reagents[r] for r in REAGENTS
|
|
||||||
# ):
|
|
||||||
# dominated[i_s2] = True
|
|
||||||
|
|
||||||
# state_after_t[t] = {
|
# if dominates(s1, s2):
|
||||||
# s1 for i_s1, s1 in enumerate(state_after_t[t]) if not dominated[i_s1]
|
# dominated[i_s2] = True
|
||||||
# }
|
# elif dominates(s2, s1):
|
||||||
|
# dominated[i_s1] = True
|
||||||
|
# break
|
||||||
|
|
||||||
|
# if not dominated[i_s1]:
|
||||||
|
# keep.add(s1)
|
||||||
|
|
||||||
|
# state_after_t[t] = list(keep)
|
||||||
|
|
||||||
# print(len(state_after_t[t]))
|
# print(len(state_after_t[t]))
|
||||||
# print(sum(dominated))
|
# print(sum(dominated))
|
||||||
|
Loading…
Reference in New Issue
Block a user