ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

2022面向对象第三单元总结

2022-06-04 19:01:54  阅读:167  来源: 互联网

标签:2022 producer 生成 面向对象 算法 指令 测试 数据 单元


目录

第三单元总结

测试方法和数据生成

测试方法

  • 采用黑盒测试
  • 测评机的实现较为简单,直接对拍即可

数据生成

随机数据

  • 分为 all, group, circle, message, emoji, money 六种模式
    • all:测试全部指令
    • group:测试与组相关的指令
    • circle:测试与关系相关的指令,重点是最小生成树和最短路
    • message:测试各种消息的发送和接受
    • emoji:测试表情类型消息的相关指令
    • money:测试红包类型消息的相关指令
  • 通过字典 INS_NUM_LIMIT = {'ap': 2500, 'qci': 100, 'ag': 20, 'qlc': 20, 'sim': 500} 限制各种指令的条数,可满足不同数据规模

特殊数据

  • 单指令:测试边界情况
  • 线性图、完全图等:测试 qlcsim 等指令的时间复杂度
  • 其他特征的数据:测试 qbsqgvsqgav 等指令的时间复杂度,具体特征各不相同,在这就不一一介绍了

数据有效性

  • 本人三次作业强测和互测均未被 hack
  • 三次互测均有 hack
  • 本次测出了其他同学的很多性能问题

架构分析

  • 核心类图(忽略了异常类和部分继承官方接口的类,重点关注图模型的构建与维护)

  • 类功能分析
    • Graph:关系图
      • 以联通分量 Block 为单位进行存储和维护
      • 支持 qbsqciqlcsim 等指令的查询
    • Block:联通分量
      • 保存了节点 MyPerson 和边 Relation 的信息
      • 用于计算最小生成树和最短路等
    • UnionFindSet:并查集
      • Graph 中用于 Block 的维护,在 Block 中用于 kruskal 算法求最小生成树
      • 进行了路径压缩、按大小合并等优化

性能问题与优化

输出性能问题

  • 在异常类中,使用 printf 函数输出会比 println 慢很多
  • 虽然不会影响通过测评,但是经过本地大规模数据的测试,在其他算法几乎相同的情况下,使用 printf 的总 CPU 时间能达到 println 的两倍

算法选择

  • 只要不出现 \(O(n^2)\) 复杂度的算法,通过强测和互测问题不大
  • qci:并查集 + 路径压缩 + 按大小合并
  • qlc:kruskal 算法(经本地测试,效率比堆优化的 prim 算法性能更好)
  • sim:dijkstra 算法 + 堆优化

动态维护

  • qgvs 为例,如果每次查询都重新计算一遍的话,复杂度会达到 \(O(n^2)\),因此可以进行动态维护
  • 添加 person 时,加上他与每个人的 value 值之和的两倍(删除时同理)
  • 添加 relation 时,遍历所有 group,如果两个人都在同一 group 中,加上 value

利用缓存

  • qlc 为例,在联通分量的结构不发生变化时,每次查询的结果一定相同,因此可以记录下来
  • 变量 leastConnection 记录最小生成树的路径权值和
    • 当其值不为 -1 时,表示数据有效,可直接返回
    • 否则需要重新计算最小生成树,并赋值给 leastConnection
  • 在添加 personrelation 时,将 leastConnection 设为 -1

Network 扩展

  • 新增 ProducerAdvertiserCustomer 接口并继承 Person

  • 新增 ItemMessage 接口并继承 Message,用于存储商品相关信息

  • 三个核心方法的规格如下

    /*@ public normal_behaviour
      @ requires !producer.hasItem(item);
      @ assignable producer.items;
      @ ensures producer.items.length = \old(producer.items.length) + 1;
      @ ensures producer.hasItem(item);
      @ ensures (\forall int i; 0 <= i && i < \old(producer.items.length);
      @         (\exists int j; 0 <= j && j < producer.items.length;
      @			producer.items[j] == (\old(producer.items[i]))));
      @ also 
      @ public exceptional_behaviour
      @ signals (DuplicatedItemException e) producer.hasItem(item);
      @*/
    void produce(Producer producer, ItemMessage item);
    
    /*@ public normal_behaviour
      @ requires !advertiser.hasItem(item) && producer.hasItem(item);
      @ assignable advertiser.items;
      @ ensures advertiser.items.length = \old(advertiser.items.length) + 1;
      @ ensures advertiser.hasItem(item);
      @ ensures (\forall int i; 0 <= i && i < \old(advertiser.items.length);
      @         (\exists int j; 0 <= j && j < advertiser.items.length;
      @			advertiser.items[j] == (\old(advertiser.items[i]))));
      @ also 
      @ public exceptional_behaviour
      @ signals (ItemNotFoundException e) !producer.hasItem(item);
      @ also 
      @ public exceptional_behaviour
      @ signals (DuplicatedItemException e) producer.hasItem(item) && advertiser.hasItem(item);
      @*/
    void advertise(Producer producer, Advertiser advertiser, ItemMessage item);
    
    
    /*@ public normal_behaviour
      @ requires advertiser.hasItem(item) && !customer.hasItem(item);
      @ assignable customer.items, advertiser.items;
      @ assignable customer.money, item.getProducer().money;
      @ ensures customer.items.length = \old(customer.items.length) + 1;
      @ ensures customer.hasItem(item);
      @ ensures (\forall int i; 0 <= i && i < \old(customer.items.length);
      @         (\exists int j; 0 <= j && j < customer.items.length;
      @			customer.items[j] == (\old(customer.items[i]))));
      @ ensures advertiser.items.length = \old(advertiser.items.length) - 1;
      @ ensures !advertiser.hasItem(item);
      @ ensures (\forall int i; 0 <= i && i < advertiser.items.length;
      @         (\exists int j; 0 <= j && j < \old(advertiser.items.length);
      @			advertiser.items[i] == (\old(advertiser.items[j]))));
      @ ensures customer.money = customer.money - item.getPrice();
      @ ensures item.getProducer().money = item.getProducer().money + item.getPrice();
      @ also 
      @ public exceptional_behaviour
      @ signals (ItemNotFoundException e) !advertiser.hasItem(item);
      @ also 
      @ public exceptional_behaviour
      @ signals (DuplicatedItemException e) advertiser.hasItem(item) && customer.hasItem(item);
      @*/
    void purchase(Advertiser advertiser, Customer customer, ItemMessage item);
    

心得与体会

  • 学习了 JML 的基础知识
  • 学会了如何用 JUnit 进行单元测试
  • 了解了契约式编程和防御式编程的概念
  • 复习了图相关算法
  • 数据构造能力进一步提升

标签:2022,producer,生成,面向对象,算法,指令,测试,数据,单元
来源: https://www.cnblogs.com/t0ush1/p/16342441.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有