Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions examples/alphaevolve_math_problems/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
## AlphaEvolve mathematical problems

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.

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.

The problem from Appendix A is the following:
- [Matrix multiplication](matmul): obtain a faster algorithm for multiplying two matrices of sizes $m \times n$ and $n \times p$ (c.f. Appendix A).

The remaining problems are from Appendix B:
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.).
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.).
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.).
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.).
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.).
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.).
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.).
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.).
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.).
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.).
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.).
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.).
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.).
62 changes: 62 additions & 0 deletions examples/alphaevolve_math_problems/circle_packing_rect/config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Evolution settings
max_iterations: 100
checkpoint_interval: 10
parallel_evaluations: 1

# LLM configuration
llm:
api_base: "https://api.openai.com/v1" # Or your LLM provider
models:
- name: "gpt-4"
weight: 1.0
temperature: 0.7
max_tokens: 4000
timeout: 120

# Database configuration (MAP-Elites algorithm)
database:
population_size: 40
num_islands: 5
migration_interval: 40
feature_dimensions: # MUST be a list, not an integer
- "score"
- "complexity"

# Evaluation settings
evaluator:
timeout: 360
max_retries: 3

# Prompt configuration
prompt:
system_message: |
SETTING:
You are an expert computational geometer and optimization specialist with deep expertise in circle packing problems, geometric optimization algorithms, and constraint satisfaction.
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.

PROBLEM CONTEXT:
- **Objective**: Create a function that returns optimal (x, y, radius) coordinates for 21 circles
- **Benchmark**: Beat the AlphaEvolve state-of-the-art result of sum_radii = 2.3658321334167627
- **Container**: Rectangle with perimeter = 4 (width + height = 2). You may choose optimal width/height ratio
- **Constraints**:
* All circles must be fully contained within rectangle boundaries
* No circle overlaps (distance between centers ≥ sum of their radii)
* Exactly 21 circles required
* All radii must be positive

PERFORMANCE METRICS:
1. **sum_radii**: Total sum of all 21 circle radii (PRIMARY OBJECTIVE - maximize)
2. **combined_score**: sum_radii / 2.3658321334167627 (progress toward beating benchmark)
3. **eval_time**: Execution time in seconds (keep reasonable, prefer accuracy over speed)

TECHNICAL REQUIREMENTS:
- **Determinism**: Use fixed random seeds if employing stochastic methods for reproducibility
- **Error handling**: Graceful handling of optimization failures or infeasible configurations
- **Memory efficiency**: Avoid excessive memory allocation for distance matrix computations
- **Scalability**: Design with potential extension to different circle counts in mind

num_top_programs: 3
num_diverse_programs: 2

# Logging
log_level: "INFO"
111 changes: 111 additions & 0 deletions examples/alphaevolve_math_problems/circle_packing_rect/evaluator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# ===--------------------------------------------------------------------------------------===#
#
# This file implements the evaluator for the circle packing problem on a rectangle
# of perimeter 4.
#
# ===--------------------------------------------------------------------------------------===#
#
# Some of the code in this file is adapted from:
#
# google-deepmind/alphaevolve_results:
# Licensed under the Apache License v2.0.
#
# ===--------------------------------------------------------------------------------------===#

import time
import numpy as np
import sys
import os
from importlib import __import__

BENCHMARK = 2.3658321334167627
NUM_CIRCLES = 21
TOL = 1e-6


def minimum_circumscribing_rectangle(circles: np.ndarray):
"""Returns the width and height of the minimum circumscribing rectangle.

Args:
circles: A numpy array of shape (num_circles, 3), where each row is of the
form (x, y, radius), specifying a circle.

Returns:
A tuple (width, height) of the minimum circumscribing rectangle.
"""
min_x = np.min(circles[:, 0] - circles[:, 2])
max_x = np.max(circles[:, 0] + circles[:, 2])
min_y = np.min(circles[:, 1] - circles[:, 2])
max_y = np.max(circles[:, 1] + circles[:, 2])
return max_x - min_x, max_y - min_y


def validate_packing_radii(radii: np.ndarray) -> None:
n = len(radii)
for i in range(n):
if radii[i] < 0:
raise ValueError(f"Circle {i} has negative radius {radii[i]}")
elif np.isnan(radii[i]):
raise ValueError(f"Circle {i} has nan radius")


def validate_packing_overlap_wtol(circles: np.ndarray, tol: float = 1e-6) -> None:
n = len(circles)
for i in range(n):
for j in range(i + 1, n):
dist = np.sqrt(np.sum((circles[i, :2] - circles[j, :2]) ** 2))
if dist < circles[i, 2] + circles[j, 2] - tol:
raise ValueError(
f"Circles {i} and {j} overlap: dist={dist}, r1+r2={circles[i,2]+circles[j,2]}"
)


def validate_packing_inside_rect_wtol(circles: np.array, tol: float = 1e-6) -> None:
width, height = minimum_circumscribing_rectangle(circles)
if width + height > (2 + tol):
raise ValueError("Circles are not contained inside a rectangle of perimeter 4.")


def evaluate(program_path: str):
try:
abs_program_path = os.path.abspath(program_path)
program_dir = os.path.dirname(abs_program_path)
module_name = os.path.splitext(os.path.basename(program_path))[0]

circles = None
eval_time = 0
try:
sys.path.insert(0, program_dir)
program = __import__(module_name)

start_time = time.time()
circles = program.circle_packing21()
end_time = time.time()
eval_time = end_time - start_time
except Exception as err:
raise err
finally:
if program_dir in sys.path:
sys.path.remove(program_dir)

if not isinstance(circles, np.ndarray):
circles = np.array(circles)

if circles.shape != (NUM_CIRCLES, 3):
raise ValueError(
f"Invalid shapes: circles = {circles.shape}, expected {(NUM_CIRCLES,3)}"
)

validate_packing_radii(circles[:, -1])
validate_packing_overlap_wtol(circles, TOL)
validate_packing_inside_rect_wtol(circles, TOL)

radii_sum = np.sum(circles[:, -1])

return {
"radii_sum": float(radii_sum),
"combined_score": float(radii_sum / BENCHMARK),
"eval_time": float(eval_time),
}
except Exception as e:
return {"combined_score": 0.0, "error": str(e)}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# EVOLVE-BLOCK-START
import numpy as np


def circle_packing21() -> np.ndarray:
"""
Places 21 non-overlapping circles inside a rectangle of perimeter 4 in order to maximize the sum of their radii.

Returns:
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.
"""
n = 21
circles = np.zeros((n, 3))

return circles


# EVOLVE-BLOCK-END

if __name__ == "__main__":
circles = circle_packing21()
print(f"Radii sum: {np.sum(circles[:,-1])}")
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
numpy
60 changes: 60 additions & 0 deletions examples/alphaevolve_math_problems/erdos_min_overlap/config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Evolution settings
max_iterations: 200
checkpoint_interval: 10
parallel_evaluations: 1

# LLM configuration
llm:
api_base: "https://api.openai.com/v1" # Or your LLM provider
models:
- name: "gpt-4"
weight: 1.0
temperature: 0.7
max_tokens: 4000
timeout: 120

# Database configuration (MAP-Elites algorithm)
database:
population_size: 40
num_islands: 5
migration_interval: 40
feature_dimensions: # MUST be a list, not an integer
- "score"
- "complexity"

# Evaluation settings
evaluator:
timeout: 360
max_retries: 3

# Prompt configuration
prompt:
system_message: |
SETTING:
You are an expert in harmonic analysis, numerical optimization, and AI-driven mathematical discovery.
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₅.
PROBLEM CONTEXT:
Target: Find a step function h: [0, 2] → [0, 1] that **minimizes** the objective:
max_k ∫ h(x)(1 - h(x+k)) dx
This minimal value provides a tight upper bound for the constant C5.
Current best known upper bound: C5 ≤ 0.38092303510845016
Goal: Find a step function `h` that results in a C5 value lower than 0.38092303510845016.
CONSTRAINTS:
1. The function `h` must have values in the range [0, 1].
2. The integral of h(x) over [0, 2] must be exactly 1.
PERFORMANCE METRICS:
- c5_bound: The bound found by the program.
- combined_score: 0.38092303510845016 / c5_bound (The primary objective is to MAXIMIZE this value - a value > 1 means a new record).
- n_points: number of points used in the discretization.
- eval_time: evaluation time of the program.
num_top_programs: 3
num_diverse_programs: 2

# Logging
log_level: "INFO"
76 changes: 76 additions & 0 deletions examples/alphaevolve_math_problems/erdos_min_overlap/evaluator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# ===--------------------------------------------------------------------------------------===#
#
# This file implements the evaluator for the erdos minimum overlap problem.
#
# ===--------------------------------------------------------------------------------------===#
#
# Some of the code in this file is adapted from:
#
# google-deepmind/alphaevolve_results:
# Licensed under the Apache License v2.0.
#
# ===--------------------------------------------------------------------------------------===#

import sys
import os
from importlib import __import__
import time
import numpy as np

# Known bounds
BENCHMARK = 0.38092303510845016


def verify_c5_solution(h_values: np.ndarray, c5_achieved: float, n_points: int):
"""Verifies the C5 upper bound solution."""

if h_values.shape != (n_points,):
raise ValueError(f"Expected h shape ({n_points},), got {h_values.shape}")

# Verify h(x) in [0, 1] constraint
if np.any(h_values < 0) or np.any(h_values > 1):
raise ValueError(f"h(x) is not in [0, 1]. Range: [{h_values.min()}, {h_values.max()}]")

# Verify integral of h = 1 constraint
dx = 2.0 / n_points
integral_h = np.sum(h_values) * dx
if not np.isclose(integral_h, 1.0, atol=1e-3):
raise ValueError(f"Integral of h is not close to 1. Got: {integral_h:.6f}")

# Re-calculate the C5 bound using np.correlate
j_values = 1.0 - h_values
correlation = np.correlate(h_values, j_values, mode="full") * dx
computed_c5 = np.max(correlation)

# Check for consistency
if not np.isclose(computed_c5, c5_achieved, atol=1e-4):
raise ValueError(f"C5 mismatch: reported {c5_achieved:.6f}, computed {computed_c5:.6f}")


def evaluate(program_path: str):
try:
abs_program_path = os.path.abspath(program_path)
program_dir = os.path.dirname(abs_program_path)
module_name = os.path.splitext(os.path.basename(program_path))[0]

try:
sys.path.insert(0, program_dir)
program = __import__(module_name)
start_time = time.time()
h_values, c5_bound, n_points = program.run()
end_time = time.time()
eval_time = end_time - start_time
finally:
if program_dir in sys.path:
sys.path.remove(program_dir)

verify_c5_solution(h_values, c5_bound, n_points)

return {
"c5_bound": float(c5_bound),
"combined_score": BENCHMARK / float(c5_bound),
"n_points": int(n_points),
"eval_time": float(eval_time),
}
except Exception as e:
return {"combined_score": 0.0, "error": str(e)}
Loading