U3总结

第三单元总结博客

(1) 自测的测试数据

根据方法的JML规格准备测试数据:

  1. 方法名前是否存在/*@ pure @*/标记,如果有,那么此方法不应该改变任何变量的值。

  2. 根据require条件分别准备满足条件和不满足条件的数。判断满足条件的数据是否有返回值满足ensure的规定,是否只有assignable修饰的变量改变;不满足条件的数据能否正确抛出异常。

  3. 随机构造测试数据时,可以通过增加测试数据条数,来提高测试数据的强度。

(2) 梳理本单元的架构设计,分析自己的图模型构建和维护策略

在图模型中,由人作为节点,两人之间的关系作为边,value作为关系的权重,构建了图的结构,其中在网络中,通过HashMap存储节点和节点id

为了提高指令的速度,需要同时维护一些数据以便快速查询。

(3) 按照作业分析代码实现出现的性能问题和修复情况

qci

性能问题:每次在查询该指令时,都对所有节点的熟人进行遍历直到找到目标,导致的超时。

修复情况:对于每个节点,保存节点的父节点。在生成一个新节点的时候,该节点就是它的父节点,那么只需一直查询父节点的父节点即可得到根节点。在添加关系时,如果两个节点的根节点不同,那么将其中一个节点的根节点的根节点设为另一个节点的根节点,那么与这两个节点直接或间接连接的节点都具有了相同的根节点。

qbs

性能问题:每次在查询该指令时,对网络中的所有人进行遍历,从而找到根节点的个数,导致的超时。

修复情况:在网络中保存分块数量n。n初始化为0,每向网络中添加一个人,n加一,而通过添加关系将两个根节点不同的节点连接时,n减一。即可直接查询n的值返回结果。

qgvs

性能问题:对组内所有人进行遍历,两次for循环,导致的超时。

修复情况:查询一个组内所有人的关系权重之和。从一个人开始遍历其所有熟人,然后再遍历其熟人的所有熟人,知道将组内所有的关系遍历完毕。

qlc

性能问题:在查询最小生成树时将所有节点分为两组,一组为有确定的连接的边的节点,另一组为没有确定的边的节点。使用两个for循环遍历其中所有节点寻找权重最小的边时会造成超时。

修复情况:应当记录两组节点中所有节点据最初节点的权重,在每次更新当前节点的所有熟人节点的权重后,找出所有未连接节点中权重最小的节点,将其作为下一轮的当前节点。

sim

使用迪杰斯特拉算法+堆优化算法。

(4) 请针对下页ppt内容对Network进行扩展,并给出相应的JML规格

假设出现了几种不同的Person

  • Advertiser:持续向外发送产品广告

  • Producer:产品生产商,通过Advertiser来销售产品

  • Customer:消费者,会关注广告并选择和自己偏好匹配的产品来购买 -- 所谓购买,就是直接通过Advertiser给相应Producer发一个购买消息

  • Person:吃瓜群众,不发广告,不买东西,不卖东西

如此Network可以支持市场营销,并能查询某种商品的销售额和销售路径等 请讨论如何对Network扩展,给出相关接口方法,并选择3个核心业务功能的接口方法撰写JML规格(借鉴所总结的JML规格模式)

Producer向Advertiser提供商品信息

  /*@ public normal_behavior
  @ requires containPerson(advertiserId) && containProduction(productId) &&
  @ (\forall int i; 0 <= i && i < getPerson(advertiserId).products.length;
  @ !getPerson(advertiserId).hasProduct(productId);
     @ assignable getPerson(advertiserId).products ;
     @ ensures (\forall int i; 0 <= i && i < \old(getPerson(advertiserId).products.length);
     @ getPerson(advertiserId).hasProduct(getPerson(advertiserId).products[i].getId());
     @ ensures getPerson(advertiserId).products.length == \old(getPerson(advertiserId).products.length) + 1 ;
     @ ensures getPerson(advertiserId).hasProduct(productionId);
     @ also
     @ public exceptional_behavior
     @ signals (AdvertiserIdNotFoundException e) !containPerson(advertiserId);
     @ signals (ProductionIdNotFoundException e) !containProduction(productionId);
     @ signals (EqualProductionIdException e) (\exists int i; 0 <= i && i < getPerson(advertiserId).products.length;
     @ getPerson(advertiserId).products[i].getId() == productionId) ;
     @*/
 public void sendProduct(int advertiserId,int productId);

Advertiser发送广告

 /*@ public normal_behavior 
       @ requires containsMessage(id) && getMessage(id).getType() == 0 &&
       @         getMessage(id).getPerson1().isLinked(getMessage(id).getPerson2()) &&
       @         getMessage(id).getPerson1() != getMessage(id).getPerson2();
       @ assignable messages;
       @ assignable getMessage(id).getPerson1().socialValue;
       @ assignable getMessage(id).getPerson2().messages, getMessage(id).getPerson2().socialValue;
       @ ensures !containsMessage(id) && messages.length == \old(messages.length) - 1 &&
       @         (\forall int i; 0 <= i && i < \old(messages.length) && \old(messages[i].getId()) != id;
       @         (\exists int j; 0 <= j && j < messages.length; messages[j].equals(\old(messages[i]))));
       @ ensures \old(getMessage(id)).getPerson1().getSocialValue() ==
       @         \old(getMessage(id).getPerson1().getSocialValue()) + \old(getMessage(id)).getSocialValue() &&
       @         \old(getMessage(id)).getPerson2().getSocialValue() ==
       @         \old(getMessage(id).getPerson2().getSocialValue()) + \old(getMessage(id)).getSocialValue();
 
       @ ensures (\old(getMessage(id)) instanceof Advertisement) ==>
       @         (\forall int i; 0 <=i && i < \old(getMessage(id)).getPerson2().products.length;       getMessage(id).getPerson2().hasProduct(\old(getMessage(id)).getPerson2().products[i]));
       @ ensure getMessage(id).getPerson2().hasProduct(((Advertisement)\old(getMessage(id))).getProduct());
       @ ensures (\forall int i; 0 <= i && i < \old(getMessage(id).getPerson2().getMessages().size());
       @         \old(getMessage(id)).getPerson2().getMessages().get(i+1) == \old(getMessage(id).getPerson2().getMessages().get(i)));
       @ ensures \old(getMessage(id)).getPerson2().getMessages().get(0).equals(\old(getMessage(id)));
       @ ensures \old(getMessage(id)).getPerson2().getMessages().size() == \old(getMessage(id).getPerson2().getMessages().size()) + 1;
       @ also
       @ public normal_behavior
       @ requires containsMessage(id) && getMessage(id).getType() == 1 &&
       @           getMessage(id).getGroup().hasPerson(getMessage(id).getPerson1());
       @ assignable people[*].socialValue, people[*].money, messages, emojiHeatList;
       @ ensures !containsMessage(id) && messages.length == \old(messages.length) - 1 &&
       @         (\forall int i; 0 <= i && i < \old(messages.length) && \old(messages[i].getId()) != id;
       @         (\exists int j; 0 <= j && j < messages.length; messages[j].equals(\old(messages[i]))));              
       @ ensures (\forall Person p; \old(getMessage(id)).getGroup().hasPerson(p); p.getSocialValue() ==
       @         \old(p.getSocialValue()) + \old(getMessage(id)).getSocialValue());              
       @ ensures (\forall int i; 0 <= i && i < people.length && !\old(getMessage(id)).getGroup().hasPerson(people[i]);
       @         \old(people[i].getSocialValue()) == people[i].getSocialValue());
       @ ensures ((\old(getMessage(id)) instanceof Advertisement)) ==>
       @         (\forall Person p; \old(getMessage(id)).getGroup().hasPerson(p);
                     (\forall int i; 0 <=i && i < \old(p).products.length;p.hasProduct(\old(p).products[i])));
       @ ensures ((\old(getMessage(id)) instanceof Advertisement)) ==>
       @         (\forall Person p; \old(getMessage(id)).getGroup().hasPerson(p);
       @             p.hasProduct(((Advertisement)\old(getMessage(id))).getProduct());
       @ also
       @ public exceptional_behavior
       @ signals (MessageIdNotFoundException e) !containsMessage(id);
       @ signals (RelationNotFoundException e) containsMessage(id) && getMessage(id).getType() == 0 &&
       @         !(getMessage(id).getPerson1().isLinked(getMessage(id).getPerson2()));
       @ signals (PersonIdNotFoundException e) containsMessage(id) && getMessage(id).getType() == 1 &&
       @         !(getMessage(id).getGroup().hasPerson(getMessage(id).getPerson1()));
       @*/
 public void sendAdvertise(int id) throws PersonIdNotFoundException,MessageIdNotFoundException,RelationNotFoundException;

 

查询价格

     /*@ public normal_behavior
     @ requires contains(personId) && getPerson(personId).Productcontains(productId);
     @ assignable \nothing;
     @ ensures \result == getPerson(personId).getProduct(productId).getValue();
     @ also
     @ public exceptional_behavior
     @ signals (PersonIdNotFoundException e) ! contians(personId);
     @ signals (ProductIdNotFoundException) contians(personId) && ! getPerson(personId).Productcontains(productId);
     @*/
     public \*@pure@*\ int queryProductValue(int personId, int productId) throws PersonIdNotFoundException,ProductIdNotFoundException;

 

(5) 本单元学习体会

在本单元中对规格建立和算法优化的练习更多,出现了很多超时的问题,但是在一一处理的过程中,提高了对于数据结构中图论部分的熟练度。关于JML规格方面,看规格基本可以理解代码意义,但是在自己写规格方面仍不是思路清晰。

posted @ 2022-06-06 15:59  LJJ+  阅读(81)  评论(0编辑  收藏  举报