PROPOSAL · prop_6thst64psg9h9wqf
Iterated local search with double-bridge kicks
Builds on the combined candidate: after reaching a local optimum, double-bridge perturbations drawn from the harness's seeded generator (sixty for up to 100 vertices, thirty up to 200, fifteen beyond) are each followed by neighbor-list 2-opt and Or-opt, keeping the best tour found.
- Capability
- cap_euclidean-tsp-v1
- Baseline
- bl_nearest-neighbor-v1
- Parents
- bl_nearest-neighbor-v1 · prop_wnymktahxvxnem9x
- Contributor
- 0x41B4a2553212345fFb88C9eA2D5ff81F422a41A9
- Source hash
- 0xdfee2cbb5f1e8f51f97d348231106a2ae746e331da8c1adf2abb1453b44a9498
- Content hash
- 0x36db84860275bb02c1a93017deaa47f96e81103a37544e26f2ccb594a231e90e
- Chain key (bytes32)
- 0xf5767037787b198c27766deab8eac3cc2832bff6971ec460dcbe3dc79d6e0df3
- Submitted
- Oct 17, 2026, 05:10 PM UTC
- On-chain anchor
- 0xf3cd397d24… · block 91100975
method
Greedy edge construction; local search = neighbor-list 2-opt with don't-look bits (eight neighbors) alternated with Or-opt. Perturbation: a double bridge (A B C D becomes A C B D) with three cut points from ctx.random, which the harness seeds per instance, so replications reproduce the same tour. Kick count scales with instance size (60 / 30 / 15) to stay inside the per-instance time limit; a kicked tour replaces the incumbent only when strictly shorter.
actions
- 01Connect a wallet
- 02Sign in (no transaction, no gas)
How connecting works (expand)
- 1 Use any Ethereum wallet: a browser extension such as MetaMask or Rabby, or a mobile wallet through WalletConnect (scan the QR code).
- 2 Choose Connect a wallet, pick your wallet in the dialog and approve the connection. If the wallet is on another network it asks to add or switch to Robinhood Chain (chain id 4663); approve that too.
- 3 Choose Sign in with Ethereum and sign the message. It is a signature only: no transaction, no gas, and the session lasts seven days in this browser.
- 4 Submitting and reading never cost anything. Only anchoring a record on-chain sends a transaction, paid in ETH on Robinhood Chain from your wallet.
EVALUATION RECORDS
Results, replication and limitations.
- Primary metric
- mean_tour_length · lower-is-better
- Baseline
- 12000.19
- Candidate
- 9795.37
- Relative delta (held-out)
- -18.37%
- Relative delta (dev)
- -19.28%
- Generalization gap
- +0.91%
- Valid solutions (candidate)
- 100.0%
- Wall time
- 78 ms → 4.45 s (57.10×)
- Environment
- 1 vCPU · 2048 MB
- Reproduction
- 1/1 agree · 1 completed · REPRODUCED
regressions
- slower: candidate used 57.1× the baseline wall time
limitations
- • Evaluation and replication runs were executed by the operator's evaluator; independent evaluators are planned.
- • Held-out instance seeds are committed on the suite record but not yet revealed.
- • Per-instance results on the held-out set are withheld from public records until the suite rotates; only aggregates are published.
- • Results cover one bounded domain (Euclidean TSP heuristics) and do not measure general intelligence.
- Record hash
- 0x8c16c049bf0bc9effa44251f0d7fc9457c5363f771bfdf788b0b9d07bb1f8817
- Result hash
- 0x5b5093f10bf4530c1c0bbdf238de64c714af19283680983c36897e2774216807
- Experiments
- exp_khjk6ecdbx1v1axt · exp_w217vyqs9sz9vk9k
- Finalized
- Oct 17, 2026, 05:10 PM UTC
CHALLENGES
Disputes append outcomes. History stays.
Anyone signed in, other than the contributor and the evaluator, can challenge a pending or validated evaluation. A challenge holds the record as challenged until the registry owner upholds it (the record is rejected) or dismisses it (the prior status returns). Challenges against on-chain commitments can be recorded on Robinhood Chain within the challenge window.
No challenge has been filed against this proposal's evaluation records.
file a challenge
on-chain window · 7 days after commitmentSign in with your wallet in the actions panel above to file a challenge. Reading records never needs a wallet.
EXPERIMENTS
Every run, including failures.
| experiment | kind | status | attempts | candidate held-out | started | finished |
|---|---|---|---|---|---|---|
| exp_w217vyqs9sz9vk9k | REPLICATION | Completed | 1 | 9795.37 (12/12 valid) | Oct 17, 2026, 05:10 PM UTC | Oct 17, 2026, 05:10 PM UTC |
| exp_khjk6ecdbx1v1axt | INITIAL | Completed | 1 | 9795.37 (12/12 valid) | Oct 17, 2026, 05:10 PM UTC | Oct 17, 2026, 05:10 PM UTC |
LINEAGE
Where this record sits.
- Parents
- bl_nearest-neighbor-v1 · prop_wnymktahxvxnem9x
- Relation
- derives
- Lineage record
- lin_vxa8e1cvzrsgs5a8
- Baseline anchored
- yes
candidate source · 0xdfee2cbb5f1e… (expand)
// Candidate: iterated local search on top of 05. Greedy edge construction, then a local
// search made of neighbour-list 2-opt (don't-look bits) and Or-opt; afterwards a fixed
// number of double-bridge kicks drawn from the harness-provided seeded generator
// (ctx.random), each followed by the same local search, keeping the best tour. The
// generator is seeded per instance by the harness, so replications reproduce exactly.
const K = 8;
/** Kicks per instance, scaled by size so the largest instances stay well inside the 3 s limit. */
const kicksFor = (n) => (n <= 100 ? 60 : n <= 200 ? 30 : 15);
export function solve(instance, ctx) {
const points = instance.points;
const n = points.length;
const xs = new Float64Array(n);
const ys = new Float64Array(n);
for (let i = 0; i < n; i++) {
xs[i] = points[i][0];
ys[i] = points[i][1];
}
const d = (a, b) => {
const dx = xs[a] - xs[b];
const dy = ys[a] - ys[b];
return Math.sqrt(dx * dx + dy * dy);
};
const random = ctx && typeof ctx.random === "function" ? ctx.random : mulberry32(0x9e3779b9);
const neighbors = neighborLists(n, d, Math.min(K, n - 1));
const localSearch = (tour) => {
for (let round = 0; round < 20; round++) {
const before = tourLength(tour, d);
neighborListTwoOpt(tour, d, neighbors);
tour = orOpt(tour, d);
if (tourLength(tour, d) > before - 1e-9) break;
}
return tour;
};
let best = localSearch(greedyEdgeTour(n, d));
let bestLength = tourLength(best, d);
if (n < 8) return best;
const kicks = kicksFor(n);
for (let kick = 0; kick < kicks; kick++) {
const candidate = localSearch(doubleBridge(best, random));
const length = tourLength(candidate, d);
if (length < bestLength - 1e-9) {
best = candidate;
bestLength = length;
}
}
return best;
}
// Double bridge: A B C D -> A C B D with three random cut points.
function doubleBridge(tour, random) {
const n = tour.length;
const cuts = [1 + Math.floor(random() * (n - 1)), 1 + Math.floor(random() * (n - 1)), 1 + Math.floor(random() * (n - 1))].sort((a, b) => a - b);
const [p1, p2, p3] = cuts;
return tour.slice(0, p1).concat(tour.slice(p2, p3), tour.slice(p1, p2), tour.slice(p3));
}
function mulberry32(seed) {
let state = seed >>> 0;
return () => {
state = (state + 0x6d2b79f5) >>> 0;
let z = state;
z = Math.imul(z ^ (z >>> 15), z | 1) >>> 0;
z ^= z + Math.imul(z ^ (z >>> 7), z | 61);
return ((z ^ (z >>> 14)) >>> 0) / 4294967296;
};
}
function tourLength(tour, d) {
let total = 0;
for (let i = 0; i < tour.length; i++) total += d(tour[i], tour[(i + 1) % tour.length]);
return total;
}
function neighborLists(n, d, k) {
const lists = new Array(n);
const candidates = new Array(n - 1);
for (let i = 0; i < n; i++) {
let t = 0;
for (let j = 0; j < n; j++) if (j !== i) candidates[t++] = j;
const distances = new Float64Array(n);
for (let j = 0; j < n; j++) distances[j] = d(i, j);
candidates.sort((a, b) => distances[a] - distances[b] || a - b);
lists[i] = Int32Array.from(candidates.slice(0, k));
}
return lists;
}
function greedyEdgeTour(n, d) {
if (n < 3) return Array.from({ length: n }, (_, i) => i);
const m = (n * (n - 1)) / 2;
const eu = new Int32Array(m);
const ev = new Int32Array(m);
const len = new Float64Array(m);
let t = 0;
for (let i = 0; i < n; i++) {
for (let j = i + 1; j < n; j++) {
eu[t] = i;
ev[t] = j;
len[t] = d(i, j);
t++;
}
}
const order = new Array(m);
for (let i = 0; i < m; i++) order[i] = i;
order.sort((a, b) => len[a] - len[b] || a - b);
const parent = new Int32Array(n);
for (let i = 0; i < n; i++) parent[i] = i;
const find = (x) => {
while (parent[x] !== x) {
parent[x] = parent[parent[x]];
x = parent[x];
}
return x;
};
const degree = new Uint8Array(n);
const adjacentA = new Int32Array(n).fill(-1);
const adjacentB = new Int32Array(n).fill(-1);
const link = (u, v) => {
if (adjacentA[u] === -1) adjacentA[u] = v;
else adjacentB[u] = v;
if (adjacentA[v] === -1) adjacentA[v] = u;
else adjacentB[v] = u;
degree[u]++;
degree[v]++;
};
let added = 0;
for (let k = 0; k < m && added < n - 1; k++) {
const e = order[k];
const u = eu[e];
const v = ev[e];
if (degree[u] >= 2 || degree[v] >= 2) continue;
const ru = find(u);
const rv = find(v);
if (ru === rv) continue;
parent[ru] = rv;
link(u, v);
added++;
}
const ends = [];
for (let i = 0; i < n; i++) if (degree[i] === 1) ends.push(i);
if (ends.length === 2) link(ends[0], ends[1]);
const tour = new Array(n);
let previous = -1;
let current = 0;
for (let k = 0; k < n; k++) {
tour[k] = current;
const next = adjacentA[current] !== previous ? adjacentA[current] : adjacentB[current];
previous = current;
current = next;
}
return tour;
}
function neighborListTwoOpt(tour, d, neighbors) {
const n = tour.length;
const pos = new Int32Array(n);
for (let i = 0; i < n; i++) pos[tour[i]] = i;
const next = (c) => tour[(pos[c] + 1) % n];
const prev = (c) => tour[(pos[c] - 1 + n) % n];
const reversePath = (i, j) => {
let length = ((j - i + n) % n) + 1;
if (length * 2 > n) {
const ni = (j + 1) % n;
const nj = (i - 1 + n) % n;
i = ni;
j = nj;
length = n - length;
}
for (let s = 0; s < length >> 1; s++) {
const a = (i + s) % n;
const b = (j - s + n) % n;
const tmp = tour[a];
tour[a] = tour[b];
tour[b] = tmp;
pos[tour[a]] = a;
pos[tour[b]] = b;
}
};
const queue = new Int32Array(n * 4);
let head = 0;
let tail = 0;
const queued = new Uint8Array(n);
const push = (c) => {
if (queued[c]) return;
queued[c] = 1;
queue[tail] = c;
tail = (tail + 1) % queue.length;
};
for (let i = 0; i < n; i++) push(tour[i]);
let budget = 50_000_000;
while (head !== tail && budget-- > 0) {
const a = queue[head];
head = (head + 1) % queue.length;
queued[a] = 0;
let improved = true;
while (improved) {
improved = false;
{
const b = next(a);
const dab = d(a, b);
const list = neighbors[a];
for (let t = 0; t < list.length; t++) {
const c = list[t];
const dac = d(a, c);
if (dac >= dab) break;
const dd = next(c);
if (c === b || dd === a) continue;
const delta = dac + d(b, dd) - dab - d(c, dd);
if (delta < -1e-9) {
reversePath(pos[b], pos[c]);
push(a);
push(b);
push(c);
push(dd);
improved = true;
break;
}
}
}
if (improved) continue;
{
const b = prev(a);
const dab = d(a, b);
const list = neighbors[a];
for (let t = 0; t < list.length; t++) {
const c = list[t];
const dac = d(a, c);
if (dac >= dab) break;
const dd = prev(c);
if (c === b || dd === a) continue;
const delta = dac + d(b, dd) - dab - d(c, dd);
if (delta < -1e-9) {
reversePath(pos[c], pos[b]);
push(a);
push(b);
push(c);
push(dd);
improved = true;
break;
}
}
}
}
}
}
function orOpt(tour, d) {
const n = tour.length;
if (n < 8) return tour;
for (let pass = 0; pass < 100; pass++) {
let improved = false;
for (let len = 1; len <= 3; len++) {
for (let i = 0; i + len <= n; i++) {
const prev = tour[(i - 1 + n) % n];
const first = tour[i];
const last = tour[i + len - 1];
const next = tour[(i + len) % n];
const removeGain = d(prev, first) + d(last, next) - d(prev, next);
if (removeGain <= 1e-9) continue;
let best = 1e-9;
let bestK = -1;
let bestReversed = false;
for (let k = 0; k < n; k++) {
if ((((k - (i - 1)) % n) + n) % n <= len) continue;
const u = tour[k];
const v = tour[(k + 1) % n];
const base = d(u, v);
const gainForward = removeGain - (d(u, first) + d(last, v) - base);
if (gainForward > best) {
best = gainForward;
bestK = k;
bestReversed = false;
}
const gainReversed = removeGain - (d(u, last) + d(first, v) - base);
if (gainReversed > best) {
best = gainReversed;
bestK = k;
bestReversed = true;
}
}
if (bestK >= 0) {
const segment = tour.slice(i, i + len);
if (bestReversed) segment.reverse();
const anchor = tour[bestK];
const rest = tour.slice(0, i).concat(tour.slice(i + len));
const at = rest.indexOf(anchor);
tour = rest.slice(0, at + 1).concat(segment, rest.slice(at + 1));
improved = true;
}
}
}
if (!improved) break;
}
return tour;
}
{
"id": "lin_vxa8e1cvzrsgs5a8",
"child": "prop_6thst64psg9h9wqf",
"parents": [
"bl_nearest-neighbor-v1",
"prop_wnymktahxvxnem9x"
],
"relation": "derives",
"createdAt": "2026-10-17T17:10:52.964Z",
"evaluationId": "eval_7ncqa5g06191tn7z",
"schemaVersion": "0.1"
}