Tell a search that gave up from a route that is not there
The route search stops after MAX_VISITED stars and returned null, which everything downstream read as "the catalogue holds no chain". On the real catalogue that was wrong for real questions: Sol to HD 120147 (136 pc) at 5 pc is 50 jumps, and the panel said there was no route. The budget also sat under what the shipped catalogue needs, so it is now 40 000 rather than 20 000: both that route and a star at 170 pc are found, and Sol to HD 2626 at 6 pc, which used to be refused after 4.7 s, plots 56 jumps in about 2 s. A search now reports whether it gave up. The range search no longer counts a give-up as proof that nothing routes below it — that is what reported ranges up to 29% too wide — and it stops after two of them, since those are the probes that cost the most and settle the least: for HD 2626 at 3 pc it offers 5.92 pc in about 4 s, against 6.13 pc in 4.7 s. At the panel's widest range the refused route and the range search are the same question, so it is asked once. Where nothing can be said, the panel says "Too many stars to search at this range." rather than claiming there is no route. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016jxMkwA2rbicdGxHosecYi
This commit is contained in:
@@ -26,7 +26,11 @@ export type RoutingRequest =
|
||||
| { readonly kind: 'links'; readonly requestId: number; readonly rangePc: number; readonly drawn: Uint32Array; readonly budget?: LinkBudget };
|
||||
|
||||
export type RoutingResponse =
|
||||
| { readonly kind: 'route'; readonly requestId: number; readonly route: Route | null; readonly neededRangePc: number | null }
|
||||
/**
|
||||
* `gaveUp` is true when the searches spent their budget rather than looking everywhere: there
|
||||
* being no route and no range to offer is then what was found, not what exists.
|
||||
*/
|
||||
| { readonly kind: 'route'; readonly requestId: number; readonly route: Route | null; readonly neededRangePc: number | null; readonly gaveUp: boolean }
|
||||
| { readonly kind: 'links'; readonly requestId: number; readonly segments: Float32Array }
|
||||
/** The question threw in the worker. Sent back so the request settles instead of waiting for good. */
|
||||
| { readonly kind: 'failed'; readonly requestId: number; readonly message: string };
|
||||
@@ -37,8 +41,9 @@ export function indexCatalogue({ ids, positions }: RoutingCatalogue): StarNeighb
|
||||
}
|
||||
|
||||
/**
|
||||
* Answers one request. A route that cannot be made comes back with the range that would make
|
||||
* one, searched no wider than `ceilingPc`, so a refusal is always also an offer.
|
||||
* Answers one request. A route that cannot be made comes back with the range that would make one,
|
||||
* searched no wider than `ceilingPc`, so a refusal is usually also an offer — unless the searches
|
||||
* gave up, which is reported rather than passed off as "there is no route".
|
||||
*/
|
||||
export function answerRouting(index: StarNeighbourhood, request: RoutingRequest): RoutingResponse {
|
||||
if (request.kind === 'links') {
|
||||
@@ -47,11 +52,12 @@ export function answerRouting(index: StarNeighbourhood, request: RoutingRequest)
|
||||
const drawn = new StarNeighbourhood(Array.from(request.drawn, (at) => index.pointAt(at)), request.rangePc);
|
||||
return { kind: 'links', requestId: request.requestId, segments: jumpLinkSegments(drawn, request.rangePc, request.budget) };
|
||||
}
|
||||
const route = routeBetween(index, request.fromId, request.toId, request.rangePc);
|
||||
return {
|
||||
kind: 'route',
|
||||
requestId: request.requestId,
|
||||
route,
|
||||
neededRangePc: route ? null : minimumRangeBetween(index, request.fromId, request.toId, request.ceilingPc)
|
||||
};
|
||||
const { route, gaveUp } = routeBetween(index, request.fromId, request.toId, request.rangePc);
|
||||
// At the ceiling the question has just been asked: the range search would repeat it, identically
|
||||
// and at the same cost, before bisecting below it.
|
||||
if (route || request.rangePc >= request.ceilingPc) {
|
||||
return { kind: 'route', requestId: request.requestId, route, neededRangePc: null, gaveUp: !route && gaveUp };
|
||||
}
|
||||
const needed = minimumRangeBetween(index, request.fromId, request.toId, request.ceilingPc);
|
||||
return { kind: 'route', requestId: request.requestId, route: null, neededRangePc: needed.rangePc, gaveUp: gaveUp || !needed.least };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user