-
Notifications
You must be signed in to change notification settings - Fork 8
/
propagator.py
66 lines (51 loc) · 2.42 KB
/
propagator.py
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
import os
import time
from multiprocessing import Pool
from pattern import Pattern
class Propagator:
"""
Propagator that computes and stores the legal patterns relative to another
"""
def __init__(self, patterns):
self.patterns = patterns
self.offsets = [(z, y, x) for x in range(-1, 2) for y in range(-1, 2) for z in range(-1, 2)]
start_time = time.time()
self.precompute_legal_patterns()
print("Patterns constraints generation took %s seconds" % (time.time() - start_time))
def precompute_legal_patterns(self):
pool = Pool(os.cpu_count())
patterns_offsets = []
for pattern in self.patterns:
for offset in self.offsets:
patterns_offsets.append((pattern, offset))
patterns_compatibility = pool.starmap(self.legal_patterns, patterns_offsets)
pool.close()
pool.join()
for pattern_index, offset, legal_patterns in patterns_compatibility:
self.patterns[pattern_index].set_legal_patterns(offset, legal_patterns)
def legal_patterns(self, pattern, offset):
legal_patt = []
for candidate_pattern in self.patterns:
if pattern.is_compatible(candidate_pattern, offset):
legal_patt.append(candidate_pattern.index)
pattern.set_legal_patterns(offset, legal_patt)
return pattern.index, offset, legal_patt
@staticmethod
def propagate(cell):
to_update = [neighbour for neighbour, _ in cell.get_neighbors()]
while len(to_update) > 0:
cell = to_update.pop(0)
for neighbour, offset in cell.get_neighbors():
for pattern_index in cell.allowed_patterns:
pattern = Pattern.from_index(pattern_index)
pattern_still_compatible = False
for neighbour_pattern_index in neighbour.allowed_patterns:
neighbour_pattern = Pattern.from_index(neighbour_pattern_index)
if pattern.is_compatible(neighbour_pattern, offset):
pattern_still_compatible = True
break
if not pattern_still_compatible:
cell.allowed_patterns.remove(pattern_index)
for neigh, _ in cell.get_neighbors():
if neigh not in to_update:
to_update.append(neigh)