Files

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));