LOOFYYLO commited on
Commit
605ae26
·
verified ·
1 Parent(s): 0bf7d8f

Upload fso_simulator.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. fso_simulator.py +126 -0
fso_simulator.py ADDED
@@ -0,0 +1,126 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import collections
2
+ import random
3
+ import itertools
4
+
5
+ class FSORouter:
6
+ def __init__(self, m, k=3, r=None):
7
+ self.m = m
8
+ self.k = k
9
+ if r:
10
+ self.r = r
11
+ elif k == 3:
12
+ self.r = [1, m - 2, 1]
13
+ if m == 3: self.r = [1, 1, 1]
14
+ elif k == 2:
15
+ self.r = [1, m - 1]
16
+ elif k == 4:
17
+ # Law I Escape: k=4 resolves even-grid parity obstructions
18
+ self.r = [1] * 4
19
+ else:
20
+ self.r = [1] * k
21
+
22
+ self.perms = {}
23
+ for s in range(m):
24
+ if k == 3:
25
+ if s < m - 2: p = [0, 1, 2]
26
+ elif s == m - 2: p = [0, 2, 1]
27
+ else: p = [1, 0, 2]
28
+ elif k == 2:
29
+ if s == 0: p = [0, 1]
30
+ else: p = [1, 0]
31
+ elif k == 4:
32
+ # Balanced distribution for k=4
33
+ p = [0, 1, 2, 3]
34
+ if s % 2 == 1: p = [2, 3, 0, 1]
35
+ else:
36
+ p = list(range(k))
37
+ self.perms[s] = p
38
+
39
+ self.anomalies = {}
40
+
41
+ def get_permutation(self, x):
42
+ s = sum(x) % self.m
43
+ if (tuple(x), s) in self.anomalies:
44
+ return self.anomalies[(tuple(x), s)]
45
+
46
+ p = list(self.perms.get(s, list(range(self.k))))
47
+ if self.k == 3 and self.m % 2 != 0:
48
+ if x[1] == 0 and s != self.m - 2:
49
+ d0_idx = p.index(0); d2_idx = p.index(2)
50
+ p[d0_idx], p[d2_idx] = 2, 0
51
+ return p
52
+
53
+ def step(self, x, color):
54
+ p = self.get_permutation(x)
55
+ dim = p[color % len(p)]
56
+ nx = list(x)
57
+ nx[dim] = (nx[dim] + self.r[dim]) % self.m
58
+ return tuple(nx), dim
59
+
60
+ def trace_cycle(self, color, start_node=None):
61
+ if start_node is None:
62
+ start_node = tuple([0] * self.k)
63
+ visited = []
64
+ visited_set = set()
65
+ edges = set()
66
+ curr = start_node
67
+ for _ in range(self.m ** self.k + 1):
68
+ if curr in visited_set:
69
+ break
70
+ visited.append(curr)
71
+ visited_set.add(curr)
72
+ next_node, dim = self.step(curr, color)
73
+ edges.add((curr, dim))
74
+ curr = next_node
75
+ return visited, edges, curr
76
+
77
+ def verify_fso_routing(m, k=3, router=None, silent=False):
78
+ if router is None:
79
+ router = FSORouter(m, k)
80
+ all_edges = set(); total_nodes = m ** k; success = True
81
+ results = []
82
+ for color in range(k):
83
+ nodes, edges, final_node = router.trace_cycle(color)
84
+ is_ham = len(nodes) == total_nodes and final_node == nodes[0]
85
+ results.append(is_ham)
86
+ if not is_ham: success = False
87
+ all_edges.update(edges)
88
+
89
+ final_success = success and (len(all_edges) == k * total_nodes)
90
+ if not silent:
91
+ print(f"Verification (m={m}, k={k}): Hamiltonian={results}, Success={final_success}")
92
+ return final_success
93
+
94
+ def repair_manifold(m, k, max_iterations=2000):
95
+ router = FSORouter(m, k)
96
+ if verify_fso_routing(m, k, router, silent=True):
97
+ return router
98
+
99
+ for attempt in range(max_iterations):
100
+ color = random.randint(0, k - 1)
101
+ nodes, edges, final_node = router.trace_cycle(color)
102
+ if len(nodes) < m**k:
103
+ tail = nodes[-1]
104
+ s = sum(tail) % m
105
+ p = list(router.get_permutation(tail))
106
+ i, j = random.sample(range(k), 2)
107
+ p[i], p[j] = p[j], p[i]
108
+ router.anomalies[(tail, s)] = p
109
+
110
+ if verify_fso_routing(m, k, router, silent=True):
111
+ print(f"Repair successful for G_{m}^{k} at attempt {attempt}!")
112
+ verify_fso_routing(m, k, router)
113
+ return router
114
+
115
+ print(f"Repair failed for G_{m}^{k}.")
116
+ return None
117
+
118
+ if __name__ == "__main__":
119
+ print("\n--- Standard Verifications ---")
120
+ verify_fso_routing(3, 3)
121
+
122
+ print("\n--- Law I Escape: Testing k=4 for even grids ---")
123
+ # m=2, k=3 is obstructed
124
+ verify_fso_routing(2, 3)
125
+ # m=2, k=4
126
+ repair_manifold(2, 4)