标签:更新 需要 直接 它的 interface 伪代码 完成 graph return
在JML官网上,是这样定义JML的。
Java建模语言(JML)是一种行为接口规范语言,可用于指定Java模块的行为 。它结合了Eiffel的契约方法设计 和Larch系列接口规范语言的基于模型的规范方法 ,以及细化演算一些元素 。
https://blog.csdn.net/piaopu0120/article/details/89527175
链接为我根据预习资料和第一次上课内容进行的JML语法整理,内容较多,仍放在另一个博客里。
没有做太多架构上的设计,仅完成了目标函数的补充。在细节方面的小优化是用hashset进行去重保存节点;用hashmap实现id和Path的双重查找。
依然没有做架构上的设计,新的图没有选择继承之前图,导致MyGraph很冗杂。主要实现了对于每一个Path的每一个小邻边的访存;修改了add和remove,完善功能;为求最短路,进行了floyd的初始化和实现。
第三次作业因为有四个相似的图,所以进行了架构上的优化。
虽然之前有考虑过指导书推荐的组合模式+工厂模式的架构,但当时主观觉得组合模式的树形结构不太好运用到这次的题(实际上是我建模的主体不对)。所以考虑了建造者模式。
使用多个简单的对象一步一步构建成一个复杂的对象。
主要解决在软件系统中,有时候面临着"一个复杂对象"的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。
用大白话讲就是生成一个套餐。
我生成了一个floyd套餐builder和一个dij套餐builder,这两个builder可以生成各种各样的套餐。
分析:
①把问题分成由floyd算法求解更优和dijkstra算法求解更优的两类
②把floyd和dijkstra的初始化与实现拆分成小块。
③将小块进行重新组合,实现builder。
顶层组合实现举例:
1 public Dij lessTransfer() { 2 if (transDij == null) { 3 transDij = new Dij(); 4 transDij.addStratege(new InitLessTransfer()); 5 transDij.addStratege(new NoneTransfer()); 6 } 7 return transDij; 8 } 9 10 public Dij lessCost() { 11 if (costDij == null) { 12 costDij = new Dij(); 13 costDij.addStratege(new InitLessMoney()); 14 costDij.addStratege(new Transfer2()); 15 } 16 return costDij; 17 } 18 19 public Dij lessUnplefation() { 20 if (unpleDij == null) { 21 unpleDij = new Dij(); 22 unpleDij.addStratege(new InitUnstatisfication()); 23 unpleDij.addStratege(new Transfer32()); 24 } 25 return unpleDij; 26 }
调用builder实例:
1 if (unpleFlag) { 2 // 省略初始化代码 3 // 如果没有缓存,调用builder1 4 unpleDij = DijBuilder.getBuilder().lessUnplefation(); 5 } else { 6 if (alreadyUnple.contains(fromNodeId)) { 7 // 省略结果返回代码 8 } 9 // 如果有缓存,调用builder2 10 unpleDij = DijBuilder.getBuilder().noneunpleDij(); 11 } 12 // 省略更新缓存代码 13 // 启动builder,得到结果 14 unpleDij.runDij(fromNodeId, unpleGraph, unpleExist, distict, 15 unpleNodeSort, buddy, pidMap, pathInformation); 16 }
下面是builder的具体实现:
以不满意度为例
DijBuilder
1 public class DijBuilder { 2 private Dij unpleDij = null; 3 private Dij noneunpleDij = null; 4 5 private static DijBuilder builder = new DijBuilder(); 6 7 private DijBuilder() { 8 } 9 10 public static DijBuilder getBuilder() { 11 return builder; 12 } 13 14 public Dij lessUnplefation() { 15 if (unpleDij == null) { 16 unpleDij = new Dij(); 17 unpleDij.addStratege(new InitUnstatisfication()); 18 unpleDij.addStratege(new Transfer32()); 19 } 20 return unpleDij; 21 } 22 23 public Dij noneunpleDij() { 24 if (noneunpleDij == null) { 25 noneunpleDij = new Dij(); 26 noneunpleDij.addStratege(new NoneInit()); 27 noneunpleDij.addStratege(new Transfer32()); 28 } 29 return noneunpleDij; 30 } 31 32 }
Dij
public class Dij { private List<Strategy> strategies = new ArrayList<>(); public void addStratege(Strategy s) { strategies.add(s); } public void runDij(int v0, int[][] distanceGraph, boolean[][] exist, HashSet<Integer> distict, HashMap<Integer, Integer> nodeSort, HashMap<String, Integer> buddy, HashMap<Path, Integer> pidMap, PathMap[] pathInformation) { Strategy initMethod = strategies.get(0); initMethod.process(0, distanceGraph, exist, distict, nodeSort, buddy, pidMap, pathInformation); Strategy calMethod = strategies.get(1); calMethod.process(nodeSort.get(v0), distanceGraph, exist, distict, nodeSort, buddy, pidMap, pathInformation); } }
Strategy接口
1 public interface Strategy { 2 void process(int v0, int[][] distanceGraph, boolean[][] exist, 3 HashSet<Integer> distict, 4 HashMap<Integer, Integer> nodeSort, 5 HashMap<String, Integer> buddy, 6 HashMap<Path, Integer> pidMap, PathMap[] pathInformation); 7 }
GenerateWay抽象类实现Strategy接口,Initial抽象类类似
1 public abstract class GenerateWay implements Strategy { 2 3 public abstract void process(int v0, int[][] distanceGraph, 4 boolean[][] exist, 5 HashSet<Integer> distict, 6 HashMap<Integer, Integer> nodeSort, 7 HashMap<String, Integer> buddy, 8 HashMap<Path, Integer> pidMap, 9 PathMap[] pathInformation); 10 }
Transfer32类继承抽象类GenerateWay
1 public class Transfer32 extends GenerateWay { 2 3 public void process(int v0, int[][] distanceGraph, boolean[][] exist, 4 HashSet<Integer> distict, 5 HashMap<Integer, Integer> nodeSort, 6 HashMap<String, Integer> buddy, 7 HashMap<Path, Integer> pidMap, 8 PathMap[] pathInformation) { 9 StaticFun.dij(v0, distict.size(), 32, distanceGraph, exist); 10 } 11 }
这样的方法使得在顶层实现不同的floyd或者dij的算法非常容易,可以实现n*m种任意的组合,并且不需要改动任何的底层代码。
但在实现的过程中也会遇到一些困难:
1. 统一接口导致传参过多;
2. 没有办法在顶层进一步封装,使得顶层代码重复变多。
第九次作业被检测出来了一个bug,compareTO用了一种错误的方法,当时为了少些几行所以是通过差值判断的。这直接导致了溢出时判断错误。修复的时候把它修改成了大小比较。
在判断最短路的时候忘记了两个相同点的情况,修复的时候把这个条件加上了。
感谢莫策同学的数据生成器,经过很多数据的互拍让bug数减到最小。
这些bug很不值得,他、它们都是很基础很容易用测试用例覆盖的问题。但这两次作业我都没怎么用心测试程序,导致了这两个bug的出现。第十一次作业我汲取了之前的教训,进行了大量的测试使得最后一次作业在强测互测都没有发现bug。以后一定谨记,在每一次测试之前优先考虑边界问题和特殊数据。
标签:更新 需要 直接 它的 interface 伪代码 完成 graph return
原文地址:https://www.cnblogs.com/puublog/p/10886026.html