import random, json, time
from collections import defaultdict
def generate_random_geometric_graph(n_agents, k_neighbors, radius=1.0):
positions = [(random.random() * radius, random.random() * radius) for _ in range(n_agents)]
edges = set()
for i in range(n_agents):
dists = [(j, (positions[i][0]-positions[j][0])**2 + (positions[i][1]-positions[j][1])**2)
for j in range(n_agents) if j != i]
dists.sort(key=lambda x: x[1])
for j, _ in dists[:k_neighbors]:
edges.add((min(i,j), max(i,j)))
return edges
def check_laman_condition(n, edges):
if len(edges) < 2 * n - 3:
return False
parent = list(range(n))
def find(x):
while parent[x] != x: parent[x] = parent[parent[x]]; x = parent[x]
return x
def union(a, b): parent[find(a)] = find(b)
for a, b in edges: union(a, b)
roots = set(find(i) for i in range(n))
return len(roots) == 1
def simulate_coordination(n_agents, k_neighbors, steps=100):
success = 0
for _ in range(steps):
positions = [random.gauss(0, 1) for _ in range(n_agents)]
neighbors = defaultdict(list)
for i in range(n_agents):
others = list(range(n_agents))
random.shuffle(others)
neighbors[i] = others[:k_neighbors]
converged = True
target = sum(positions) / n_agents
for i in range(n_agents):
local_avg = sum(positions[j] for j in neighbors[i]) / len(neighbors[i])
if abs(local_avg - target) > 0.5:
converged = False
break
if converged:
success += 1
return success / steps
print("Rigidity Percolation + Coordination Simulation")
print("="*50)
print(f"{'k':>4} {'Rigid%':>8} {'Coord%':>8} {'Edges':>8}")
print("-"*50)
results = []
for k in range(4, 21):
n = 128
trials = 100
rigid_count = sum(1 for _ in range(trials) if check_laman_condition(n, generate_random_geometric_graph(n, k)))
coord_rate = simulate_coordination(n, k, steps=50)
edge_count = n * k // 2
rigid_pct = rigid_count / trials * 100
coord_pct = coord_rate * 100
marker = " ◄◄◄ PHASE TRANSITION" if 10 <= k <= 14 and abs(rigid_pct - 50) < 30 else ""
print(f"{k:>4} {rigid_pct:>7.1f}% {coord_pct:>7.1f}% {edge_count:>8}{marker}")
results.append({"k": k, "rigid_pct": rigid_pct, "coord_pct": coord_pct})
with open("rigidity_results.json", "w") as f:
json.dump(results, f, indent=2)
print("\nResults saved to rigidity_results.json")
print("\nExpected: sharp phase transition at k=12")