OO第三单元总结 JML

OO第三单元总结 JML

JML语言的理论基础、应用工具链情况

JML是一种形式化的,面向JAVA的行为接口规格语言,它结合了Eiffel的契约方法和Larch方法,以及细化演算的一些元素,有着坚实的理论基础。

JML最主要的语法有前置条件,后置条件,不变式,通过这些语法对输入和输出进行约束,也就是达成了一种契约。当模块实现后,只要输入输出满足这些约束表达式就满足了规格的要求。JML主要使用java的语法,除此之外还有自己的一些语法,比如/forall,/exist等等,来实现对输入输出的约束。

JML拥有自己的一套工具链,其中最有用的是断言检查编译器jmlc,单元测试工具jmlunit以及jmldoc。另一种OpenJML可以通过命令行工具进行jml语法检查,可以说OpenJML是JML工具链的核心。

部署JMLUnitNG

在下载openjml和jmlunitng之后,编译时发生以下错误,在多次尝试后无果

生成测试文件后文件结构如下

通过阅读他人博客,我发现jmlunitng还是有一定局限性的,它生成的测试用例多是边界数据,而且不能很好的符合requires的要求。

三次作业架构设计与BUG分析

第一次作业


架构

第一次作业比较简单,其中最困难的部分在于如何建立Path和PathId的双向映射,我才用了两个TreeMap,一个是TreeMap<Path, Integer>, 另一个是TreeMap<Integer, Path>,用空间复杂度减少时间复杂度。

在Distinct_Node_Count,我在每次addPath时就将此值计算好,调用时直接返回即可。

Bug分析

本次作业比较简单,我自己在强测和互测中都没有bug,也没能找出别人的bug。

第二次作业

架构

(由于作业提交的代码有点惨……这里使用bug修复后的作业)

这次修复后我将node和edge都提炼成了新的类,也就弃用了上次的代码。距离图也从HashMap<Integer, HashMap<Integer, Integer>>变为了HashMap<Edge, Integer>,不仅时简洁了很多,而且也简化了自己写代码时候的思维。图采用了邻接表的方式储存。

本次作业理论上应该继承上次的PathContainer,但是我的改动比较大,也就整体重写。由于图的结构变更指令比较少,我采用的策略是:每次图结构变更指令后重新构建图,然后将图当作静态图来处理。对于时间复杂度最高的最短路径,我采用了dijkstra算法,并在完成计算后记录“该点为起点的最短路径都已经计算”,将结果缓存下来,加快了计算。

Bug分析

本次作业在强侧部分出现了大面积TLE,而且不仅仅是最短路径搜索算法的问题。据我分析原因主要有两点:

  1. 最短路径搜索问题

    求最短路径有三种方法,bfs、Floyd算法和Dijkstra算法。其中Floyd算法时间复杂度为o(n^3),运行一次就可以求出整张图上任意两点之间的最短路径,Dijkstra算法时间复杂度低,运行一次可以求出出发点到剩下所有点的最短路径。这两种算法的选择就在于图结构更改的次数。如果图结构更改很少而有大量的查询最短路径的指令,那么floyd算法会更有优势。但是如果图结构更改相对频繁,则Dijkstra算法更快。在本次作业的情形下还是使用Dijkstra算法更能符合题目的要求。

  2. 查询问题

    在本次作业种包含了大量的查询指令,我在一开始完成作业时不知道remove指令,只会将值设为null,导致查询种出现了很多无谓的循环,我应该在此浪费了很多的时间。这也提醒我要对java语法多加了解,善于运用java种自带的数据结构。

寻找别人bug时我没有针对性查找,只是将自己的测试数据提交了上去。

第三次作业

架构分析

本次作业完成的很差……由于bug一直没有修复好,为了正确性我出现了大量的重复代码。

本次作业一共有四个问题,而不满意度,最少换乘和票价问题其实是同一个问题,只需要设置不同的边的权值。另一个图的联通块问题我采用了并查集,每次图结构变更之后重新计算。

不满意度,最少换乘和票价需要包含三个新的图,这三个图因为换乘的问题与第二次作业中的最短距离问题出现了一些不同。我采用的方法是将经过多个Path的Node拆分,但也在这里出现了新的问题。这一部分将在bug分析里具体描述。

bug分析

本次作业最主要的问题还是TLE,由于星期日才知道上次作业的bug,并且发现第二次作业的bug不是修修补补就可以修改的,要整体性重写……于是第三次作业跟着一起炸了。除了第二次作业的问题外,我还想说一个拆点的问题:在我提交的作业中,一个Node如果在x个Path上,那么将它拆成x个不同的点。那么查询以它为起点的最短路径的时候,应该用哪个点作为起点呢?我原来的做法是将x个点都作为起点遍历一遍,执行了x次Dijkstra,显然时间复杂度爆炸了。评论区里有一个很好的方法:对每个Node拆成2+x个点,多出来的两个点一个作为起点,一个作为终点,每个地铁站的终点到起点连边的边权为y。每个站台往它所在的终点连边的边权为0,每个地铁站的起点往它的每个站台连边的边权为0。

规格撰写和理解上的心得体会

在学习了一个月的规格后,我印象最深刻的就是老师告诉我们“思维的转变”。写规格就像是写说明书,只需要告诉别人这个黑箱是怎么用的。比如一个求解最短路径的模块,我们由一看到最短路径就想到“迪杰斯特拉”“弗洛伊德”转变为思考我们这个模块要接受什么样的数据进来,要输出什么样的结果出去。这种契约设计的思想,我觉得是将任务的进一步划分。之前自己写代码就将设计和实现混在一起,写的时候先都写上去,发现有哪种方法用的比较多再将他提取出来。而现在则是提前做好完整的规划,然后再将模块一个一个实现。这样子在实现一个模块的时候觉得轻松了很多,不用考虑或者说已经事先考虑好了它给整体带来的影响,只需要实现就好了。在最后测试的时候也方便了许多,验证我的每一块“积木”都是正确的,哪块“积木”坏了就从哪里找问题。整个过程都变得更加井然有序。

原文地址:https://www.cnblogs.com/quarkstar/p/10908262.html

时间: 2024-08-06 02:01:55

OO第三单元总结 JML的相关文章

2019年北航OO第三单元(JML规格任务)总结

一.JML简介 1.1 JML与契约式设计 说起JML,就不得不提到契约式设计(Design by Contract).这种设计模式的始祖是1986年的Eiffel语言.它是一种限定了软件中每个元素所必需的责任与义务的开发模式,程序设计中的每个元素都需要用规范的语言精准地限定其前置条件(Preconditions).后置条件(Postconditions)和不变式(Invariants).通过这三项限定,我们可以清晰地获得对一个函数功能的刻画,从而达成设计与实现的分离,便于优化.测试和生成文档.

规格化设计——OO第三单元总结

规格化设计--OO第三单元总结 一.JML语言理论基础.应用工具链 1.1 JML语言 ? JML(java modeling language)是一种描述代码行为的语言,包括前置条件.副作用等等.JML是一种行为接口规格语言 (Behavior Interface Speci?cation Language,BISL),基于Larch方法构建. ? 通过使用JML,我们可以忽略一个类.一个方法内部的具体实现,专注于描述方法的预期功能,从而把过程性的思考延迟到方法设计中,扩展了面向对象设计的原则

OO第三单元总结(规格设计)

OO第三单元总结 一.关于JML Java Modeling Language,即JML是一种规格化表示语言,主要用于对Java程序的各种方法功能的规范描述.这样做既可以给程序设计人员明确清晰的功能要求,又可以充分全面地验证已有的代码实现保证其满足规格描述的要求. 1.语法梳理 JML的语法清晰直观地描述了一个Java的各种特征.它的语法主要由以下三个部分组成. (1)表达式: 诸如 \result \old等有具体确定意义的固定关键词称为表达式.通过不同的搭配组合可以表示不同的含义,比如(\f

OO第三单元总结--根据JML写代码

一. JML语言 1. 理论基础 首先,JML不是JAVA的一部分,它是一群研究者为JAVA设计的扩展部分,但还没有得到官方的支持.因此,JAVA编译器并不支持JML,所以要想JML起作用,只能采用类似openJML这样的第三方来编译,将JML 规格编译为运行时检查的语句,即RAC code(runtime assertion checking).如果代码实现与其JML规格不一致,将引发运行时JML exception. JML遵从契约式设计范式(DBC),Design by contract是

OO第三单元总结

JML语言理论基础 Java建模语言(Java Modeling Language,JML)是一种进行详细设计的符号语言,他鼓励你用一种全新的方式来看待Java的类和方法.JML是一种行为接口规格语言 (Behavior Interface Speci?cation Language,BISL),基于Larch方法构建.BISL提供了对方法和类型的规格定义手段.所谓接口即一个方法或类型外部可见的内容.通过在Java代码中增加了一些符号,这些符号用来标识一个方法是干什么的,却并不关心它的实现.使用

OO第三单元总结-规格化设计

OO规格化编程体验小结 1. JML语言的理论基础.应用工具链情况 JML 理论基础: JML建立契约式编程的基础上,是一种实现契约式编程的规格化语言.顾名思义,契约式编程,是供求双方建立在一定的契约上进行软件的开发和应用.类似于在共同完成这一个工程的时候我们对于每个方法都以一个供求双方都统一并且详细知晓的合同,在这个合同上,供应方要不多不少完成合同上的所有要求,需求方的可提出的需求范围只限于合同上的明确条文.这样同时明确了双方的权利和义务.而产生契约式编程的背景是很多工程的开发过程权责混乱,导

面向对象第三单元(JML)总结体会

一.JML语言 定义 Java建模语言(JML)是一种行为接口规范语言,可用于指定Java模块的行为 .它结合了Eiffel的契约方法设计 和Larch 系列接口规范语言的基于模型的规范方法 . 理论基础 JML是契约式语言的一种具体表现形式. 契约(Contact):声明一个函数/方法的时候,对函数的输入和输出所具备的性质是有所期望和规定的.有时候这种性质会被我们明确的写出来,有时候会被我们忽略掉.这些期望和规定就是Contract. 而契约设计的核心便是断言(assertion) :永远为真

OO第三单元单元总结

目录 JML知识梳理 部署JMLUnitNG/JMLUnit 按照作业梳理自己的架构设计,并特别分析迭代中对架构的重构 按照作业分析代码实现的bug和修复情况 阐述对规格撰写和理解上的心得体会 JML知识梳理 JML理论基础 关于JML的相关介绍其实课程给出的指导书就已经足够使用了,由于指导书上都有相关知识的梳理,所以这里不花费大量篇幅去书写这部分内容,只是简单提及一些东西.首先是什么是JML,课程进行,其实阅读简单的JML已经没有多大障碍了,但是对于JML的定义这种概念已经忘记的差不多了.JM

OO第三单元总结——java建模语言

一.JML语言的理论基础 面向对象分析和设计的原则之一就是应当尽可能地把过程设想往后推.我们大多数人只在实现方法之前遵守这一规则.一旦确定了类及其接口并该开始实现方法时,我们就转向了过程设想. Java 建模语言(JML)将注释添加到 Java 代码中,这样我们就可以确定方法所执行的内容,而不必说明它们如何做到这一点.有了 JML,我们就可以描述方法预期的功能,无需考虑实现.通过这种方法,JML 将延迟过程设想的面向对象原则扩展到了方法设计阶段. 二.JML应用工具链 openJML可以检查规格