|
|
import sys |
|
|
import random |
|
|
import json |
|
|
import os |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_barycentric_grid(n): |
|
|
|
|
|
|
|
|
vertices = [] |
|
|
coord_to_idx = {} |
|
|
idx = 0 |
|
|
for y in range(n + 1): |
|
|
for x in range(n - y + 1): |
|
|
vertices.append((x, y)) |
|
|
coord_to_idx[(x, y)] = idx |
|
|
idx += 1 |
|
|
return vertices, coord_to_idx |
|
|
|
|
|
def get_triangles(n, coord_to_idx): |
|
|
triangles = [] |
|
|
|
|
|
for y in range(n): |
|
|
for x in range(n - y): |
|
|
|
|
|
v1 = coord_to_idx[(x, y)] |
|
|
v2 = coord_to_idx[(x + 1, y)] |
|
|
v3 = coord_to_idx[(x, y + 1)] |
|
|
triangles.append([v1, v2, v3]) |
|
|
|
|
|
|
|
|
if x + y + 1 < n: |
|
|
v4 = coord_to_idx[(x + 1, y)] |
|
|
v5 = coord_to_idx[(x + 1, y + 1)] |
|
|
v6 = coord_to_idx[(x, y + 1)] |
|
|
triangles.append([v4, v5, v6]) |
|
|
return triangles |
|
|
|
|
|
def is_boundary(x, y, n): |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if y == 0: return 0 |
|
|
if x == 0: return 2 |
|
|
if x + y == n: return 1 |
|
|
return -1 |
|
|
|
|
|
def color_grid(vertices, n): |
|
|
colors = [] |
|
|
for x, y in vertices: |
|
|
boundary_type = is_boundary(x, y, n) |
|
|
|
|
|
|
|
|
if x == n and y == 0: |
|
|
c = 1 |
|
|
elif x == 0 and y == n: |
|
|
c = 2 |
|
|
elif x == 0 and y == 0: |
|
|
c = 0 |
|
|
elif boundary_type != -1: |
|
|
|
|
|
|
|
|
if boundary_type == 0: c = random.choice([0, 1]) |
|
|
elif boundary_type == 2: c = random.choice([0, 2]) |
|
|
else: c = random.choice([1, 2]) |
|
|
else: |
|
|
|
|
|
c = random.randint(0, 2) |
|
|
colors.append(c) |
|
|
return colors |
|
|
|
|
|
def find_sperner_triangle(triangles, colors): |
|
|
|
|
|
|
|
|
target_set = {0, 1, 2} |
|
|
for i, tri in enumerate(triangles): |
|
|
tri_colors = {colors[v] for v in tri} |
|
|
if tri_colors == target_set: |
|
|
return i, tri |
|
|
return -1, [] |
|
|
|
|
|
def generate_sample(size): |
|
|
verts, v_map = get_barycentric_grid(size) |
|
|
tris = get_triangles(size, v_map) |
|
|
colors = color_grid(verts, size) |
|
|
|
|
|
solution_idx, solution_tri = find_sperner_triangle(tris, colors) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return { |
|
|
"n": size, |
|
|
"vertices": verts, |
|
|
"triangles": tris, |
|
|
"vertex_colors": colors, |
|
|
"solution_index": solution_idx, |
|
|
"solution_vertices": solution_tri |
|
|
} |
|
|
|
|
|
if __name__ == "__main__": |
|
|
|
|
|
dataset = [] |
|
|
print("Generating dataset...") |
|
|
for i in range(100): |
|
|
|
|
|
sample_n = random.randint(5, 15) |
|
|
try: |
|
|
data = generate_sample(sample_n) |
|
|
|
|
|
if data["solution_index"] != -1: |
|
|
dataset.append(data) |
|
|
except Exception as e: |
|
|
pass |
|
|
|
|
|
output_file = "sperner_dataset.json" |
|
|
with open(output_file, "w") as f: |
|
|
json.dump(dataset, f, indent=2) |
|
|
print(f"Generated {len(dataset)} samples into {output_file}") |
|
|
|