Skip to content

Commit 65ff9f6

Browse files
add all experiments from Appendices A and B from AlphaEvolve
1 parent e20547c commit 65ff9f6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+3647
-0
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
## AlphaEvolve mathematical problems
2+
3+
This folder contains the necessary evaluator and initial program files for all of the 14 problems from [AlphaEvolve's Appendices A and B](https://storage.googleapis.com/deepmind-media/DeepMind.com/Blog/alphaevolve-a-gemini-powered-coding-agent-for-designing-advanced-algorithms/AlphaEvolve.pdf). The circle packing problem was among the first implemented by OpenEvolve. This folder implements the remaining 13 problems.
4+
5+
Not all problems take the form of a maximization problem, however in order to make this problem set more standardized we chose to **make it so all evaluator files are aiming to maximize the target metric**. We achieve by some straightforward algebraic manipulation, but this can be easily edited and changed if the user finds it necessary.
6+
7+
The problem from Appendix A is the following:
8+
- **Matrix multiplication** (```./matmul/```): obtain a faster algorithm for multiplying two matrices of sizes $m \times n$ and $n \times p$ (c.f. Appendix A).
9+
10+
The remaining problems are from Appendix B:
11+
1. **First autocorrelation inequality** (```./first_autocorr_ineq/```): Construct a nonnegative step function $f:\mathbb{R} \mapsto \mathbb{R}$ to improve an upper bound on a constant related to the autoconvolution of $f$ (c.f. Appendix B.1.).
12+
2. **Second autocorrelation inequality** (```./second_autocorr_ineq/```): Construct a nonnegative step function $f:\mathbb{R} \mapsto \mathbb{R}$ to improve a lower bound on a constant related to the norm of the autoconvolution of $f$ (c.f. Appendix B.2.).
13+
3. **Third autocorrelation inequality** (```./third_autocorr_ineq/```): Construct a nonnegative step function $f:\mathbb{R} \mapsto \mathbb{R}$ to improve an upper bound on a constant related to th absolute value of the autoconvolution of $f$ (c.f. Appendix B.3.).
14+
4. **An uncertainty inequality** (```./uncertainty_ineq/```): Construct a function $f:\mathbb{R} \mapsto \mathbb{R}$ to obtain an upper bound on a constant related to $f$ and its fourier transform. (c.f. Appendix B.4.).
15+
5. **Erdos minimum overlap problem** (```./erdos_min_overlap/```): Construct a nonnegative step function $f:\mathbb{R} \mapsto \mathbb{R}$ satisfyind some special properties to improve an upper bound on a constant that controls the asymptotics of the Minimum Overlap Problem (c.f. Appendix B.5.).
16+
6. **Sums and differences of finite sets** (```./sums_diffs_finite_sets/```): Construct a set of nonnegative integers $U$ satisfying some special properties to improve a lower bound to a constant related to sums and differences of finite sets (c.f. Appendix B.6.).
17+
7. **Packing unit regular hexagons inside a regular hexagon** (```./hexagon_packing/```): Place $n$ disjoint unit regular hexagons inside a larger regular hexagon, minimizing the side length of the outer hexagon. We consider the case where $n = 11$ and $n = 12$ (c.f. Appendix B.7.).
18+
8. **Minimizing the ratio of maximum to minimum distance** (```./minimizing_max_min_dist/```): Place $n$ $d$-dimensional points in order to minimize the ratio between the maximum and minimum pairwise distances. We consider the cases where $n=16,d=2$ and $n=14,d=3$ (c.f. Appendix B.8.).
19+
9. **The Heilbronn problem for triangles** (```./heilbronn_triangle/```): Place $n$ points on or inside a triangle with unit area so that the area of the smallest triangle formed by these points is maximized. We consider the case where $n = 11$ (c.f. Appendix B.9.).
20+
10. **The Heilbronn problem for convex regions** (```./heilbronn_convex/```): Place $n$ points on or inside a convex region with unit area so that the area of the smallest triangle formed by these points is maximized. We consider the case where $n = 13$ and $n=14$ (c.f. Appendix B.10.).
21+
11. **Kissing number in dimension 11** (```./kissing_number/```): Increase the lower bound on the $11$-dimensional kissing number, i.e., the number of disjoint unit spheres that can be packed tangent to a given unit sphere (c.f. Appendix B.11.).
22+
12. **Packing circles inside a unit square to maximize sum of radii** (```../circle_packing/```): Place $n$ disjoint circles inside a unit square so as to maximize the sum of their radii (c.f. Appendix B.12.).
23+
13. **Packing circles inside a rectangle of perimeter 4 to maximize sum of radii** (```./circle_packing_rect/```): Place $n$ disjoint circles inside a rectangle of perimeter $4$ so as to maximize the sum of their radii (c.f. Appendix B.13.).
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Evolution settings
2+
max_iterations: 100
3+
checkpoint_interval: 10
4+
parallel_evaluations: 1
5+
6+
# LLM configuration
7+
llm:
8+
api_base: "https://api.openai.com/v1" # Or your LLM provider
9+
models:
10+
- name: "gpt-4"
11+
weight: 1.0
12+
temperature: 0.7
13+
max_tokens: 4000
14+
timeout: 120
15+
16+
# Database configuration (MAP-Elites algorithm)
17+
database:
18+
population_size: 50
19+
num_islands: 3
20+
migration_interval: 10
21+
feature_dimensions: # MUST be a list, not an integer
22+
- "score"
23+
- "complexity"
24+
25+
# Evaluation settings
26+
evaluator:
27+
timeout: 60
28+
max_retries: 3
29+
30+
# Prompt configuration
31+
prompt:
32+
system_message: |
33+
You are an expert programmer. Your goal is to improve the code
34+
in the EVOLVE-BLOCK to achieve better performance on the task.
35+
36+
Focus on algorithmic improvements and code optimization.
37+
num_top_programs: 3
38+
num_diverse_programs: 2
39+
40+
# Logging
41+
log_level: "INFO"
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
# ===--------------------------------------------------------------------------------------===#
2+
#
3+
# This file implements the evaluator for the circle packing problem on a rectangle
4+
# of perimeter 4.
5+
#
6+
# ===--------------------------------------------------------------------------------------===#
7+
#
8+
# Some of the code in this file is adapted from:
9+
#
10+
# google-deepmind/alphaevolve_results:
11+
# Licensed under the Apache License v2.0.
12+
#
13+
# ===--------------------------------------------------------------------------------------===#
14+
15+
import time
16+
import numpy as np
17+
import sys
18+
import os
19+
from importlib import __import__
20+
21+
BENCHMARK = 2.3658321334167627
22+
NUM_CIRCLES = 21
23+
TOL = 1e-6
24+
25+
26+
def minimum_circumscribing_rectangle(circles: np.ndarray):
27+
"""Returns the width and height of the minimum circumscribing rectangle.
28+
29+
Args:
30+
circles: A numpy array of shape (num_circles, 3), where each row is of the
31+
form (x, y, radius), specifying a circle.
32+
33+
Returns:
34+
A tuple (width, height) of the minimum circumscribing rectangle.
35+
"""
36+
min_x = np.min(circles[:, 0] - circles[:, 2])
37+
max_x = np.max(circles[:, 0] + circles[:, 2])
38+
min_y = np.min(circles[:, 1] - circles[:, 2])
39+
max_y = np.max(circles[:, 1] + circles[:, 2])
40+
return max_x - min_x, max_y - min_y
41+
42+
43+
def validate_packing_radii(radii: np.ndarray) -> None:
44+
n = len(radii)
45+
for i in range(n):
46+
if radii[i] < 0:
47+
raise ValueError(f"Circle {i} has negative radius {radii[i]}")
48+
elif np.isnan(radii[i]):
49+
raise ValueError(f"Circle {i} has nan radius")
50+
51+
52+
def validate_packing_overlap_wtol(circles: np.ndarray, tol: float = 1e-6) -> None:
53+
n = len(circles)
54+
for i in range(n):
55+
for j in range(i + 1, n):
56+
dist = np.sqrt(np.sum((circles[i, :2] - circles[j, :2]) ** 2))
57+
if dist < circles[i, 2] + circles[j, 2] - tol:
58+
raise ValueError(
59+
f"Circles {i} and {j} overlap: dist={dist}, r1+r2={circles[i,2]+circles[j,2]}"
60+
)
61+
62+
63+
def validate_packing_inside_rect_wtol(circles: np.array, tol: float = 1e-6) -> None:
64+
width, height = minimum_circumscribing_rectangle(circles)
65+
if width + height > (2 + tol):
66+
raise ValueError("Circles are not contained inside a rectangle of perimeter 4.")
67+
68+
69+
def evaluate(program_path: str):
70+
try:
71+
abs_program_path = os.path.abspath(program_path)
72+
program_dir = os.path.dirname(abs_program_path)
73+
module_name = os.path.splitext(os.path.basename(program_path))[0]
74+
75+
circles = None
76+
eval_time = 0
77+
try:
78+
sys.path.insert(0, program_dir)
79+
program = __import__(module_name)
80+
81+
start_time = time.time()
82+
circles = program.circle_packing21()
83+
end_time = time.time()
84+
eval_time = end_time - start_time
85+
except Exception as err:
86+
raise err
87+
finally:
88+
if program_dir in sys.path:
89+
sys.path.remove(program_dir)
90+
91+
if not isinstance(circles, np.ndarray):
92+
circles = np.array(circles)
93+
94+
if circles.shape != (NUM_CIRCLES, 3):
95+
raise ValueError(
96+
f"Invalid shapes: circles = {circles.shape}, expected {(NUM_CIRCLES,3)}"
97+
)
98+
99+
validate_packing_radii(circles[:, -1])
100+
validate_packing_overlap_wtol(circles, TOL)
101+
validate_packing_inside_rect_wtol(circles, TOL)
102+
103+
radii_sum = np.sum(circles[:, -1])
104+
105+
return {
106+
"radii_sum": float(radii_sum),
107+
"combined_score": float(radii_sum / BENCHMARK),
108+
"eval_time": float(eval_time)
109+
}
110+
except Exception as e:
111+
return {
112+
'combined_score': 0.0,
113+
'error': str(e)
114+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# EVOLVE-BLOCK-START
2+
import numpy as np
3+
4+
5+
def circle_packing21() -> np.ndarray:
6+
"""
7+
Places 21 non-overlapping circles inside a rectangle of perimeter 4 in order to maximize the sum of their radii.
8+
9+
Returns:
10+
circles: np.array of shape (21,3), where the i-th row (x,y,r) stores the (x,y) coordinates of the i-th circle of radius r.
11+
"""
12+
n = 21
13+
circles = np.zeros((n, 3))
14+
15+
return circles
16+
17+
18+
# EVOLVE-BLOCK-END
19+
20+
if __name__ == "__main__":
21+
circles = circle_packing21()
22+
print(f"Radii sum: {np.sum(circles[:,-1])}")
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
numpy
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Evolution settings
2+
max_iterations: 100
3+
checkpoint_interval: 10
4+
parallel_evaluations: 1
5+
6+
# LLM configuration
7+
llm:
8+
api_base: "https://api.openai.com/v1" # Or your LLM provider
9+
models:
10+
- name: "gpt-4"
11+
weight: 1.0
12+
temperature: 0.7
13+
max_tokens: 4000
14+
timeout: 120
15+
16+
# Database configuration (MAP-Elites algorithm)
17+
database:
18+
population_size: 50
19+
num_islands: 3
20+
migration_interval: 10
21+
feature_dimensions: # MUST be a list, not an integer
22+
- "score"
23+
- "complexity"
24+
25+
# Evaluation settings
26+
evaluator:
27+
timeout: 60
28+
max_retries: 3
29+
30+
# Prompt configuration
31+
prompt:
32+
system_message: |
33+
You are an expert programmer. Your goal is to improve the code
34+
in the EVOLVE-BLOCK to achieve better performance on the task.
35+
36+
Focus on algorithmic improvements and code optimization.
37+
num_top_programs: 3
38+
num_diverse_programs: 2
39+
40+
# Logging
41+
log_level: "INFO"
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# ===--------------------------------------------------------------------------------------===#
2+
#
3+
# This file implements the evaluator for the erdos minimum overlap problem.
4+
#
5+
# ===--------------------------------------------------------------------------------------===#
6+
#
7+
# Some of the code in this file is adapted from:
8+
#
9+
# google-deepmind/alphaevolve_results:
10+
# Licensed under the Apache License v2.0.
11+
#
12+
# ===--------------------------------------------------------------------------------------===#
13+
14+
import sys
15+
import os
16+
from importlib import __import__
17+
import time
18+
import numpy as np
19+
20+
# Known bounds
21+
BENCHMARK = 0.38092303510845016
22+
23+
24+
def verify_c5_solution(h_values: np.ndarray, c5_achieved: float, n_points: int):
25+
"""Verifies the C5 upper bound solution."""
26+
27+
if h_values.shape != (n_points,):
28+
raise ValueError(f"Expected h shape ({n_points},), got {h_values.shape}")
29+
30+
# Verify h(x) in [0, 1] constraint
31+
if np.any(h_values < 0) or np.any(h_values > 1):
32+
raise ValueError(f"h(x) is not in [0, 1]. Range: [{h_values.min()}, {h_values.max()}]")
33+
34+
# Verify integral of h = 1 constraint
35+
dx = 2.0 / n_points
36+
integral_h = np.sum(h_values) * dx
37+
if not np.isclose(integral_h, 1.0, atol=1e-3):
38+
raise ValueError(f"Integral of h is not close to 1. Got: {integral_h:.6f}")
39+
40+
# Re-calculate the C5 bound using np.correlate
41+
j_values = 1.0 - h_values
42+
correlation = np.correlate(h_values, j_values, mode="full") * dx
43+
computed_c5 = np.max(correlation)
44+
45+
# Check for consistency
46+
if not np.isclose(computed_c5, c5_achieved, atol=1e-4):
47+
raise ValueError(f"C5 mismatch: reported {c5_achieved:.6f}, computed {computed_c5:.6f}")
48+
49+
50+
def evaluate(program_path: str):
51+
try:
52+
abs_program_path = os.path.abspath(program_path)
53+
program_dir = os.path.dirname(abs_program_path)
54+
module_name = os.path.splitext(os.path.basename(program_path))[0]
55+
56+
try:
57+
sys.path.insert(0, program_dir)
58+
program = __import__(module_name)
59+
start_time = time.time()
60+
h_values, c5_bound, n_points = program.run()
61+
end_time = time.time()
62+
eval_time = end_time - start_time
63+
finally:
64+
if program_dir in sys.path:
65+
sys.path.remove(program_dir)
66+
67+
verify_c5_solution(h_values, c5_bound, n_points)
68+
69+
return {
70+
"c5_bound": float(c5_bound),
71+
"combined_score": BENCHMARK / float(c5_bound),
72+
"n_points": int(n_points),
73+
"eval_time": float(eval_time)
74+
}
75+
except Exception as e:
76+
return {
77+
'combined_score': 0.0,
78+
'error': str(e)
79+
}

0 commit comments

Comments
 (0)