如何一次性计算并持久存储Floyd-Warshall相关矩阵及Map数据供服务端使用
解决方案
完全可以通过JSON实现持久化存储,你的所有数据结构都可以无损序列化和重建,整套实现非常简单,分三步即可完成:
第一步:编写一次性预计算脚本,输出JSON文件
你可以单独写一个Node.js脚本执行Floyd-Warshall计算,完成后把所有变量转换成可序列化的普通结构写入JSON文件,代码示例如下:
const fs = require('fs'); // 引入你自己的Floyd-Warshall计算逻辑、ArrayKeyedMap类 const { computeFloydWarshall, ArrayKeyedMap } = require('./你的业务代码文件'); // 执行计算拿到结果 const [path, cost, tupleVal, index, ForbiddenVals] = computeFloydWarshall(你的地图参数); // 转换为可序列化的普通对象 const serializeData = { // 二维数组直接支持序列化 path, cost, // ArrayKeyedMap直接转成普通对象,键已经是序列化后的元组字符串 tupleVal: Object.fromEntries(tupleVal.entries()), index: Object.fromEntries(index.entries()), ForbiddenVals: Object.fromEntries(ForbiddenVals.entries()), // 可选:存当前地图的哈希值/唯一标识,后续可以自动检测地图是否变更 mapHash: '你当前地图的唯一标识' }; // 写入JSON文件 fs.writeFileSync('./floyd-precompute.json', JSON.stringify(serializeData, null, 2)); console.log('预计算结果已存储');
你只需要在地图变更的时候手动执行一次这个脚本就行,不需要每次启动服务都跑计算逻辑。
第二步:服务端启动时读取JSON并重建原始数据结构
服务端启动的时候直接读预存的JSON文件,把普通结构转回你需要的类实例即可:
const fs = require('fs'); const { ArrayKeyedMap } = require('./你的业务代码文件'); // 读取预计算文件 const rawData = JSON.parse(fs.readFileSync('./floyd-precompute.json', 'utf8')); // 重建原始数据结构 const path = rawData.path; const cost = rawData.cost; // 重建ArrayKeyedMap const tupleVal = new ArrayKeyedMap(); Object.entries(rawData.tupleVal).forEach(([strKey, val]) => { // 把字符串键转回元组,用你自定义的set方法存入 tupleVal.set(JSON.parse(strKey), val); }); const ForbiddenVals = new ArrayKeyedMap(); Object.entries(rawData.ForbiddenVals).forEach(([strKey, val]) => { ForbiddenVals.set(JSON.parse(strKey), val); }); // 重建index Map const index = new Map(); Object.entries(rawData.index).forEach(([numKey, tuple]) => { index.set(Number(numKey), tuple); }); // 接下来直接用这些变量即可,不需要再执行Floyd-Warshall计算
第三步(可选):自动检测地图变更触发重计算
如果你不想手动执行预计算脚本,可以在服务端启动时先比对当前地图的哈希值和预存JSON里的mapHash,如果不一致就自动执行一次Floyd-Warshall计算,再更新JSON文件即可,完全不用人工干预。
多地图场景适配:如果你的地图数量不多,也可以给每个地图单独生成一个预计算JSON文件,用地图ID作为文件名,启动时根据当前加载的地图读取对应的文件即可。
内容的提问来源于stack exchange,提问作者Steveit
相关产品推荐
相关产品推荐

