读见

通过进化式 LLM 程序搜索提升 25 平方打包上界

原题Improving 25 square packing upper bounds through evolutionary LLM program search

约 5 分钟约 1,005 字原文英文

推荐理由本文介绍了成功的优化方形打包演化搜索,其中一个 LLM 反复修正基准程序,从而打破了在不同数量单位正方形下最小包围正方形大小的诸多记录。

读前速览

3 个要点

本文介绍了成功的优化方形打包演化搜索,其中一个 LLM 反复修正基准程序,从而打破了在不同数量单位正方形下最小包围正方形大小的诸多记录。

  1. 搜索从一个简单的基准程序开始,该程序随机放置正方形并使用 L-BFGS 收缩它们至不重叠。

    这种初始设置提供了演化过程的起点,让算法探索方形打包的参数空间。

  2. 整个实验共打破了 25 条记录。

    搜索的成功通过新发现的最低值数量来衡量,表明相对于之前已知的最佳解决方案有显著改进。

  3. 随着进度的推进,策略从单纯打磨已有打包转变为根本改变正方形的初始排列方式,从而获得更好的全局极小值。

    程序的进化从添加优化算法转变为优化初始化模式。

完整摘要

作者描述了一项为期两天的计算实验,利用演化算法和大型语言模型解决方形打包问题。从一个随机放置和收缩正方形的基准程序出发,系统历经 128 代变异和选择。搜索成功打破了 25 条记录,包括 1979 年的古老记录,通过演化更高效的初始化模式和打包优化策略实现。

目录 · 3 节
Oct 09, 2026
1
Share

What is the smallest square that encloses n unit squares?

For some values of n, the answer is clear. 16 squares pack into a 4x4.

In contrast, here is the beautiful, recently proven to be optimal, answer for n=11.

s = 3.87708

Records for different values of n were historically maintained by Erich Friedman, and more recently by David Ellsworth. Driven by a flurry of recent excitement around square packing, records are now also nicely maintained by Joshua Levy.

How did we break these records?

TL;DR: We achieve these results through LLM-driven evolutionary program search, similar to AlphaEvolve. The programs were seeded with primitives vibe-coded by yours truly, and the search was lightly guided between meetings and insufficient sleep.

Motivating program search

Following recent state-of-the-art approaches to solving open problems, I began by asking claude to break a record and then let it crunch away for an hour to no success.

Seared into my brain from years of ML is to always look at the data. Looking at some of the resulting packings, it became apparent that the style of search was inefficient, often landing in uninteresting minima. To build some intuition, I vibe-coded a web app and decided to try for the records myself.

Over the course of many hours and many packed squares, I requested various features that I thought may help the algorithm to break out of degenerate solutions, such as:

  • being able to round the corners of the squares

  • a control for shaking intensity

  • “wind” - restricting the shaking direction

  • “fade” - shaking less as the box shrinks

This packing lab is memorialized here.

While packing, I often found myself repeating certain actions that consistently led to interesting packings (e.g. rounding the squares, then letting them sharpen over and over again). Eventually it occurred to me that I was simply executing a program on top of these vibe-coded toggles, and that an LLM could search through the space of programs to rediscover mine, and hopefully many better.

The initial evolutionary search was implemented and within an hour, the record for n=51 had been broken on my little MacBook Air without a fan. Soon after, n=103 and n=105 had also fallen.

The next morning, as I ran around sharing my packings with the office, I was kindly gifted a bit more compute by the boss and encouraged to take the day to scale up the approach.

The run

The run began with a seeded baseline program. This program places n squares at random in a box, then slowly shrinks the box. Whenever squares overlap, an optimizer (L-BFGS) finds a local arrangement where they no longer overlap. When this converges, we have a packing! Alongside this code was a set of unused functions developed for the packing lab for future programs to use.

Every generation, we tasked a fleet of claude haiku agents with generating mutations of the previous generation’s best programs. Best is decided by a fitness score—the distance from the best known packing for a fixed sample of n values.

We ran this evolutionary loop for 128 generations.

In the end, a total of 25 records were broken over the course of 2 days, using 7.5k CPU-hours and $125 of tokens. The oldest record broken had stood for 47 years.

The run

Although the records were broken in one continuous evolutionary search, a few modifications were made throughout:

  1. Scaling up from 16 candidates per generation to 64

  2. Sampling instructions from a set of roles for candidate generation, since the diversity of evolved programs appeared low

    1. default: try to improve the program

    2. crossover: merge two candidates

    3. invent: create and use a new primitive

    4. moonshot: make a high risk high reward change

  3. Starting to include n values > 200

  4. Increasing max runtime 10s → 60s, as I noticed that large n were timing out

  5. Upweighting unbeaten n in the fitness score

In many cases, we broke our own records multiple times!

The evolved programs

In the first half of the search, evolved programs kept the initial random search and squeeze engine, opting to add increasingly strong and diverse packing-refining algorithms on top of standard basin hopping.

Once the fitness score was modified to include larger values of n, programs began to initialize squares in more structured patterns, nicely matching what real world approaches might look like.

high level program descriptions for select record breakers

Much of the fun in working with RL or evolutionary algorithms is seeing what novel behaviors are discovered. Here we list a few:

  • Initially rounding the squares, then sharpening them as the box shrinks

  • Writing the trivial grid immediately, so that an incomplete packing is not penalized—some light reward hacking

  • Tricks during polishing

    • Moving a square into the most empty spot—some programs choose random squares, others choose edge squares

    • Swapping the angles or positions of two squares.

  • Better initialization

    • Initializing squares at nice angles such as atan(1/2), atan(1/3), atan(2/3)

    • Initializing with structures such as staircases or diagonal columns

  • Fixing squares during squeeze

    • For large n, fixing staircases and optimizing only the rest

    • Squares that cause overlaps during perturbations are jittered less, leading to edges stabilizing fast

In general, we see that the evolution agents had a tendency to add code and complexity. We see an explosion of program diversity around generation 20 after expanding the set of evolution prompts.

Around ten years ago I spent an embarrassing number of hours trying to pack n=17 on paper. While I’m unsure what the future of human involvement in math looks like, I’m content knowing that this push began with an insight from a human in a coffee shop while packing squares in squares.

I’d like to thank Mamacoffee Vodičkova, all the square packers out there, and Equilibre Technologies for the time and a slice of the company cluster.

more to come :)

Subscribe
n = 295, the oldest record broken, set in 1979 by Frits Göbel
n = 86, set in 1997 by the shape packer himself, Erich Friedman
n=126 - just funny
1
Share

值得记下

该运行以一个有种子的基准程序开始。该程序在一个盒子中随机放置 n 个正方形,然后慢慢缩小盒子。每当正方形重叠时,一个优化器(L-BFGS)就会找到一个它们不再重叠的局部排列。
最终,在 2 天内,使用 7.5k CPU 小时和 125 美元的代币,共打破了 25 条记录。最古老的被打破的记录已经保持了 47 年。
在搜索的前半程,演化的程序保留了最初的随机搜索和挤压引擎,选择在标准盆地跳跃之上添加越来越强、越来越多样化的打包优化算法。