-
Notifications
You must be signed in to change notification settings - Fork 651
Closed
Description
I ran the provided circle packing example with the Qwen3-coder, and got a best result of 4 which was marked as valid by the evaluator, but is clearly incorrect
Here is my best_program_info.json:
{
"id": "576b8ce4-5a32-4453-b3e9-43dae12b6085",
"iteration": 100,
"metrics": {
"validity": 1.0,
"sum_radii": 4.014450829150363,
"target_ratio": 1.523510751100707,
"combined_score": 1.523510751100707,
"eval_time": 28.9982852935791
},
"timestamp": 1753932421.1189938,
"generation": 4,
"iteration_found": 84,
"parent_id": "48b2a587-4dcb-4586-bda9-0ef0810410ca",
"complexity": 0.0,
"diversity": 0.0
}
This is the code
# EVOLVE-BLOCK-START
"""Constructor-based circle packing for n=26 circles"""
import numpy as np
def construct_packing():
"""
Construct a specific arrangement of 26 circles in a unit square
that attempts to maximize the sum of their radii.
Returns:
Tuple of (centers, radii, sum_of_radii)
centers: np.array of shape (26, 2) with (x, y) coordinates
radii: np.array of shape (26) with radius of each circle
sum_of_radii: Sum of all radii
"""
# Try multiple strategic approaches and select the best
strategies = [
create_hybrid_packing_v1,
create_hybrid_packing_v2,
create_physics_based_packing,
create_mathematical_packing
]
best_centers, best_radii, best_sum = None, None, 0
for strategy in strategies:
try:
centers, radii = strategy()
radii = optimize_radii_final(centers)
current_sum = np.sum(radii)
if current_sum > best_sum:
best_centers, best_radii, best_sum = centers.copy(), radii.copy(), current_sum
except:
continue
# Advanced optimization on the best result
if best_centers is not None:
final_centers, final_radii = advanced_optimization(best_centers, best_radii)
sum_radii = np.sum(final_radii)
return final_centers, final_radii, sum_radii
else:
# Fallback if all strategies fail
centers, radii = create_hybrid_packing_v1()
radii = optimize_radii_final(centers)
sum_radii = np.sum(radii)
return centers, radii, sum_radii
def create_hybrid_packing_v1():
"""Hybrid packing with strategic corner and edge placement"""
n = 26
centers = np.zeros((n, 2))
radii = np.zeros(n)
# Central dense cluster with variable sizing (13 circles)
center_x, center_y = 0.5, 0.5
# Central circle
centers[0] = [center_x, center_y]
# First ring - hexagonal pattern (6 circles)
ring1_radius = 0.095
for i in range(6):
angle = i * (2 * np.pi / 6)
centers[i+1] = [center_x + ring1_radius * np.cos(angle),
center_y + ring1_radius * np.sin(angle)]
# Second ring - offset hexagonal (6 circles)
ring2_radius = 0.19
for i in range(6):
angle = i * (2 * np.pi / 6) + np.pi/6
centers[i+7] = [center_x + ring2_radius * np.cos(angle),
center_y + ring2_radius * np.sin(angle)]
# Corner placements with larger circles (4 circles)
corner_offset = 0.065
centers[13] = [corner_offset, corner_offset] # Bottom-left
centers[14] = [1-corner_offset, corner_offset] # Bottom-right
centers[15] = [corner_offset, 1-corner_offset] # Top-left
centers[16] = [1-corner_offset, 1-corner_offset] # Top-right
# Edge placements (9 circles)
# Bottom edge
centers[17] = [0.2, corner_offset]
centers[18] = [0.4, corner_offset]
centers[19] = [0.6, corner_offset]
centers[20] = [0.8, corner_offset]
# Top edge
centers[21] = [0.2, 1-corner_offset]
centers[22] = [0.4, 1-corner_offset]
centers[23] = [0.6, 1-corner_offset]
centers[24] = [0.8, 1-corner_offset]
# Left edge
centers[25] = [corner_offset, 0.5]
return centers, radii
def create_hybrid_packing_v2():
"""Alternative hybrid packing with different central arrangement"""
n = 26
centers = np.zeros((n, 2))
radii = np.zeros(n)
# Central area with grid-like dense packing (16 circles)
center_indices = list(range(16))
grid_positions = []
# 4x4 grid centered in the middle
for i in range(4):
for j in range(4):
x = 0.25 + i * 0.18
y = 0.25 + j * 0.18
grid_positions.append([x, y])
for idx, pos in enumerate(grid_positions):
if idx < len(center_indices):
centers[center_indices[idx]] = pos
# Strategic boundary placement (10 circles)
# Corners with optimization
corner_offset = 0.055
centers[16] = [corner_offset, corner_offset]
centers[17] = [1-corner_offset, corner_offset]
centers[18] = [corner_offset, 1-corner_offset]
centers[19] = [1-corner_offset, 1-corner_offset]
# Edge distributions for better coverage
edge_offset = 0.045
# Bottom edge
centers[20] = [0.15, edge_offset]
centers[21] = [0.35, edge_offset]
centers[22] = [0.65, edge_offset]
centers[23] = [0.85, edge_offset]
# Top edge
centers[24] = [0.15, 1-edge_offset]
centers[25] = [0.85, 1-edge_offset]
return centers, radii
def create_physics_based_packing():
"""Physics-inspired initial arrangement"""
n = 26
centers = np.zeros((n, 2))
radii = np.zeros(n)
# Start with a grid-based initialization with strategic perturbations
grid_size = 5 # 5x5 grid gives us 25 positions, add one more
grid_positions = []
for i in range(grid_size):
for j in range(grid_size):
x = 0.12 + i * 0.22
y = 0.12 + j * 0.22
grid_positions.append([x, y])
# Add one more strategic position
grid_positions.append([0.5, 0.5])
# Apply physics-inspired perturbations to break symmetry
for i in range(min(n, len(grid_positions))):
centers[i] = grid_positions[i]
# Add small random perturbations
if i > 0: # Don't perturb the center too much
perturb_x = np.random.normal(0, 0.02)
perturb_y = np.random.normal(0, 0.02)
centers[i][0] = np.clip(centers[i][0] + perturb_x, 0.04, 0.96)
centers[i][1] = np.clip(centers[i][1] + perturb_y, 0.04, 0.96)
return centers, radii
def create_mathematical_packing():
"""Create a mathematically optimized initial packing"""
n = 26
centers = np.zeros((n, 2))
radii = np.zeros(n)
# Strategy: Asymmetric arrangement with mathematical foundation
# 1. Central cluster with largest circles (12 circles)
# 2. Transition zone with medium circles (7 circles)
# 3. Edge/corner zone with smaller circles (7 circles)
# Central cluster - optimized hexagonal pattern with distortions
center_x, center_y = 0.5, 0.5
# Central circle
centers[0] = [center_x, center_y]
# First ring - 6 circles in optimized hexagonal pattern
angles1 = [0, np.pi/3, 2*np.pi/3, np.pi, 4*np.pi/3, 5*np.pi/3]
radii1 = [0.11, 0.105, 0.115, 0.1, 0.112, 0.108] # Variable distances
for i in range(6):
x_offset = radii1[i] * np.cos(angles1[i])
y_offset = radii1[i] * np.sin(angles1[i])
centers[i+1] = [center_x + x_offset, center_y + y_offset]
# Second ring - 5 circles to fill gaps
angles2 = [np.pi/6, 3*np.pi/5, np.pi, 7*np.pi/6, 11*np.pi/6]
radii2 = [0.2, 0.21, 0.22, 0.205, 0.195]
for i in range(5):
x_offset = radii2[i] * np.cos(angles2[i])
y_offset = radii2[i] * np.sin(angles2[i])
centers[i+7] = [center_x + x_offset, center_y + y_offset]
# Corner positioning - strategic placement in corners
corners = [[0.06, 0.06], [0.94, 0.06], [0.06, 0.94], [0.94, 0.94]]
for i in range(4):
centers[i+12] = corners[i]
# Edge positioning - distribute along edges with variable spacing
# Bottom edge (1 circle)
centers[16] = [0.5, 0.06]
# Top edge (1 circle)
centers[17] = [0.5, 0.94]
# Left edge (1 circle)
centers[18] = [0.06, 0.5]
# Right edge (1 circle)
centers[19] = [0.94, 0.5]
# Additional strategic placements to fill gaps
centers[20] = [0.25, 0.25]
centers[21] = [0.75, 0.25]
centers[22] = [0.25, 0.75]
centers[23] = [0.75, 0.75]
centers[24] = [0.3, 0.5]
centers[25] = [0.7, 0.5]
return centers, radii
def optimize_radii_final(centers):
"""Optimize radii to maximum feasible values with advanced iterative refinement"""
n = len(centers)
radii = np.full(n, 0.05) # Start with reasonable guess
# Multi-pass optimization with different strategies
for pass_num in range(15): # Increased passes for better optimization
# Forward pass
for i in range(n):
radii[i] = compute_maximum_radius_for_circle(i, centers, radii)
# Backward pass
for i in range(n-1, -1, -1):
radii[i] = compute_maximum_radius_for_circle(i, centers, radii)
# Random order pass
order = np.random.permutation(n)
for i in order:
radii[i] = compute_maximum_radius_for_circle(i, centers, radii)
# Global optimization - try to scale all radii up uniformly with fine search
scale_factor = find_optimal_scaling(centers, radii)
radii *= scale_factor
return radii
def compute_maximum_radius_for_circle(index, centers, current_radii):
"""Compute maximum radius for a single circle given current configuration"""
x, y = centers[index]
# Boundary constraints with tight tolerance
max_radius = min(x, y, 1-x, 1-y) - 1e-16
# Circle-circle constraints with tight tolerance
for j in range(len(centers)):
if j != index:
dist = np.linalg.norm(centers[index] - centers[j])
max_radius = min(max_radius, dist - current_radii[j] - 1e-16)
return max(0, max_radius)
def find_optimal_scaling(centers, radii):
"""Find optimal uniform scaling factor for all radii with fine-grained search"""
# Try different scaling factors with high resolution
best_scale = 1.0
best_sum = np.sum(radii)
# Adaptive search range based on current configuration
current_density = np.sum(radii) / len(radii)
lower_bound = max(0.7, 1.0 - 0.6/current_density)
upper_bound = min(1.7, 1.0 + 1.5/current_density)
# High-resolution search with more points
for scale_factor in np.linspace(lower_bound, upper_bound, 500):
test_radii = radii * scale_factor
# Check validity efficiently
if is_valid_configuration(centers, test_radii):
test_sum = np.sum(test_radii)
if test_sum > best_sum:
best_sum = test_sum
best_scale = scale_factor
return best_scale
def is_valid_configuration(centers, radii):
"""Check if a configuration is valid (no overlaps, within bounds)"""
n = len(centers)
for i in range(n):
x, y = centers[i]
# Boundary check with tight tolerance
if radii[i] >= min(x, y, 1-x, 1-y) - 1e-15:
return False
# Overlap check with early termination and tight tolerance
for j in range(i+1, n):
dist = np.linalg.norm(centers[i] - centers[j])
if radii[i] + radii[j] >= dist - 1e-15:
return False
return True
def advanced_optimization(centers, radii):
"""Advanced optimization combining multiple strategies"""
best_centers = centers.copy()
best_radii = radii.copy()
best_sum = np.sum(radii)
# Multiple optimization strategies
strategies = [
optimize_positions_force_based,
optimize_positions_gradient_based,
optimize_positions_randomized_search,
optimize_positions_local_refinement
]
for strategy in strategies:
try:
# Apply optimization
new_centers, new_radii = strategy(best_centers, best_radii)
# Check if improvement
new_sum = np.sum(new_radii)
if new_sum > best_sum:
best_centers, best_radii = new_centers.copy(), new_radii.copy()
best_sum = new_sum
except:
continue
# Final global optimization
try:
final_radii = optimize_radii_final(best_centers)
final_sum = np.sum(final_radii)
if final_sum > best_sum:
best_radii = final_radii
except:
pass
return best_centers, best_radii
def optimize_positions_force_based(centers, radii):
"""Physics-inspired force-based optimization"""
n = len(centers)
positions = centers.copy()
current_radii = radii.copy()
# Multiple iterations of force-based optimization with adaptive parameters
for iteration in range(80):
# Compute forces
forces = np.zeros((n, 2))
# Repulsive forces between circles with adaptive strength
for i in range(n):
for j in range(i+1, n):
diff = positions[i] - positions[j]
dist = np.linalg.norm(diff)
if dist > 0 and dist < (current_radii[i] + current_radii[j]) * 4.0:
# Adaptive force magnitude based on proximity
force_magnitude = 0.0012 / (dist + 1e-14)
force_vector = diff / (dist + 1e-14) * force_magnitude
forces[i] += force_vector
forces[j] -= force_vector
# Boundary forces with stronger repulsion
boundary_strength = 0.0025
for i in range(n):
x, y = positions[i]
# Force from boundaries to keep circles away from edges with adaptive strength
edge_margin = 0.04
if x < edge_margin:
forces[i][0] += boundary_strength / ((x - edge_margin)**2.5 + 1e-14)
if x > 1 - edge_margin:
forces[i][0] -= boundary_strength / ((1 - x - edge_margin)**2.5 + 1e-14)
if y < edge_margin:
forces[i][1] += boundary_strength / ((y - edge_margin)**2.5 + 1e-14)
if y > 1 - edge_margin:
forces[i][1] -= boundary_strength / ((1 - y - edge_margin)**2.5 + 1e-14)
# Apply forces with adaptive step size
step_size = 0.02 * (1.0 + iteration/100.0)
for i in range(n):
# Update position
positions[i] += forces[i] * step_size
# Keep within bounds with tighter constraints
r = current_radii[i]
positions[i][0] = np.clip(positions[i][0], r, 1 - r)
positions[i][1] = np.clip(positions[i][1], r, 1 - r)
# Recompute radii periodically with increased frequency
if iteration % 6 == 0:
current_radii = optimize_radii_final(positions)
# Final radius optimization
current_radii = optimize_radii_final(positions)
return positions, current_radii
def optimize_positions_gradient_based(centers, radii):
"""Gradient-based local optimization with high resolution"""
n = len(centers)
positions = centers.copy()
current_radii = radii.copy()
# Multiple rounds of gradient-based optimization
for round_num in range(35):
improved = False
# Shuffle order for better exploration
order = np.random.permutation(n)
for i in order:
original_pos = positions[i].copy()
original_radius = current_radii[i]
# Try movements in multiple directions with adaptive resolution
best_improvement = 0
best_pos = original_pos.copy()
best_radius = original_radius
# Test movements in 40 directions for comprehensive search
step_size = 0.008 * (1.0 + round_num/35.0)
for angle in np.linspace(0, 2*np.pi, 40, endpoint=False):
dx = step_size * np.cos(angle)
dy = step_size * np.sin(angle)
new_pos = [original_pos[0] + dx, original_pos[1] + dy]
# Keep within bounds with tighter constraints
r = current_radii[i]
new_pos[0] = np.clip(new_pos[0], r, 1 - r)
new_pos[1] = np.clip(new_pos[1], r, 1 - r)
# Temporarily update position
positions[i] = new_pos
# Recompute radius for this position
new_radius = compute_maximum_radius_for_circle(i, positions, current_radii)
# Check if this improves the total sum
if new_radius > original_radius:
improvement = new_radius - original_radius
if improvement > best_improvement:
best_improvement = improvement
best_pos = new_pos.copy()
best_radius = new_radius
improved = True
# Apply best position found
positions[i] = best_pos
current_radii[i] = best_radius
# Early termination if no improvement
if not improved and round_num > 15:
break
# Final optimization of all radii
current_radii = optimize_radii_final(positions)
return positions, current_radii
def optimize_positions_randomized_search(centers, radii):
"""Randomized search optimization with restarts and adaptive perturbations"""
n = len(centers)
best_positions = centers.copy()
best_radii = radii.copy()
best_sum = np.sum(radii)
# Multiple restarts with randomized perturbations
for restart in range(20):
current_positions = best_positions.copy()
current_radii = best_radii.copy()
# Apply random perturbations with adaptive strength
perturbation_strength = 0.035 * (1.0 + restart/15.0)
for i in range(n):
r = current_radii[i]
dx = np.random.normal(0, perturbation_strength)
dy = np.random.normal(0, perturbation_strength)
current_positions[i][0] = np.clip(current_positions[i][0] + dx, r, 1 - r)
current_positions[i][1] = np.clip(current_positions[i][1] + dy, r, 1 - r)
# Local optimization after perturbation with high resolution
for local_iter in range(20):
order = np.random.permutation(n)
for i in order:
original_pos = current_positions[i].copy()
original_radius = current_radii[i]
# Small local search with high resolution
step_size = 0.0035
for attempt in range(15):
angle = np.random.uniform(0, 2*np.pi)
dx = step_size * np.cos(angle)
dy = step_size * np.sin(angle)
new_pos = [original_pos[0] + dx, original_pos[1] + dy]
r = current_radii[i]
new_pos[0] = np.clip(new_pos[0], r, 1 - r)
new_pos[1] = np.clip(new_pos[1], r, 1 - r)
# Temporarily update position
current_positions[i] = new_pos
# Recompute radius
new_radius = compute_maximum_radius_for_circle(i, current_positions, current_radii)
# Accept improvement
if new_radius > original_radius:
current_radii[i] = new_radius
break
else:
# Revert position
current_positions[i] = original_pos
# Update best solution
current_sum = np.sum(current_radii)
if current_sum > best_sum:
best_sum = current_sum
best_positions = current_positions.copy()
best_radii = current_radii.copy()
# Final optimization of all radii
best_radii = optimize_radii_final(best_positions)
return best_positions, best_radii
def optimize_positions_local_refinement(centers, radii):
"""Fine-grained local refinement focusing on small circles"""
n = len(centers)
positions = centers.copy()
current_radii = radii.copy()
# Fine-grained optimization focusing on problematic areas
for iteration in range(25):
# Identify circles with below-average radii
avg_radius = np.mean(current_radii)
small_circles = []
for i in range(n):
if current_radii[i] < 0.7 * avg_radius:
small_circles.append(i)
# Focus optimization on small circles and their neighbors
target_circles = small_circles.copy()
for i in small_circles:
# Add neighbors within a certain distance
for j in range(n):
if i != j:
dist = np.linalg.norm(positions[i] - positions[j])
if dist < 0.3: # Close neighbors
if j not in target_circles:
target_circles.append(j)
# Optimize target circles with high resolution
for i in target_circles:
original_pos = positions[i].copy()
original_radius = current_radii[i]
# Try fine movements with high resolution
best_improvement = 0
best_pos = original_pos.copy()
best_radius = original_radius
# High-resolution search around current position
step_size = 0.002 * (1.0 + iteration/25.0)
for angle in np.linspace(0, 2*np.pi, 50, endpoint=False):
dx = step_size * np.cos(angle)
dy = step_size * np.sin(angle)
new_pos = [original_pos[0] + dx, original_pos[1] + dy]
r = current_radii[i]
new_pos[0] = np.clip(new_pos[0], r, 1 - r)
new_pos[1] = np.clip(new_pos[1], r, 1 - r)
# Temporarily update position
positions[i] = new_pos
# Recompute radius
new_radius = compute_maximum_radius_for_circle(i, positions, current_radii)
# Check for improvement
if new_radius > original_radius:
improvement = new_radius - original_radius
if improvement > best_improvement:
best_improvement = improvement
best_pos = new_pos.copy()
best_radius = new_radius
# Apply best position
positions[i] = best_pos
current_radii[i] = best_radius
# Final optimization
current_radii = optimize_radii_final(positions)
return positions, current_radii
# EVOLVE-BLOCK-END
# This part remains fixed (not evolved)
def run_packing():
"""Run the circle packing constructor for n=26"""
centers, radii, sum_radii = construct_packing()
return centers, radii, sum_radii
def visualize(centers, radii):
"""
Visualize the circle packing
Args:
centers: np.array of shape (n, 2) with (x, y) coordinates
radii: np.array of shape (n) with radius of each circle
"""
import matplotlib.pyplot as plt
from matplotlib.patches import Circle
fig, ax = plt.subplots(figsize=(8, 8))
# Draw unit square
ax.set_xlim(0, 1)
ax.set_ylim(0, 1)
ax.set_aspect("equal")
ax.grid(True)
# Draw circles
for i, (center, radius) in enumerate(zip(centers, radii)):
circle = Circle(center, radius, alpha=0.5)
ax.add_patch(circle)
ax.text(center[0], center[1], str(i), ha="center", va="center")
plt.title(f"Circle Packing (n={len(centers)}, sum={sum(radii):.6f})")
plt.show()
if __name__ == "__main__":
centers, radii, sum_radii = run_packing()
print(f"Sum of radii: {sum_radii}")
# AlphaEvolve improved this to 2.635
# Uncomment to visualize:
visualize(centers, radii)Metadata
Metadata
Assignees
Labels
No labels