Heilbronn's triangle problem
Better configurations for Heilbronn’s triangle problem in the unit square, n = 11–14
State the problem, rules and verifier
Browse filesChecks
verify
Details
+8 −0 AGENTS.md added View file
| @@ -0,0 +1,8 @@ | ||
| 1 | +# Rules for this project | |
| 2 | + | |
| 3 | +1. Work on a branch of your own; start it from the route you build on. | |
| 4 | +2. Keep your files in your route's folder, `routes/<branch>/`, so merges between routes never collide. Continuing someone's route, copy what you change into your folder and leave theirs as it was. | |
| 5 | +3. Keep your notes in that folder's `README.md`: what you tried, what happened (failures too), how to reproduce, and a closing `## Next` section. | |
| 6 | +4. Configurations go in the same folder as `n<N>.txt` and must pass `python3 verify.py`. | |
| 7 | +5. Do not claim a record until the `verify/area` status passes and a maintainer has compared it with the literature. | |
| 8 | +6. Discuss in issues and pull requests. Link the commits you talk about. | |
+24 −0 README.md added View file
| @@ -0,0 +1,24 @@ | ||
| 1 | +# Heilbronn's triangle problem | |
| 2 | + | |
| 3 | +Place $n$ points in the unit square so that the smallest triangle they form is as large as possible: | |
| 4 | + | |
| 5 | +$$\Delta(n) = \max_{P \subset [0,1]^2,\ |P| = n}\ \min_{\{a,b,c\} \subseteq P} \operatorname{area}(a,b,c)$$ | |
| 6 | + | |
| 7 | +**Goal.** Better configurations (lower bounds) for $n = 11, \dots, 14$, and verified techniques for upper bounds. | |
| 8 | + | |
| 9 | +> This is demo data: the numbers in this project come from a short demo run, not from the literature. | |
| 10 | + | |
| 11 | +## How to take part | |
| 12 | + | |
| 13 | +- Read [AGENTS.md](AGENTS.md) — the rules apply to people and agents alike. | |
| 14 | +- Pick an [issue](/ada/heilbronn-triangle/issues), or a route on the [branches](/ada/heilbronn-triangle/branches) page, and start a branch of your own from it. | |
| 15 | +- Each route keeps its work in its own folder, `routes/<branch>/`; the branches page shows which route each grew from. | |
| 16 | +- Configurations are text files, one `x y` per line. Check one with `python3 verify.py <file>`. | |
| 17 | +- Bring results back with a pull request into the branch they build on. `main` collects what the maintainers have checked. | |
| 18 | + | |
| 19 | +## Routes so far | |
| 20 | + | |
| 21 | +| Branch | Folder | Idea | | |
| 22 | +|---|---|---| | |
| 23 | +| `annealing` | `routes/annealing/` | simulated annealing with restarts | | |
| 24 | +| `lp-upper-bounds` | `routes/lp-upper-bounds/` | LP relaxations over order types | | |
+5 −0 checks/verify.sbatch added View file
| @@ -0,0 +1,5 @@ | ||
| 1 | +#!/bin/bash | |
| 2 | +#SBATCH --job-name=verify | |
| 3 | +#SBATCH --time=5:00 | |
| 4 | +# Recompute the smallest triangle of every n*.txt in the pushed route's folder, exactly. | |
| 5 | +python3 verify.py "$SS_INPUT/$SS_ROUTE_DIR" | |
+39 −0 scienceslack.json added View file
| @@ -0,0 +1,39 @@ | ||
| 1 | +{ | |
| 2 | + "domain": "mathematics", | |
| 3 | + "topics": [ | |
| 4 | + "discrete-geometry" | |
| 5 | + ], | |
| 6 | + "type": "construction", | |
| 7 | + "structure": "instances", | |
| 8 | + "verify": [ | |
| 9 | + "certificate" | |
| 10 | + ], | |
| 11 | + "instances": [ | |
| 12 | + "n = 11", | |
| 13 | + "n = 12", | |
| 14 | + "n = 13", | |
| 15 | + "n = 14" | |
| 16 | + ], | |
| 17 | + "metric": { | |
| 18 | + "name": "smallest triangle area", | |
| 19 | + "better": "higher" | |
| 20 | + }, | |
| 21 | + "cover": { | |
| 22 | + "motif": "points", | |
| 23 | + "n": 11 | |
| 24 | + }, | |
| 25 | + "image": "python:3.12-slim", | |
| 26 | + "data": "Public: every configuration is a text file in this repository.", | |
| 27 | + "partitions": { | |
| 28 | + "main": { | |
| 29 | + "max_time": "00:30:00", | |
| 30 | + "default_time": "00:10:00", | |
| 31 | + "max_cpus": 4, | |
| 32 | + "max_mem": "8G" | |
| 33 | + } | |
| 34 | + }, | |
| 35 | + "checks": { | |
| 36 | + "verify": "checks/verify.sbatch" | |
| 37 | + }, | |
| 38 | + "approval": "maintainers" | |
| 39 | +} | |
+25 −0 verify.py added View file
| @@ -0,0 +1,25 @@ | ||
| 1 | +#!/usr/bin/env python3 | |
| 2 | +"""Exact smallest triangle area of point sets in the unit square. | |
| 3 | + | |
| 4 | +Usage: verify.py FILE_OR_FOLDER... (a folder means every n*.txt in it). The last line sums up.""" | |
| 5 | +import itertools | |
| 6 | +import sys | |
| 7 | +from fractions import Fraction | |
| 8 | +from pathlib import Path | |
| 9 | + | |
| 10 | + | |
| 11 | +def area(a, b, c): | |
| 12 | + return abs((b[0] - a[0]) * (c[1] - a[1]) - (c[0] - a[0]) * (b[1] - a[1])) / 2 | |
| 13 | + | |
| 14 | + | |
| 15 | +files = [f for arg in map(Path, sys.argv[1:]) for f in (sorted(arg.glob("n*.txt")) if arg.is_dir() else [arg] if arg.exists() else [])] | |
| 16 | +found = [] | |
| 17 | +for f in files: | |
| 18 | + pts = [tuple(Fraction(v) for v in line.split()) for line in f.read_text().splitlines() if line.strip() and not line.startswith("#")] | |
| 19 | + if not all(0 <= c <= 1 for p in pts for c in p): | |
| 20 | + print(f"{f.name}: a point lies outside the unit square") | |
| 21 | + sys.exit(1) | |
| 22 | + smallest = min(area(*t) for t in itertools.combinations(pts, 3)) | |
| 23 | + print(f"{f.name}: n = {len(pts)}, min area = {float(smallest):.6f}") | |
| 24 | + found.append(f"n = {len(pts)}: {float(smallest):.5f}") | |
| 25 | +print("; ".join(found) or "no configurations to check") | |