mirror of
https://github.com/unanmed/ginka-generator.git
synced 2026-05-24 05:01:41 +08:00
feat: 不可达区域惩罚 & 合并数据集
This commit is contained in:
parent
3eb80d79c7
commit
11378380b4
@ -6,6 +6,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"ginka": "tsx ./src/ginka.ts",
|
"ginka": "tsx ./src/ginka.ts",
|
||||||
"minamo": "tsx ./src/minamo.ts",
|
"minamo": "tsx ./src/minamo.ts",
|
||||||
|
"merge": "tsx ./src/merge.ts",
|
||||||
"test:topo": "tsx ./src/topology/test.ts",
|
"test:topo": "tsx ./src/topology/test.ts",
|
||||||
"test:vision": "tsx ./src/vision/test.ts"
|
"test:vision": "tsx ./src/vision/test.ts"
|
||||||
},
|
},
|
||||||
|
|||||||
15
data/src/merge.ts
Normal file
15
data/src/merge.ts
Normal 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');
|
||||||
|
})();
|
||||||
@ -6,7 +6,6 @@ import { directions, tileType } from './topology/graph';
|
|||||||
import { calculateVisualSimilarity } from './vision/similarity';
|
import { calculateVisualSimilarity } from './vision/similarity';
|
||||||
import { BaseConfig } from './types';
|
import { BaseConfig } from './types';
|
||||||
import { Presets, SingleBar } from 'cli-progress';
|
import { Presets, SingleBar } from 'cli-progress';
|
||||||
import { log } from 'console';
|
|
||||||
|
|
||||||
interface MinamoConfig extends BaseConfig {}
|
interface MinamoConfig extends BaseConfig {}
|
||||||
|
|
||||||
@ -25,9 +24,16 @@ interface MinamoDataset {
|
|||||||
|
|
||||||
const [output, ...list] = process.argv.slice(2);
|
const [output, ...list] = process.argv.slice(2);
|
||||||
// 判断 assigned 模式,此模式下只会对前两个塔处理,会在这两个塔之间对比,而单个塔的地图不会对比
|
// 判断 assigned 模式,此模式下只会对前两个塔处理,会在这两个塔之间对比,而单个塔的地图不会对比
|
||||||
const assigned = list.at(-1) === 'assigned';
|
const assigned = list.at(-1)?.startsWith('assigned');
|
||||||
|
const assignedCount = parseAssigned(list.at(-1)!);
|
||||||
if (assigned) list.pop();
|
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[] {
|
function chooseFrom<T>(arr: T[], n: number): T[] {
|
||||||
const copy = arr.slice();
|
const copy = arr.slice();
|
||||||
for (let i = copy.length - 1; i > 0; i--) {
|
for (let i = copy.length - 1; i > 0; i--) {
|
||||||
@ -323,12 +329,13 @@ function parseAllData(data: Map<string, FloorData>): MinamoDataset {
|
|||||||
|
|
||||||
function generateAssignedData(
|
function generateAssignedData(
|
||||||
data1: Map<string, FloorData>,
|
data1: Map<string, FloorData>,
|
||||||
data2: Map<string, FloorData>
|
data2: Map<string, FloorData>,
|
||||||
|
count: [number, number]
|
||||||
): MinamoDataset {
|
): MinamoDataset {
|
||||||
const length = data1.size + data2.size;
|
const length = data1.size + data2.size;
|
||||||
const totalCount = data1.size * data2.size;
|
const totalCount = data1.size * data2.size;
|
||||||
const count1 = Math.min(100, data1.size);
|
const count1 = Math.min(count[0], data1.size);
|
||||||
const count2 = Math.min(100, data2.size);
|
const count2 = Math.min(count[1], data2.size);
|
||||||
const keys1 = [...data1.keys()];
|
const keys1 = [...data1.keys()];
|
||||||
const keys2 = [...data2.keys()];
|
const keys2 = [...data2.keys()];
|
||||||
const choose1 = chooseFrom(keys1, count1);
|
const choose1 = chooseFrom(keys1, count1);
|
||||||
@ -388,7 +395,7 @@ function generateAssignedData(
|
|||||||
}
|
}
|
||||||
const data1 = await readOne(tower1);
|
const data1 = await readOne(tower1);
|
||||||
const data2 = await readOne(tower2);
|
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');
|
await writeFile(output, JSON.stringify(results, void 0), 'utf-8');
|
||||||
const size = Object.keys(results.data).length;
|
const size = Object.keys(results.data).length;
|
||||||
console.log(`✅ 已处理 ${list.length} 个塔,共 ${size} 个组合`);
|
console.log(`✅ 已处理 ${list.length} 个塔,共 ${size} 个组合`);
|
||||||
|
|||||||
@ -166,6 +166,9 @@ export function overallSimilarity(
|
|||||||
if (maxGraph) comparedGraph.add(maxGraph);
|
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;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import { join } from 'path';
|
|||||||
import { BaseConfig, TowerInfo } from './types';
|
import { BaseConfig, TowerInfo } from './types';
|
||||||
import { convertApeiriaMap, convertFloor } from './floor';
|
import { convertApeiriaMap, convertFloor } from './floor';
|
||||||
|
|
||||||
interface DatasetMergable<T> {
|
export interface DatasetMergable<T> {
|
||||||
datasetId: number;
|
datasetId: number;
|
||||||
data: Record<string, T>;
|
data: Record<string, T>;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user