AnyLogic参数变异并行评估结果混乱及多变量绘图咨询
问题1:并行评估下结果混乱的解决方案
核心原因
AnyLogic并行评估采用多线程执行不同迭代/重复,getCurrentIteration()在多线程环境下无法保证线程安全,会出现上下文混淆,导致迭代号与参数值不匹配,最终引发数据混叠。
修复步骤与代码修改
1. 调整存储结构
放弃以迭代号为键的TreeMap<Integer, ArrayList<Result>>,改用当前变异参数值(单参数场景)或参数组合(多参数场景)作为键,同时使用线程安全的集合避免并发冲突。
示例:将c_dataMap改为线程安全的ConcurrentHashMap,键为单参数p_manHeightPickPercentage的数值:
// 定义全局变量 ConcurrentHashMap<Double, CopyOnWriteArrayList<Result>> c_dataMap = new ConcurrentHashMap<>();
2. 移除迭代号初始化代码
无需提前按迭代号创建列表,改为在仿真运行时动态生成:
// 原初始化代码可删除
3. 修改仿真运行后的数据存储逻辑
直接用当前参数值作为键绑定结果,不再依赖getCurrentIteration():
Result r = new Result(); r.pickDur=root.v_pickingDuration; r.waitTime=root.v_totalWaitingTime; r.perLine= root.v_pickingDuration/root.v_totalNumLines; r.numLines=root.v_totalNumLines; r.percen= p_manHeightPickPercentage; r.mDist= p_minDist; // 用参数值作为键,动态创建线程安全的结果列表 double paramKey = r.percen; c_dataMap.putIfAbsent(paramKey, new CopyOnWriteArrayList<Result>()); c_dataMap.get(paramKey).add(r); traceln("after run: param=" + paramKey + " rep: " + getCurrentReplication()); traceln("percentage: " + r.percen);
4. 修改迭代后的数据聚合逻辑
遍历整个参数-结果映射,直接按参数值计算均值:
// 遍历所有参数对应的结果列表,计算均值 for (Map.Entry<Double, CopyOnWriteArrayList<Result>> entry : c_dataMap.entrySet()) { double param = entry.getKey(); CopyOnWriteArrayList<Result> res = entry.getValue(); double tpickDur=0; double twait=0; double tperLine=0; int lines=0; for(Result r: res){ tpickDur+=r.pickDur; twait+=r.waitTime; tperLine+=r.perLine; lines+=r.numLines; traceln("r: res percen=" + r.percen); } dataset.add(param, tpickDur/res.size()); dataset1.add(param, twait/res.size()); dataset2.add(param, tperLine/res.size()); dataset3.add(param, (double)lines/res.size()); }
问题2:多参数变异时的图表绘制方法
当同时变异2个及以上参数时,可根据需求选择以下图表类型:
1. 分组折线图
- 适用场景:展示一个参数与结果的关系,按另一个参数的取值分组
- 实现方式:
- 用参数组合(如
(paramA, paramB))作为键存储结果 - 聚合时,固定
paramB的某一取值,将paramA与对应结果均值添加到单独数据集 - 在折线图中添加多个数据集,每个数据集对应
paramB的一个取值,形成分组折线
- 用参数组合(如
2. 热力图
- 适用场景:直观展示两个参数组合与结果的数值分布
- 实现方式:
- 使用AnyLogic的
Heatmap组件 - 聚合后将
paramA作为X轴、paramB作为Y轴、结果均值作为颜色值,添加到热力图数据集:heatmapDataset.add(paramA, paramB, averageWaitTime);
- 使用AnyLogic的
3. 3D曲面/散点图
- 适用场景:展示三个维度(两个参数+一个结果)的空间关系
- 实现方式:
- 使用AnyLogic的
3D Surface Chart或3D Scatter Chart组件 - 将
paramA作为X轴、paramB作为Y轴、结果均值作为Z轴,添加到3D数据集
- 使用AnyLogic的
参数组合存储示例
若同时变异p_manHeightPickPercentage(double)和p_minDist(int),可创建参数组合类作为键:
class ParamCombination { double pickPercent; int minDist; public ParamCombination(double pickPercent, int minDist) { this.pickPercent = pickPercent; this.minDist = minDist; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; ParamCombination that = (ParamCombination) o; return Double.compare(that.pickPercent, pickPercent) == 0 && minDist == that.minDist; } @Override public int hashCode() { return Objects.hash(pickPercent, minDist); } } // 定义全局存储Map ConcurrentHashMap<ParamCombination, CopyOnWriteArrayList<Result>> c_dataMap = new ConcurrentHashMap<>();
内容的提问来源于stack exchange,提问作者XanderW
相关产品推荐
相关产品推荐

