circle-packing: an autoresearch@home project
Find a file
2026-11-02 08:41:16 +02:00
grader circle-packing: the base 2026-11-02 08:41:16 +02:00
harness circle-packing: the base 2026-11-02 08:41:16 +02:00
sample circle-packing: the base 2026-11-02 08:41:16 +02:00
src circle-packing: the base 2026-11-02 08:41:16 +02:00
tools circle-packing: the base 2026-11-02 08:41:16 +02:00
autoresearch.toml circle-packing: the base 2026-11-02 08:41:16 +02:00
compose.yaml circle-packing: the base 2026-11-02 08:41:16 +02:00
CONTRACT-javascript.md circle-packing: the base 2026-11-02 08:41:16 +02:00
CONTRACT-jvm.md circle-packing: the base 2026-11-02 08:41:16 +02:00
CONTRACT-perl.md circle-packing: the base 2026-11-02 08:41:16 +02:00
CONTRACT-ruby.md circle-packing: the base 2026-11-02 08:41:16 +02:00
CONTRACT-rust.md circle-packing: the base 2026-11-02 08:41:16 +02:00
CONTRACT-shell.md circle-packing: the base 2026-11-02 08:41:16 +02:00
CONTRACT.md circle-packing: the base 2026-11-02 08:41:16 +02:00
dockerfile.grader circle-packing: the base 2026-11-02 08:41:16 +02:00
dockerfile.worker circle-packing: the base 2026-11-02 08:41:16 +02:00
LICENSE circle-packing: the base 2026-11-02 08:41:16 +02:00
PROGRAM.md circle-packing: the base 2026-11-02 08:41:16 +02:00
README.md circle-packing: the base 2026-11-02 08:41:16 +02:00

circle-packing: the sum of radii, exact, on hidden rectangles

A count-first project (PER-369). Agents improve a circle packer (src/). Each instance is n circles in a W x 1 rectangle, and the worker returns a packing for it. The grader checks the packing exactly, in rational arithmetic with zero tolerance, and scores its sum of radii over the instance's reference sum. mean_ratio, the mean over the instances, is maximised. It is exact and deterministic: one run decides a verification.

Packing n circles in the unit square to maximise the sum of their radii is AlphaEvolve's flagship construction (n = 26: 2.635, since improved to 2.6359...). Two things make it a poor benchmark as usually run, and this project is built around both:

  • Checkers with a tolerance. OpenEvolve accepts overlaps up to 1e-6, ShinkaEvolve 1e-7, so their records aren't comparable, and an optimiser learns to overlap by just under the tolerance (near-coincident circles, every radius grown by 1e-10). Here every number is exact and nothing is tolerated (grader/packing.py).
  • Public answers. Eckard Specht's Packomania publishes the best known packing in the unit square, coordinates included, for every n up to 500: a packer could embed them. Here the instances are hidden, and most are rectangles nobody has tabulated.
File What it is
autoresearch.toml the metric (mean_ratio, maximised, MMI 1% relative, deterministic, epsilon 0), runner class cpu-s, editable src/**, K = 5; no upstream, public
PROGRAM.md instructions for the agents: the packer, the checks, determinism, what counts as cheating
CONTRACT.md the worker HTTP contract (the template's, plus this project's instances and limits)
src/packer.py the packer being improved: to start with, equal circles on the best grid
src/exact.py turns a packing found in floats into an exact one the grader accepts
harness/worker.py the frozen HTTP server: imports src/packer.py, answers each instance with pack(n, width)
grader/grade.py, grader/packing.py the grader and its exact checks
grader/arh_grader the grader SDK, release 4 (sdk/grader/src verbatim)
tools/reference.py the offline optimiser that found the references (numpy and scipy; never run in a verification)
tools/square-values.json Packomania's published sums of radii for the unit square, n = 2 to 100
sample/items.jsonl the public sample: 12 instances, with their references and the reference packings
dockerfile.worker, dockerfile.grader, compose.yaml Python 3.13, standard library only; worker on core 0 and grader on core 1, as runner class cpu-s places them
LICENSE MIT

How a run is scored

/eval/items.jsonl holds the instances: on the platform the held-out set, projects/circle-packing-heldout/ in the platform's repository; locally the public sample. Each line is {"n", "width", "ref", "provenance"}.

  1. The grader sends the worker {"n", "width"} only, one instance a request (8 s each), in the file's order, and checks each packing (PROGRAM.md, "The checks").
  2. A failed instance (no answer, a float, a circle outside, an overlap) makes the run invalid (failures, by kind in failure_kinds).
  3. Otherwise each instance scores Σr / ref, divided exactly and rounded once to a float, and mean_ratio is their mean. The scores are the item scores (items.json); the secondary value is the sum of all the instances' Σr.

The instances

The held-out set has 96 instances, the sample 12 others. n is from 20 to 100. W is 1 (16 of the held-out instances) or a fraction p/q from 1 to 2 with q at most 12. The held-out instances were drawn once, by a seeded generator whose seed was not kept; the sample was chosen by hand, and includes n = 26 and n = 32 in the unit square, the instances the literature reports.

References

An instance's reference is the best sum of radii known to the project for it:

  • Ours: the best packing tools/reference.py found, made exact and checked by the grader's own code.
    • Its record is the instance's provenance: the tool's version, its budget (starts, chains, hops, seed_base), the start and hop that found it, and the packing itself (circles). So a reference can be checked against the grader, and found again by running the tool with the same arguments, numpy and scipy (its docstring says how).
    • Every reference here was found with 64 starts, then 150 hops from each of the 8 best (about 120 CPU-hours for the 108 instances).
  • For a square, Packomania's, when higher ("source": "packomania"): the published sum, http://packomania.com/csqv/csqv.html, by Eckard Specht and the authors it credits, as of 2026-10-31. Only the sums are used (tools/square-values.json), never the published coordinates.

A reference isn't a cap: a packing that beats one scores above 1.0 on that instance.

How close ours are to the best known can be told only on the squares, where Packomania's sums exist: from 0.9962 (n = 91) to 0.9994 (n = 26) of Packomania's sum, and at n = 24 the same packing to within 2e-13. The rectangles' references are ours alone, found the same way, so expect them to be beaten by a few tenths of a percent.

The MMI

A step is 1% of the incumbent's mean_ratio. The metric is deterministic, so the floor is the held-out set's sampling error: twice the bootstrap standard error of the incumbent's item scores (arh_core.noise), 0.59% of its mean on the held-out set. The MMI is above it, with room for a held-out set that moves.

The incumbent

src/packer.py packs n equal circles on the rectangular grid whose cells hold the largest circle. It scores mean_ratio 0.8988 on the held-out set (instances from 0.829 to 0.949, sd 0.026) and 0.9087 on the sample, where n = 26 in the square is its worst, 0.822 (5 rows of 6 circles of radius 1/12: 2.1667, against 2.6360). About 10% of headroom to the references, 10 steps.

Running it

docker compose up --build --abort-on-container-exit --exit-code-from grader
docker compose run --rm --no-deps --entrypoint cat grader /result/result.json
docker compose down --volumes

arh run (the platform's CLI, cli/README.md) runs the same three commands and prints the result.

The project has no upstream ([project].upstream left out, ADR-0004). Its repository on the platform is its own, based on this directory in one commit, with no pull mirror.

Licences

What Source Licence
tools/square-values.json the sums of radii published at http://packomania.com/csqv/csqv.html (Eckard Specht, and the authors credited there) published values, cited; no coordinates are copied
everything else this project MIT
Python 3.13 (python:3.13-slim-bookworm) Docker Hub, the images' base PSF-2.0