Something went wrong. Try again.
A functional toolkit for authoring resource-leveling algorithms — compose constraint and scoring blocks, enumerate feasible schedules
Something went wrong. Try again.
1.9 kB · 47 lines
TypeScript
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748// KBest — Collector block.//// Keeps the best `k` schedules out of a candidate stream, ranked// lexicographically over the referenced scorer instances: the second scorer// only breaks ties on the first, and so on (order matters). Unlike a// Scorer, which ranks a single schedule, a Collector selects a *set* — the// run consumption path (`LevelingRun.collectors()`) executes it.//// The `by` entries are scorer instanceIds from the same pipeline, not Scorer// closures: they resolve to compiled scorers only at run-wiring time (as// `objective.lexicographic` does), so the emitted spec stays plain JSON.//// Collectors are a selection layer above the solver, so `toMiniZinc` emits// an explanatory comment rather than a constraint fragment.
import { z } from "zod";
import type { KBestCollector } from "../level-core/types.ts";
import type { CollectorBlock, MiniZincFragment } from "./types.ts";
export const KBestInputSchema = z.object({ k: z.number().int().positive(), /** Scorer instanceIds in tie-break priority order; at least one. */ by: z.array(z.string()).min(1),});
export type KBestInput = z.infer<typeof KBestInputSchema>;
const KBestOutputSchema: z.ZodType<KBestCollector> = z.object({ kind: z.literal("KBest"), k: z.number().int().positive(), by: z.array(z.string()).min(1),});
export const KBestBlock: CollectorBlock<KBestInput> = { id: "KBest", schema: { input: KBestInputSchema, output: KBestOutputSchema }, apply: ({ k, by }): KBestCollector => ({ kind: "KBest", k, by }), toMiniZinc: ({ k }): MiniZincFragment => ({ text: `% KBest(k=${String(k)}) — selection layer; keeps the best k schedules, emits no solver constraint.`, }), doc: { nl: "Keeps the best k schedules, ranked lexicographically over the referenced scorers (order matters).", pseudocode: "sort(candidates, lex(by)).slice(0, k)", },};