feat: 不可达区域惩罚 & 合并数据集

This commit is contained in:
unanmed 2025-03-22 18:17:30 +08:00
parent 3eb80d79c7
commit 11378380b4
5 changed files with 34 additions and 8 deletions

View File

@ -6,6 +6,7 @@
"scripts": {
"ginka": "tsx ./src/ginka.ts",
"minamo": "tsx ./src/minamo.ts",
"merge": "tsx ./src/merge.ts",
"test:topo": "tsx ./src/topology/test.ts",
"test:vision": "tsx ./src/vision/test.ts"
},

15
data/src/merge.ts Normal file
View File

@ -0,0 +1,15 @@
import { readFile, writeFile } from 'fs-extra';
import { DatasetMergable, mergeDataset } from './utils';
const [output, ...datasets] = process.argv.slice(2);
(async () => {
const data = await Promise.all(
datasets.map(async v => {
const file = await readFile(v, 'utf-8');
return JSON.parse(file) as DatasetMergable<any>;
})
);
const merged = mergeDataset(...data);
await writeFile(output, JSON.stringify(merged), 'utf-8');
})();

View File

@ -6,7 +6,6 @@ import { directions, tileType } from './topology/graph';
import { calculateVisualSimilarity } from './vision/similarity';
import { BaseConfig } from './types';
import { Presets, SingleBar } from 'cli-progress';
import { log } from 'console';
interface MinamoConfig extends BaseConfig {}
@ -25,9 +24,16 @@ interface MinamoDataset {
const [output, ...list] = process.argv.slice(2);
// 判断 assigned 模式,此模式下只会对前两个塔处理,会在这两个塔之间对比,而单个塔的地图不会对比
const assigned = list.at(-1) === 'assigned';
const assigned = list.at(-1)?.startsWith('assigned');
const assignedCount = parseAssigned(list.at(-1)!);
if (assigned) list.pop();
function parseAssigned(arg: string): [number, number] {
const p = arg.slice(9);
const [a, b] = p.split(':');
return [parseInt(a) || 100, parseInt(b) || 100];
}
function chooseFrom<T>(arr: T[], n: number): T[] {
const copy = arr.slice();
for (let i = copy.length - 1; i > 0; i--) {
@ -323,12 +329,13 @@ function parseAllData(data: Map<string, FloorData>): MinamoDataset {
function generateAssignedData(
data1: Map<string, FloorData>,
data2: Map<string, FloorData>
data2: Map<string, FloorData>,
count: [number, number]
): MinamoDataset {
const length = data1.size + data2.size;
const totalCount = data1.size * data2.size;
const count1 = Math.min(100, data1.size);
const count2 = Math.min(100, data2.size);
const count1 = Math.min(count[0], data1.size);
const count2 = Math.min(count[1], data2.size);
const keys1 = [...data1.keys()];
const keys2 = [...data2.keys()];
const choose1 = chooseFrom(keys1, count1);
@ -388,7 +395,7 @@ function generateAssignedData(
}
const data1 = await readOne(tower1);
const data2 = await readOne(tower2);
const results = generateAssignedData(data1, data2);
const results = generateAssignedData(data1, data2, assignedCount);
await writeFile(output, JSON.stringify(results, void 0), 'utf-8');
const size = Object.keys(results.data).length;
console.log(`✅ 已处理 ${list.length} 个塔,共 ${size} 个组合`);

View File

@ -166,6 +166,9 @@ export function overallSimilarity(
if (maxGraph) comparedGraph.add(maxGraph);
});
// 不可达区域惩罚
const reduction =
1 / (1 + Math.abs(a.unreachable.size - b.unreachable.size));
// 取根号使结果更接近线性
return Math.sqrt(totalSimilarity / graphsA.length);
return Math.sqrt(totalSimilarity / graphsA.length) * reduction;
}

View File

@ -3,7 +3,7 @@ import { join } from 'path';
import { BaseConfig, TowerInfo } from './types';
import { convertApeiriaMap, convertFloor } from './floor';
interface DatasetMergable<T> {
export interface DatasetMergable<T> {
datasetId: number;
data: Record<string, T>;
}