OO第三单元作业(JML)总结

OO第三单元作业(JML)总结


一:梳理JML语言的理论基础,应用工具链情况

  对于JML(Java Modeling Language)是对java的一种建模语言,通过JML可以规定不同方法,不同类希望完成的动作与行为,对整个开发过程有着良好的监控行为。该建模语言在以注释的形式内嵌在代码中,它对代码对对象的修改、以及返回值、异常情况的抛出等等进行了限制,但对算法的实现层面确实放松的。

  JML能够约束整个代码结果,但是JML的限制先决条件是该JML的正确性,只有一个正确的JML,才能够引导正确的结果。并且JML这种对结果进行规定,而不规定过程的语言,更适合于形成测试,可以针对JML的描述,针对性的构造测试样例,对程序的正确性是有很大的好处的。

1. JML格式

  JML以注释的形式嵌入在代码中,具体的形式有:

// @ annotation
/* @ annotation
@ annotation
@ annotation */

2. JML表达式

2.1 原子表达式:

  • \result:表示一个非void类型的方法执行所获得的结果,即方法执行后的返回值
  • \old(expr):用来表示一个表达式expr在相应方法执行前的取值
  • \not_assigned(x, y, ...):用来表示括号中的变量是否在方法执行过程中被赋值。
  • \not_modified(x, y, ...):用来表示括号中的变量是否在方法执行过程中取值发生变化
  • \nonnullelement(container):表示容器中存储的对象不会包含有null
  • \type(type):用来表示类型type所对应的对象种类
  • \typeof(expr):用来表示表达式所对应的种类

2.2 量化表达式

  • \forall:全称量词修饰的表达式
  • \exits:存在量词修饰的表达式
  • \sum:给定范围内的表达式的和

2.3 集合表达式

2.4 操作符

  • E1<:E2:表示E1是E2的子类型,属于子类型关系操作符
  • expr1 <==> expr2, expr1 <=!=> expr2:表示两个布尔表达式是否相同,属于等价关系操作符
  • expr1 ==> expr2, expr1 <== expr2:表示两个布尔表达式的推理过程,属于推理操作符
  • \nothing, \everything等,这类是对变量的特殊引用,属于变量引用操作符

3. JML方法规格

  方法规格的核心内容包括三个方面,前置条件、后置条件和副作用约定。

  • 前置条件:requires:表示对输入方法的数据,需要满足的条件
  • 后置条件:ensures:表示对于实现方法的策略需要遵循的规则
  • 副作用:assignable | modifiable:表示在方法执行的过程中,会被修改的属性数据或者类的静态成员数据。

  而对于方法而言,若其不会产生任何的副作用,即不修改任意对象,仅仅是访问的形式,则称其为纯访问方法,在方法名中用 /* pure */表示。

4. JML类型规格

  JML类型规格是针对Java程序中的数据类型所设计的限制,常用不变式限制和约束限制。

  • 不变式约束:invariant:表示在所有的可见状态下都必须满足的特性,可见状态指:不修改成员变量方法之外的状态。
  • 状态变化约束:constraint:对于前序可见状态和当前可见状态的关系约束

5. JML 工具链

  JML由于其具有标准的格式,所以同样可以对其进行格式以及语法上的检查,有OpenJML完成对JML的静态检查。

  而JML这类语言,其很容易的可以用于构造测试样例,于是也诞生有相关的自动化测试,如JMLUnitNG/IMLunit


 

二:部署SMT Solver,选择至少三个主要方法来尝试进行验证


 

三:部署JMLUnitNG/JMLUnit,针对Graph接口实现自动生成测试用例,结合规格对生成的测试用例和数据进行简要的分析

  本部分采用的测试样例如下:

OO第三单元作业(JML)总结
package demo;

public class Demo {
    /*
     @ ensures \result == (num1 + num2);
     */
    public static int add(int num1, int num2) {
        return num1 + num2;
    }

    /*
     @ ensures \result == (num1 - num2);
     */
    public static int sub(int num1, int num2) {
        return num1 - num2;
    }

    /*
     @ ensures \result == (num1 / num2);
     */
    public static int div(int num1, int num2) {
        return num1 / num2;
    }

    public static void main(String[] args) {
        add(4546456, 353546);
        sub(1234567, 323598);
        div(331235, 0);
    }
}
View Code

 针对该进行自动生成测试用例,使用下述命令:

java -jar ..\..\openjml\jmlunitng.jar .\demo\Demo.java

生成得到众多测试文件,如

其中较为重要的一些文件解释如下:

  • MyGraph_JML_Test.java 为主要的测试类
  • MyGraph_InstanceStrategy.java 为生成实例的策略类
  • MyGraph_'function':这里为具体的测试方法

 对上述进行编译,并且进行运行测试,得到结果如下:

OO第三单元作业(JML)总结
[TestNG] Running:
  Command line suite

Failed: racEnabled()
Passed: constructor Demo()
Passed: static add(-2147483648, -2147483648)
Passed: static add(0, -2147483648)
Passed: static add(2147483647, -2147483648)
Passed: static add(-2147483648, 0)
Passed: static add(0, 0)
Passed: static add(2147483647, 0)
Passed: static add(-2147483648, 2147483647)
Passed: static add(0, 2147483647)
Passed: static add(2147483647, 2147483647)
Passed: static div(-2147483648, -2147483648)
Passed: static div(0, -2147483648)
Passed: static div(2147483647, -2147483648)
Failed: static div(-2147483648, 0)
Failed: static div(0, 0)
Failed: static div(2147483647, 0)
Passed: static div(-2147483648, 2147483647)
Passed: static div(0, 2147483647)
Passed: static div(2147483647, 2147483647)
Failed: static main(null)
Failed: static main({})
Passed: static sub(-2147483648, -2147483648)
Passed: static sub(0, -2147483648)
Passed: static sub(2147483647, -2147483648)
Passed: static sub(-2147483648, 0)
Passed: static sub(0, 0)
Passed: static sub(2147483647, 0)
Passed: static sub(-2147483648, 2147483647)
Passed: static sub(0, 2147483647)
Passed: static sub(2147483647, 2147483647)

===============================================
Command line suite
Total tests run: 31, Failures: 6, Skips: 0
===============================================


Process finished with exit code 0
View Code

   由于测试的过程中均采用的是int类型,其在测试时,采用大量的边缘数据进行测试,即大量使用0,最大正值以及最小负数等进行测试,以对边缘数据进行监控。

  而本次实验中产生了6项错误,其中基本为除零错误,但是可以发现,对于溢出的情况,这里并没有报错,表示这里的溢出根据JML的书写规则是合法的,若需要监控溢出,应该在JML中扩大数据范围,进行测试。

四:按照作业梳理自己的架构设计,并特别分析迭代中对架构的重构

 4.1 作业9

  作业9只需要根据规格实现相应的内容即可,难度较低,结构如下:

OO第三单元作业(JML)总结

在该实现中,采用双HashMap的结构,对Path和id分别进行索引,如下:

HashMap<MyPath, Id>
HashMap<Id, MyPath>

这样在检索过程中的效率较高。

  而针对不同点的检索,需要将复杂的搜索均摊到无法优化的指令中去,也就是说在加点的过程中,就可以开始统计不同点的个数,这样要不同点的个数的时候只需要直接取即可。

4.2 作业10

 OO第三单元作业(JML)总结

  在作业10中,新增的图的管理,对此,我新建了一个类名为Matrix用邻接矩阵来存储改图,并且在该类中进行是否邻接,是否可达,最短距离等计算,采用弗洛伊德算法进行计算最短距离。

最短距离:

  在每次加点的过程中,更新matrix图,并且同时计算最短距离。

是否存在边:

  这里需要维护一个边的集合,因为两个点之间是否存在边,不可以通过两点之间最短距离来判断,如点2 到 点2存在一个边,但是其最短距离为0,这样无法判断。

是否连通:

  这里仅仅需要根据最短距离来判断即可,若两个点之间的最短距离不为INF,则表示两点可达。

4.3 作业11

  在作业11中,对于图的分析更进一步了,需要对图建立其有层次的联系,我的框架图如下:

OO第三单元作业(JML)总结

  同作业10,我将复杂的计算全部放在了matrix中。而针对不同的路径的计算,同样都采用了弗洛伊德算法进行计算。

  首先,对于不同的Path在自己的Path中利用弗洛伊德算法,算出该条路径上两两之间的最短距离,最少消费等等,得到一个较低层次的结果。

  再在全局中,利用不同Path上的不同点,再进行更新最短距离,实现一个两级的最短距离的层次算法,这样的时间复杂度为n^3 * 50,是可以接受的,由于每个Path是不变的,仅需要在addPath的阶段计算即可,计算的开销较小。

如何计算不同的指标

  针对于不同的指标,实际上都是计算最小值的一个过程,仅在更新两个点之间的距离时产生不同,在更新时根据是否需要换乘等进行计算即可。

五:按照作业分析代码实现的bug和修复情况

5.1 作业9

  作业9中,是第一次接触这类作业,对时间开销没有认真的考虑,仅仅在结构上采用了可能会更加省时的结构,但是没有将需求进行拆解分摊,导致了TLE。

  针对作业9,也利用Python进行了相应的测试,测试代码如下,对正确性及时间都有所考察

OO第三单元作业(JML)总结
  1 import os
  2 import time
  3 import random
  4 
  5 instructions1 = [
  6     "PATH_ADD",  # 节点序列
  7     "PATH_REMOVE",  # 节点序列
  8     "PATH_REMOVE_BY_ID",  # id
  9     "PATH_GET_ID",  # 节点序列
 10     "PATH_GET_BY_ID",  # id
 11     "CONTAINS_PATH",  # 节点序列
 12     "CONTAINS_PATH_ID"  # id
 13 ]
 14 instructions2 = [
 15     "PATH_COUNT",  # 空
 16     "PATH_SIZE",  # id
 17     "PATH_DISTINCT_NODE_COUNT",  # id
 18     "DISTINCT_NODE_COUNT",  # 空
 19     "COMPARE_PATHS",  # id id
 20     "PATH_CONTAINS_NODE"  # id 节点
 21 ]
 22 
 23 id = 0
 24 node_length = 1000
 25 id_list = []
 26 nodes_list = []
 27 instr1 = 0
 28 instr2 = 0
 29 instruction_list = []
 30 output_list = []
 31 input_list = []
 32 
 33 
 34 def make_instruction():
 35     for instr in instruction_list:
 36         count, lst = instr[0], instr[1]
 37         count1 = count // 10
 38         count2 = count % 10
 39         string = ""
 40         if count1 == 1:
 41             string = instructions1[count2 - 1] + " "
 42         else:
 43             string = instructions2[count2 - 1] + " "
 44         for item in lst:
 45             string = string + str(item) + " "
 46         input_list.append(string)
 47 
 48 
 49 def print_input():
 50     for item in input_list:
 51         print(item)
 52 
 53 
 54 def print_output():
 55     for item in output_list:
 56         print(item)
 57 
 58 
 59 def gen_data():
 60     """
 61     for i in range(20):
 62         random1()
 63     for j in range(20):
 64         random2()
 65     """
 66     while instr1 + instr2 != 3000:
 67         if instr1 == 300:
 68             random2()
 69             continue
 70 
 71         if instr2 == 2700:
 72             random1()
 73             continue
 74 
 75         num = random.random()
 76         if num < 0.1:
 77             random1()
 78         else:
 79             random2()
 80     make_instruction()
 81 
 82 
 83 def random1():
 84     num = random.randint(-4, 7)
 85     if num <= 1:
 86         judge, result = random1_1()
 87     elif num == 2:
 88         judge, result = random1_2()
 89     elif num == 3:
 90         judge, result = random1_3()
 91     elif num == 4:
 92         judge, result = random1_4()
 93     elif num == 5:
 94         judge, result = random1_5()
 95     elif num == 6:
 96         judge, result = random1_6()
 97     elif num == 7:
 98         judge, result = random1_7()
 99     if judge == False:
100         pass
101     else:
102         global instr1
103         instr1 += 1
104         instruction_list.append(result)
105 
106 
107 def random2():
108     num = random.randint(1, 6)
109     if num == 1:
110         judge, result = random2_1()
111     elif num == 2:
112         judge, result = random2_2()
113     elif num == 3:
114         judge, result = random2_3()
115     elif num == 4:
116         judge, result = random2_4()
117     elif num == 5:
118         judge, result = random2_5()
119     elif num == 6:
120         judge, result = random2_6()
121     if judge == False:
122         pass
123     else:
124         global instr2
125         instr2 += 1
126         instruction_list.append(result)
127 
128 
129 def random1_1():
130     lst = []
131     for i in range(node_length):
132         num = random.randint(1, node_length)
133         lst.append(num)
134     nodes_list.append(lst)
135     global id
136     id += 1
137     id_list.append(id)
138     output_list.append("Ok, path id is {}.".format(id))
139     return True, [11, lst]
140 
141 
142 def random1_2():
143     if nodes_list == []:
144         return False, []
145     num = random.randint(1, 2)
146     if num == 1:
147         lst = []
148         for i in range(node_length):
149             lst.append(random.randint(1, node_length))
150         if lst not in nodes_list:
151             output_list.append("Failed, path not exist.")
152         else:
153             index = nodes_list.index(lst)
154             nodes_list.pop(index)
155             num = id_list.pop(index)
156             output_list.append("Ok, path id is {}.".format(num))
157         return True, [12, lst]
158     else:
159         num = random.randint(1, len(nodes_list))
160         lst = nodes_list.pop(num - 1)
161         num = id_list.pop(num - 1)
162         output_list.append("Ok, path id is {}.".format(num))
163         return True, [12, lst]
164 
165 
166 def random1_3():
167     if id_list == []:
168         return False, []
169     num = random.randint(1, 2)
170     if num == 1:
171         num = random.randint(1, id)
172         if num not in id_list:
173             output_list.append("Failed, path id not exist.")
174         else:
175             index = id_list.index(num)
176             id_list.pop(index)
177             nodes_list.pop(index)
178             output_list.append("Ok, path removed.")
179         return True, [13, [num]]
180     else:
181         num = random.randint(1, len(id_list))
182         nodes_list.pop(num - 1)
183         lst = [id_list.pop(num - 1)]
184         output_list.append("Ok, path removed.")
185         return True, [13, lst]
186 
187 
188 def random1_4():
189     if nodes_list == []:
190         return False, []
191     num = random.randint(1, 2)
192     if num == 1:
193         lst = []
194         for i in range(node_length):
195             lst.append(random.randint(1, node_length))
196         if lst not in nodes_list:
197             output_list.append("Failed, path not exist.")
198             return True, [14, lst]
199         else:
200             index = nodes_list.index(lst)
201             output_list.append("Ok, path id is {}.".format(id_list[index]))
202             return True, [14, lst]
203     else:
204         num = random.randint(1, len(nodes_list))
205         output_list.append("Ok, path id is {}.".format(id_list[num - 1]))
206         return True, [14, nodes_list[num - 1]]
207 
208 
209 def random1_5():
210     if id_list == []:
211         return False, []
212     num = random.randint(1, 2)
213     if num == 1:
214         num = random.randint(1, id)
215         if num not in id_list:
216             output_list.append("Failed, path id not exist.")
217             return True, [15, [num]]
218         else:
219             index = id_list.index(num)
220             path = nodes_list[index]
221             string = ""
222             for item in path:
223                 string += str(item) + ", "
224             string = string[:-2]
225             output_list.append("Ok, path is (" + string + ").")
226             return True, [15, [num]]
227     else:
228         num = random.randint(1, len(id_list))
229         path = nodes_list[num - 1]
230         string = ""
231         for item in path:
232             string += str(item) + ", "
233         string = string[:-2]
234         output_list.append("Ok, path is (" + string + ").")
235         return True, [15, [id_list[num - 1]]]
236 
237 
238 def random1_6():
239     num = random.randint(1, 2)
240     if num == 1:
241         if nodes_list == []:
242             return False, []
243         num = random.randint(1, len(nodes_list))
244         output_list.append("Yes.")
245         return True, [16, nodes_list[num - 1]]
246     else:
247         lst = []
248         for i in range(node_length):
249             num = random.randint(1, node_length)
250             lst.append(num)
251         if lst in nodes_list:
252             output_list.append("Yes.")
253         else:
254             output_list.append("No.")
255         return True, [16, lst]
256 
257 
258 def random1_7():
259     if id == 0:
260         return False, [17, [0]]
261     else:
262         num = random.randint(1, id)
263         if num in id_list:
264             output_list.append("Yes.")
265         else:
266             output_list.append("No.")
267     return True, [17, [num]]
268 
269 
270 def random2_1():
271     output_list.append("Total count is {}.".format(len(id_list)))
272     return True, [21, []]
273 
274 
275 def random2_2():
276     if id_list == []:
277         return False, [22, [0]]
278     num = random.randint(1, id)
279     if num not in id_list:
280         output_list.append("Failed, path id not exist.")
281     else:
282         index = id_list.index(num)
283         output_list.append("Ok, path size is {}.".format(len(nodes_list[index])))
284     return True, [22, [num]]
285 
286 
287 def random2_3():
288     if id == 0:
289         return False, [22, [0]]
290     num = random.randint(1, id)
291     if num not in id_list:
292         output_list.append("Failed, path id not exist.")
293     else:
294         index = id_list.index(num)
295         lst = nodes_list[index]
296         lst = set(lst)
297         output_list.append("Ok, distinct node count of path is {}.".format(len(lst)))
298     return True, [23, [num]]
299 
300 
301 def random2_4():
302     lst = set([])
303     for item in nodes_list:
304         lst = lst | set(item)
305     output_list.append("Ok, distinct node count is {}.".format(len(lst)))
306     return True, [24, []]
307 
308 
309 def random2_5():
310     if len(id_list) < 2:
311         return False, [25, [1, 2]]
312     lst = [i + 1 for i in range(id)]
313     lst = random.sample(lst, 2)
314     id1 = lst[0]
315     id2 = lst[1]
316     if id1 in id_list and id2 in id_list:
317         index1 = id_list.index(id1)
318         index2 = id_list.index(id2)
319         judge = compare_lst(nodes_list[index1], nodes_list[index2])
320         if judge == -1:
321             output_list.append("Ok, path {} is less than to {}.".format(id1, id2))
322         elif judge == 1:
323             output_list.append("Ok, path {} is greater than to {}.".format(id1, id2))
324         return True, [25, [id1, id2]]
325     else:
326         output_list.append("Failed, path id not exist.")
327         return True, [25, [id1, id2]]
328 
329 
330 def random2_6():
331     if len(id_list) == 0:
332         return False, [26, [0, 0]]
333     num1 = random.randint(1, id)
334     num2 = random.randint(1, node_length)
335     if num1 in id_list:
336         index = id_list.index(num1)
337         path = nodes_list[index]
338         if num2 in path:
339             output_list.append("Yes.")
340         else:
341             output_list.append("No.")
342     else:
343         output_list.append("Failed, path id not exist.")
344     return True, [26, [num1, num2]]
345 
346 
347 def compare_lst(lst1, lst2):
348     len1 = len(lst1)
349     len2 = len(lst2)
350     if len1 < len2:
351         length = len1
352     else:
353         length = len2
354     for i in range(length):
355         if lst1[i] < lst2[i]:
356             return -1
357         elif lst1[i] > lst2[i]:
358             return 1
359     if len1 < len2:
360         return -1
361     elif len1 > len2:
362         return 1
363     else:
364         return 0
365 
366 
367 def test():
368     # gen_data()
369     # print_input()
370     # print_output()
371     # '''
372     # f = open("input.txt", "w")
373     # for line in input_list:
374     #     f.write(line + "\n")
375     # f.close()
376     # f = open("standard.txt", "w")
377     # for line in output_list:
378     #     f.write(line + "\n")
379     # f.close
380     # '''
381     begin_time = time.clock()
382     os.system("cat input.txt|java -cp .;D:/My_code/JAVA/OO9/specs-homework-1-1.1-raw-jar-with-dependencies.jar Main>output.txt")
383     end_time = time.clock()
384     print("Time used = ", end_time - begin_time)
385     '''
386     f = open("standard.txt", "r")
387     lines_standard = f.readlines()
388     f.close()
389 
390     f = open("output.txt", "r")
391     lines_out = f.readlines()
392     f.close()
393 
394     len1 = len(lines_standard)
395     len2 = len(lines_out)
396     if len1 != len2:
397         print("lines number dismatch")
398         return False
399     else:
400         flag = 1
401         for i in range(len1):
402             line1 = lines_standard[i].strip()
403             line2 = lines_out[i].strip()
404             if line1 != line2:
405                 print("in the line {}, different!!!".format(i + 1))
406                 flag = 0
407                 return False
408         if flag == 1:
409             print("Congratulations, you are the same with WL")
410             return True
411     '''
412     return True
413 
414 
415 if __name__ == "__main__":
416     for i in range(1):
417         judge = test()
418         if not judge:
419             break
420         id = 0
421         node_length = 1000
422         id_list = []
423         nodes_list = []
424         instr1 = 0
425         instr2 = 0
426         instruction_list = []
427         output_list = []
428         input_list = []
View Code

5.2 作业10

  作业10在作业9的基础上知道需要进行时间上的分摊,在进行相应的分摊后,便也没有超时。

  针对作业10,也利用Python进行相应的大规模的测试,该代码部分由17376482同学实现:

OO第三单元作业(JML)总结
  1 from os import system
  2 import time
  3 import random
  4 from queue import Queue
  5 
  6 instructions1 = [
  7     "PATH_ADD",  # 节点序列
  8     "PATH_REMOVE",  # 节点序列
  9     "PATH_REMOVE_BY_ID",  # id
 10 ]
 11 nodes_graph = {}
 12 distance = {}
 13 instructions2 = [
 14     "PATH_GET_ID",
 15     "PATH_GET_BY_ID",
 16     "CONTAINS_PATH",
 17     "COMPARE_PATHS"
 18 ]
 19 instructions3 = [
 20     "PATH_COUNT",  # 空
 21     "PATH_SIZE",  # id
 22     "PATH_DISTINCT_NODE_COUNT",  # id
 23     "DISTINCT_NODE_COUNT",  # 空
 24     "CONTAINS_PATH_ID",  # id
 25     "PATH_CONTAINS_NODE",  # id 节点
 26     "CONTAINS_NODE",  # id 节点
 27     "CONTAINS_EDGE",  # 节点 节点
 28     "IS_NODE_CONNECTED",  # 节点 节点
 29     "SHORTEST_PATH_LENGTH"  # 节点 节点
 30 ]
 31 
 32 id = 0
 33 node_length = 200
 34 id_list = []
 35 nodes_list = []
 36 instr1 = 0
 37 instr2 = 0
 38 instr3 = 0
 39 instruction_list = []
 40 output_list = []
 41 input_list = []
 42 
 43 
 44 def make_instruction():
 45     for instr in instruction_list:
 46         count, lst = instr[0], instr[1]
 47         count1 = count // 10
 48         count2 = count % 10
 49         if count1 == 1:
 50             string = instructions1[count2 - 1] + " "
 51         elif count1 == 2:
 52             string = instructions2[count2 - 1] + " "
 53         else:
 54             if count == 0:
 55                 count += 10
 56             string = instructions3[count2 - 1] + " "
 57         for item in lst:
 58             string = string + str(item) + " "
 59         input_list.append(string)
 60 
 61 
 62 def print_input():
 63     for item in input_list:
 64         print(item)
 65 
 66 
 67 def print_output():
 68     for item in output_list:
 69         print(item)
 70 
 71 
 72 def gen_data():
 73     """
 74     while instr1 + instr2 + instr3 != 7000:
 75         # instruction type1
 76         if instr1 == 20:
 77             if instr3 != 6500:
 78                 random3()
 79                 continue
 80             else:
 81                 random2()
 82                 continue
 83         # instruction type2
 84         if instr2 == 480:
 85             if instr1 != 20:
 86                 random1()
 87                 continue
 88             else:
 89                 random2()
 90                 continue
 91         if instr3 == 6500:
 92             if instr1 != 20:
 93                 random1()
 94                 continue
 95             else:
 96                 random2()
 97                 continue
 98         num = random.random()
 99         if num < 0.04:
100             random1()
101         elif num < 0.1:
102             random2()
103         else:
104             random3()
105     """
106     for i in range(20):
107         random1()
108         for j in range(24):
109             random2()
110         for k in range(325):
111             random3()
112     make_instruction()
113 
114 
115 def random1():
116     num = random.randint(-4, 3)
117     # PATH_ADD
118     if num <= 1:
119         judge, result = random1_1()
120     # PATH_REMOVE
121     elif num == 2:
122         judge, result = random1_1()
123     # PATH_REMOVE_BY_ID
124     else:
125         judge, result = random1_1()
126     if judge is False:
127         pass
128     else:
129         global instr1
130         instr1 += 1
131         instruction_list.append(result)
132 
133 
134 def random2():
135     num = random.randint(1, 4)
136     # PATH_COUNT
137     if num == 1:
138         judge, result = random2_1()
139     # PATH_SIZE
140     elif num == 2:
141         judge, result = random2_2()
142     # PATH_DISTINCT_NODE_COUNT
143     elif num == 3:
144         judge, result = random2_3()
145     # DISTINCT_NODE_COUNT
146     else:
147         judge, result = random2_4()
148     if judge is False:
149         pass
150     else:
151         global instr2
152         instr2 += 1
153         instruction_list.append(result)
154 
155 
156 def random3():
157     num = random.randint(1, 15)
158     # PATH_COUNT
159     if num == 1:
160         judge, result = random3_10()
161     # PATH_SIZE
162     elif num == 2:
163         judge, result = random3_10()
164     # PATH_DISTINCT_NODE_COUNT
165     elif num == 3:
166         judge, result = random3_10()
167     # DISTINCT_NODE_COUNT
168     elif num == 4:
169         judge, result = random3_10()
170     elif num == 5:
171         judge, result = random3_10()
172     elif num == 6:
173         judge, result = random3_10()
174     elif num == 7:
175         judge, result = random3_10()
176     elif num == 8:
177         judge, result = random3_10()
178     elif num == 9:
179         judge, result = random3_10()
180     else:
181         judge, result = random3_10()
182     if judge is False:
183         pass
184     else:
185         global instr3
186         instr3 += 1
187         instruction_list.append(result)
188 
189 
190 # PATH_ADD
191 def random1_1():
192     lst = []
193     for i in range(node_length):
194         num = random.randint(0, 260)
195         lst.append(num)
196     if lst in nodes_list:
197         output_list.append("Ok, path id is {}.".format(nodes_list.index(lst)))
198         return True, [11, lst]
199     else:
200         nodes_list.append(lst)
201         global id
202         id += 1
203         id_list.append(id)
204         output_list.append("Ok, path id is {}.".format(id))
205         for i in range(0, len(lst) - 1):
206             add_edge(lst[i], lst[i + 1])
207             add_edge(lst[i + 1], lst[i])
208         bfs()
209         return True, [11, lst]
210 
211 
212 # PATH_REMOVE
213 def random1_2():
214     if nodes_list == []:
215         return False, []
216     num = random.randint(1, 2)
217     if num == 1:
218         lst = []
219         for i in range(node_length):
220             lst.append(random.randint(1, node_length))
221         if lst not in nodes_list:
222             output_list.append("Failed, path not exist.")
223         else:
224             index = nodes_list.index(lst)
225             nodes_list.pop(index)
226             num = id_list.pop(index)
227             output_list.append("Ok, path id is {}.".format(num))
228             for i in range(0, len(lst) - 1):
229                 remove_edge(lst[i], lst[i + 1])
230                 remove_edge(lst[i + 1], lst[i])
231             bfs()
232         return True, [12, lst]
233     else:
234         num = random.randint(1, len(nodes_list))
235         lst = nodes_list.pop(num - 1)
236         num = id_list.pop(num - 1)
237         output_list.append("Ok, path id is {}.".format(num))
238         for i in range(0, len(lst) - 1):
239             remove_edge(lst[i], lst[i + 1])
240             remove_edge(lst[i + 1], lst[i])
241         bfs()
242         return True, [12, lst]
243 
244 
245 # PATH_REMOVE_BY_ID
246 def random1_3():
247     if id_list == []:
248         return False, []
249     num = random.randint(1, 2)
250     if num == 1:
251         num = random.randint(1, id)
252         if num not in id_list:
253             output_list.append("Failed, path id not exist.")
254         else:
255             index = id_list.index(num)
256             id_list.pop(index)
257             lst = nodes_list.pop(index)
258             for i in range(0, len(lst) - 1):
259                 remove_edge(lst[i], lst[i + 1])
260                 remove_edge(lst[i + 1], lst[i])
261             output_list.append("Ok, path removed.")
262             bfs()
263         return True, [13, [num]]
264     else:
265         num = random.randint(1, len(id_list))
266         del_lst = nodes_list.pop(num - 1)
267         for i in range(0, len(del_lst) - 1):
268             remove_edge(del_lst[i], del_lst[i + 1])
269             remove_edge(del_lst[i + 1], del_lst[i])
270         lst = [id_list.pop(num - 1)]
271         output_list.append("Ok, path removed.")
272         bfs()
273         return True, [13, lst]
274 
275 
276 # PATH_GET_ID
277 def random2_1():
278     if nodes_list == []:
279         return False, []
280     num = random.randint(1, 2)
281     if num == 1:
282         lst = []
283         for i in range(node_length):
284             lst.append(random.randint(1, node_length))
285         if lst not in nodes_list:
286             output_list.append("Failed, path not exist.")
287             return True, [21, lst]
288         else:
289             index = nodes_list.index(lst)
290             output_list.append("Ok, path id is {}.".format(id_list[index]))
291             return True, [21, lst]
292     else:
293         num = random.randint(1, len(nodes_list))
294         output_list.append("Ok, path id is {}.".format(id_list[num - 1]))
295         return True, [21, nodes_list[num - 1]]
296 
297 
298 # PATH_GET_BY_ID
299 def random2_2():
300     if id_list == []:
301         return False, []
302     num = random.randint(1, 2)
303     if num == 1:
304         num = random.randint(1, id)
305         if num not in id_list:
306             output_list.append("Failed, path id not exist.")
307             return True, [22, [num]]
308         else:
309             index = id_list.index(num)
310             path = nodes_list[index]
311             string = ""
312             for item in path:
313                 string += str(item) + ", "
314             string = string[:-2]
315             output_list.append("Ok, path is (" + string + ").")
316             return True, [22, [num]]
317     else:
318         num = random.randint(1, len(id_list))
319         path = nodes_list[num - 1]
320         string = ""
321         for item in path:
322             string += str(item) + ", "
323         string = string[:-2]
324         output_list.append("Ok, path is (" + string + ").")
325         return True, [22, [id_list[num - 1]]]
326 
327 
328 # CONTAINS_PATH
329 def random2_3():
330     num = random.randint(1, 2)
331     if num == 1:
332         if nodes_list == []:
333             return False, []
334         num = random.randint(1, len(nodes_list))
335         output_list.append("Yes.")
336         return True, [23, nodes_list[num - 1]]
337     else:
338         lst = []
339         for i in range(node_length):
340             num = random.randint(1, node_length)
341             lst.append(num)
342         if lst in nodes_list:
343             output_list.append("Yes.")
344         else:
345             output_list.append("No.")
346         return True, [23, lst]
347 
348 
349 # COMPARE_PATHS
350 def random2_4():
351     if len(id_list) < 2:
352         return False, [24, [1, 2]]
353     lst = [i + 1 for i in range(id)]
354     lst = random.sample(lst, 2)
355     id1 = lst[0]
356     id2 = lst[1]
357     if id1 in id_list and id2 in id_list:
358         index1 = id_list.index(id1)
359         index2 = id_list.index(id2)
360         judge = compare_lst(nodes_list[index1], nodes_list[index2])
361         if judge == -1:
362             output_list.append("Ok, path {} is less than {}.".format(id1, id2))
363         elif judge == 1:
364             output_list.append("Ok, path {} is greater than {}.".format(id1, id2))
365         return True, [24, [id1, id2]]
366     else:
367         output_list.append("Failed, path id not exist.")
368         return True, [24, [id1, id2]]
369 
370 
371 # PATH_COUNT
372 def random3_1():
373     output_list.append("Total count is {}.".format(len(id_list)))
374     return True, [31, []]
375 
376 
377 # PATH_SIZE
378 def random3_2():
379     if id_list == []:
380         return False, [32, [0]]
381     num = random.randint(1, id)
382     if num not in id_list:
383         output_list.append("Failed, path id not exist.")
384     else:
385         index = id_list.index(num)
386         output_list.append("Ok, path size is {}.".format(len(nodes_list[index])))
387     return True, [32, [num]]
388 
389 
390 # PATH_DISTINCT_NODE_COUNT
391 def random3_3():
392     if id == 0:
393         return False, [33, [0]]
394     num = random.randint(1, id)
395     if num not in id_list:
396         output_list.append("Failed, path id not exist.")
397     else:
398         index = id_list.index(num)
399         lst = nodes_list[index]
400         lst = set(lst)
401         output_list.append("Ok, distinct node count of path is {}.".format(len(lst)))
402     return True, [33, [num]]
403 
404 
405 # DISTINCT_NODE_COUNT
406 def random3_4():
407     lst = set([])
408     for item in nodes_list:
409         lst = lst | set(item)
410     output_list.append("Ok, distinct node count is {}.".format(len(lst)))
411     return True, [34, []]
412 
413 
414 # CONTAINS_PATH_ID
415 def random3_5():
416     if id == 0:
417         return False, [35, [0]]
418     else:
419         num = random.randint(1, id)
420         if num in id_list:
421             output_list.append("Yes.")
422         else:
423             output_list.append("No.")
424     return True, [35, [num]]
425 
426 
427 # PATH_CONTAINS_NODE
428 def random3_6():
429     if len(id_list) == 0:
430         return False, [36, [0, 0]]
431     num1 = random.randint(1, id)
432     num2 = random.randint(1, node_length)
433     if num1 in id_list:
434         index = id_list.index(num1)
435         path = nodes_list[index]
436         if num2 in path:
437             output_list.append("Yes.")
438         else:
439             output_list.append("No.")
440     else:
441         output_list.append("Failed, path id not exist.")
442     return True, [36, [num1, num2]]
443 
444 
445 # CONTAINS_NODE
446 def random3_7():
447     if len(id_list) == 0:
448         return False, [37, [0, 0]]
449     num = random.randint(1, 450)
450     flag = 0
451     for i in range(len(nodes_list)):
452         lst = nodes_list[i]
453         if num in lst:
454             flag = 1
455             output_list.append("Yes.")
456             break
457     if flag == 0:
458         output_list.append("No.")
459     return True, [37, [num]]
460 
461 
462 # CONTAINS_EDGE
463 def random3_8():
464     if len(id_list) == 0:
465         return False, [38, [0, 0]]
466     num1 = random.randint(1, 260)
467     num2 = random.randint(1, 260)
468     if num1 not in nodes_graph:
469         output_list.append("No.")
470     else:
471         lst = nodes_graph.get(num1)
472         if num2 in lst:
473             output_list.append("Yes.")
474         else:
475             output_list.append("No.")
476     return True, [38, [num1, num2]]
477 
478 
479 # IS_NODE_CONNECTED
480 def random3_9():
481     if len(id_list) == 0:
482         return False, [39, [0, 0]]
483     num1 = random.randint(1, 270)
484     num2 = random.randint(1, 270)
485     if judge_node_in(num1) is False:
486         output_list.append("Failed, node id not exist.")
487     elif judge_node_in(num2) is False:
488         output_list.append("Failed, node id not exist.")
489     elif num1 == num2:
490         output_list.append("Yes.")
491     elif (num1, num2) in distance:
492         output_list.append("Yes.")
493     else:
494         output_list.append("No.")
495     return True, [39, [num1, num2]]
496 
497 
498 # SHORTEST_PATH_LENGTH
499 def random3_10():
500     if len(id_list) == 0:
501         return False, [30, [0, 0]]
502     num1 = random.randint(1, 265)
503     num2 = random.randint(1, 265)
504     if judge_node_in(num1) is False:
505         output_list.append("Failed, node id not exist.")
506     elif judge_node_in(num2) is False:
507         output_list.append("Failed, node id not exist.")
508     elif num1 == num2:
509         output_list.append("Ok, length is {}.".format(0))
510     elif distance.get((num1, num2)) is not None:
511         output_list.append("Ok, length is {}.".format(distance.get((num1, num2))))
512     else:
513         output_list.append("Failed, node not connected with each other.")
514     return True, [30, [num1, num2]]
515 
516 
517 def compare_lst(lst1, lst2):
518     len1 = len(lst1)
519     len2 = len(lst2)
520     if len1 < len2:
521         length = len1
522     else:
523         length = len2
524     for i in range(length):
525         if lst1[i] < lst2[i]:
526             return -1
527         elif lst1[i] > lst2[i]:
528             return 1
529     if len1 < len2:
530         return -1
531     elif len1 > len2:
532         return 1
533     else:
534         return 0
535 
536 
537 def judge_node_in(node):
538     for i in range(len(nodes_list)):
539         lst = nodes_list[i]
540         if node in lst:
541             return True
542     return False
543 
544 
545 def add_edge(fromNode, toNode):
546     if fromNode in nodes_graph:
547         mid_dict = nodes_graph.get(fromNode)
548         if toNode in mid_dict:
549             mid_dict[toNode] = mid_dict.get(toNode) + 1
550         else:
551             mid_dict[toNode] = 1
552         nodes_graph[fromNode] = mid_dict
553     else:
554         mid_dict = {}
555         mid_dict[toNode] = 1
556         nodes_graph[fromNode] = mid_dict
557 
558 
559 def remove_edge(fromNode, toNode):
560     mid_dict = nodes_graph.get(fromNode)
561     if mid_dict.get(toNode) == 1:
562         del mid_dict[toNode]
563     else:
564         mid_dict[toNode] = mid_dict.get(toNode) - 1
565     if mid_dict:
566         nodes_graph[fromNode] = mid_dict
567     else:
568         del nodes_graph[fromNode]
569 
570 
571 def bfs():
572     global distance
573     distance = {}
574     for key in nodes_graph.keys():
575         depth = 1
576         nowqueue = Queue()
577         nextqueue = Queue()
578         nowqueue.put(key)
579         while not nowqueue.empty():
580             nextNode = nowqueue.get()
581             keyMap = nodes_graph[nextNode]
582             for Anode in keyMap.keys():
583                 if Anode != key:
584                     if not (key, Anode) in distance:
585                         distance[(key, Anode)] = depth
586                         nextqueue.put(Anode)
587             if nowqueue.empty():
588                 depth += 1
589                 nowqueue = nextqueue
590                 midqueue = Queue()
591                 nextqueue = midqueue
592 
593 
594 if __name__ == "__main__":
595     while True:
596         nodes_graph = {}
597         distance = {}
598         id = 0
599         node_length = 200
600         id_list = []
601         nodes_list = []
602         instr1 = 0
603         instr2 = 0
604         instr3 = 0
605         instruction_list = []
606         output_list = []
607         input_list = []
608         gen_data()
609         f = open("input.txt", "w")
610         for line in input_list:
611             f.write(line + "\n")
612         f.close()
613         f = open("standard.txt", "w")
614         for line in output_list:
615             f.write(line + "\n")
616         f.close()
617         begin_time = time.perf_counter()
618         system("java -cp .;D:/My_code/JAVA/OO10/specs-homework-2-1.2-raw-jar-with-dependencies.jar Main < input.txt > output.txt")
619         end_time = time.perf_counter()
620         print("Time used = {}".format(end_time - begin_time))
621         f = open("standard.txt", "r")
622         lines_standard = f.readlines()
623         f.close()
624         f = open("output.txt", "r")
625         lines_out = f.readlines()
626         f.close()
627         len1 = len(lines_standard)
628         len2 = len(lines_out)
629         if len1 != len2:
630             print("lines number dismatch")
631             break
632         else:
633             flag = 1
634             for i in range(len1):
635                 line1 = lines_standard[i].strip()
636                 line2 = lines_out[i].strip()
637                 if line1 != line2:
638                     print("in the line {}, different!!!".format(i + 1))
639                     flag = 0
640                     break
641             if flag == 1:
642                 print("Congratulations, you are the same with the standard!")
643             else:
644                 break
View Code

5.3 作业11

  作业11出现大面积翻车,在该作业期间,周二看时间节点还是周日,到周四早上惊然发现时间节点是周四晚上,于是从看题开始一个下午速成,在中测结果通过后,时间已不够,没有构造较多测试,导致翻车。

  对于该作业完成的期间,思考的过程如下:

拆点作法:

  这道题相同id的点,在不同的Path上是不同的,可以将这些点进行拆分形成多个点,并进行链接,从而将该问题转换成一个很简单的点点之间的最短路径问题,但是这样的复杂度激增。

不拆点:

  不拆点,仍然需要对相同的id的点进行不同的考虑。

  

  bug出现原因:层次化的方法需要思考细致,在对每条Path完成各自最短路径的计算后,再在全局进行更新时,需要对全局的图首先由所有的Path进行初始化,在缺少这一步的情况下就可能出现问题。

六:阐述对规格撰写和理解上的心得体会

   JML规格更像是一种形式验证,从这样的形式验证的角度来保证代码的正确性,既保证了程序的正确性,又不限制算法的实现过程,在理解JML的前提下,代码实现就变得更加简单,感觉在团队合作过程中,相互交流不同函数的要求,不如直接看这类的JML的要求,对程序员而言更直接更能接受。

  这几次的作业中大家最终在完成规格的情况下,结果也不尽相同,表示规格的正确性固然重要,但是程序的性能不能由规格定义(虽然可以通过限制时间),仍然需要对架构和方法有清楚的认识。

上一篇:Oracle 12cR1 RAC集群安装(一)--环境准备


下一篇:java生成图片验证码