33 lines
1.9 KiB
TypeScript
33 lines
1.9 KiB
TypeScript
import assert from "node:assert/strict";
|
|
import { readFileSync, writeFileSync } from "node:fs";
|
|
import { forwardMixtures, forwardMergedRange, toImprovement } from "../../src/rules/index.ts";
|
|
import { readRun, type J } from "./py.ts";
|
|
|
|
// 只读复核选批记录的合并分位数;不调用模型或启动研究。
|
|
// node eval/route/verify-ranges.ts <blind-map.json> <输出json>
|
|
const [mapPath, output] = process.argv.slice(2);
|
|
if (mapPath === undefined || output === undefined) throw new Error("需要运行映射和输出路径");
|
|
const runs = Object.keys(JSON.parse(readFileSync(mapPath, "utf8")));
|
|
const results = runs.map((run) => {
|
|
const rows = readRun(run);
|
|
const batch = rows.find(([kind, c]) => kind === "decision" && c.decision === "batch")?.[1];
|
|
if (batch === undefined) return { run, status: "无第1轮" };
|
|
const predictions = rows.filter(([kind, c]) => kind === "submission" && c.kind === "secondPrediction").map(([, c]) => c);
|
|
const candidates = batch.output.candidates.map((c: J) => ({
|
|
id: c.id,
|
|
ranges: predictions.filter((p) => p.target === c.id).map((p) => ({ researcher: p.author, range: p.content.range })),
|
|
}));
|
|
// 读取选批输入里的基线,不由预测反推。
|
|
const base = batch.input.baseline;
|
|
assert.equal(typeof base, "number", "选批输入应保存基线分");
|
|
const mixtures = forwardMixtures(candidates, batch.output.params.lambda);
|
|
const checked = candidates.map((c: J, i: number) => {
|
|
const computed = forwardMergedRange(toImprovement(mixtures[i]!, base, "maximize"), base, "maximize");
|
|
const recorded = batch.output.candidates[i].merged;
|
|
assert.deepEqual(computed, recorded);
|
|
return { id: c.id, ranges: c.ranges, recorded, computed, equal: true };
|
|
});
|
|
return { run, baseline: base, lambda: batch.output.params.lambda, candidates: checked };
|
|
});
|
|
writeFileSync(output, JSON.stringify(results, null, 2));
|