Skip to content

Commit 897cb78

Browse files
authored
Merge pull request #302 from HenriqueAssumpcao/feature/alphaevolve_math_problems
Add all AlphaEvolve mathematical problems
2 parents e20547c + e614e17 commit 897cb78

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

+4053
-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: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
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: 40
19+
num_islands: 5
20+
migration_interval: 40
21+
feature_dimensions: # MUST be a list, not an integer
22+
- "score"
23+
- "complexity"
24+
25+
# Evaluation settings
26+
evaluator:
27+
timeout: 360
28+
max_retries: 3
29+
30+
# Prompt configuration
31+
prompt:
32+
system_message: |
33+
SETTING:
34+
You are an expert computational geometer and optimization specialist with deep expertise in circle packing problems, geometric optimization algorithms, and constraint satisfaction.
35+
Your mission is to evolve and optimize a constructor function that generates an optimal arrangement of exactly 21 non-overlapping circles within a rectangle, maximizing the sum of their radii.
36+
37+
PROBLEM CONTEXT:
38+
- **Objective**: Create a function that returns optimal (x, y, radius) coordinates for 21 circles
39+
- **Benchmark**: Beat the AlphaEvolve state-of-the-art result of sum_radii = 2.3658321334167627
40+
- **Container**: Rectangle with perimeter = 4 (width + height = 2). You may choose optimal width/height ratio
41+
- **Constraints**:
42+
* All circles must be fully contained within rectangle boundaries
43+
* No circle overlaps (distance between centers ≥ sum of their radii)
44+
* Exactly 21 circles required
45+
* All radii must be positive
46+
47+
PERFORMANCE METRICS:
48+
1. **sum_radii**: Total sum of all 21 circle radii (PRIMARY OBJECTIVE - maximize)
49+
2. **combined_score**: sum_radii / 2.3658321334167627 (progress toward beating benchmark)
50+
3. **eval_time**: Execution time in seconds (keep reasonable, prefer accuracy over speed)
51+
52+
TECHNICAL REQUIREMENTS:
53+
- **Determinism**: Use fixed random seeds if employing stochastic methods for reproducibility
54+
- **Error handling**: Graceful handling of optimization failures or infeasible configurations
55+
- **Memory efficiency**: Avoid excessive memory allocation for distance matrix computations
56+
- **Scalability**: Design with potential extension to different circle counts in mind
57+
58+
num_top_programs: 3
59+
num_diverse_programs: 2
60+
61+
# Logging
62+
log_level: "INFO"
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
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 {"combined_score": 0.0, "error": str(e)}
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: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# Evolution settings
2+
max_iterations: 200
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: 40
19+
num_islands: 5
20+
migration_interval: 40
21+
feature_dimensions: # MUST be a list, not an integer
22+
- "score"
23+
- "complexity"
24+
25+
# Evaluation settings
26+
evaluator:
27+
timeout: 360
28+
max_retries: 3
29+
30+
# Prompt configuration
31+
prompt:
32+
system_message: |
33+
SETTING:
34+
You are an expert in harmonic analysis, numerical optimization, and AI-driven mathematical discovery.
35+
Your task is to evolve and optimize a Python script to find a better **upper bound** for the Erdős minimum overlap problem constant C₅.
36+
37+
PROBLEM CONTEXT:
38+
Target: Find a step function h: [0, 2] → [0, 1] that **minimizes** the objective:
39+
max_k ∫ h(x)(1 - h(x+k)) dx
40+
41+
This minimal value provides a tight upper bound for the constant C5.
42+
43+
Current best known upper bound: C5 ≤ 0.38092303510845016
44+
Goal: Find a step function `h` that results in a C5 value lower than 0.38092303510845016.
45+
46+
CONSTRAINTS:
47+
1. The function `h` must have values in the range [0, 1].
48+
2. The integral of h(x) over [0, 2] must be exactly 1.
49+
50+
PERFORMANCE METRICS:
51+
- c5_bound: The bound found by the program.
52+
- combined_score: 0.38092303510845016 / c5_bound (The primary objective is to MAXIMIZE this value - a value > 1 means a new record).
53+
- n_points: number of points used in the discretization.
54+
- eval_time: evaluation time of the program.
55+
56+
num_top_programs: 3
57+
num_diverse_programs: 2
58+
59+
# Logging
60+
log_level: "INFO"
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
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 {"combined_score": 0.0, "error": str(e)}

0 commit comments

Comments
 (0)