其他分享
首页 > 其他分享> > OO第三单元总结

OO第三单元总结

作者:互联网

OO第三单元总结

利用JML规格准备测试数据

利用JML规格的前置条件构造数据便于对所有可能的情况进行分类讨论,保障了测试数据的覆盖率。但仅用后置条件和约束条件对结果进行判断无法保证结果完全正确,仍需要对拍。此外,对于代码性能的检测也需要额外构造数据。

图模型构建和维护策略

queryLeastConnection

先找到节点所在的Block,然后采用kruskal算法计算最小生成树

public int queryLeastConnection() {
   if (changed) {
       Collections.sort(edges);       //对所有边按权重从小到大排序
       HashMap<Integer, Integer> fatherMap = new HashMap<>();
       leastConnection = 0;
       int edgeNum = 0;   //已经加入的边的数量,最大为people.size - 1
       for (Edge edge : edges) {    //遍历所有边
           int root1 = findRoot(fatherMap, edge.getId1());  //找到两个顶点的根节点
           int root2 = findRoot(fatherMap, edge.getId2());
           if (root1 != root2) {      //保证不构成回路
               if (root1 > root2) {
                   fatherMap.put(root1, root2);
              } else {
                   fatherMap.put(root2, root1);
              }
               leastConnection += edge.getValue();
               edgeNum++;
               if (edgeNum == people.size() - 1) {   //已经构成最小生成树
                   break;
              }
          }
      }
       changed = false;
  }
   return leastConnection;
}
sendIndirectMessage

通过findRoot找到对应的Block,并调用getStep采用Dijkstra算法计算最短路径

public int getStep(PersonClass person1, PersonClass person2) {
   HashMap<Person, Integer> net = new HashMap<>(person1.getAcquaintance());
   //person1所有能到达的节点,以及对应的路径长度
   HashMap<Person, Integer> queue = new HashMap<>(person1.getAcquaintance());
   //未找到最短路径的节点的队列,以及当前到达person1的路径长度
   for (int layer = 0;layer < people.size();layer++) {
       Integer min = null;
       PersonClass target = null;
       for (Person i : queue.keySet()) {    //从queue中寻找离person1最近的节点
           if ((min == null) || (queue.get(i) < min)) {
               min = queue.get(i);
               target = (PersonClass) i;
          }
      }
       assert target != null;
       assert min != null;
       if (target.equals(person2)) {   //找到person2,可以返回
           return net.get(person2);
      }
       queue.remove(target);   //从queue中删除已经找到最短路径的节点
       for (Person i : target.getAcquaintance().keySet()) {
           if ((net.get(i) == null) || (net.get(i) > min + i.queryValue(target))) {
           //需要更新路径长度的节点
               net.put(i, min + i.queryValue(target));    //更新路径
               queue.put(i, min + i.queryValue(target));  //加入队列
          }
      }
  }
   return net.get(person2);
}

性能问题

getAgeVar

计算AgeVar时,可以根据每个人年龄的平方和以及平均数得到,在addPerson和delPerson的时候对ageVarSum和ageMeanSum进行更新,降低了getAgeVar的复杂度。但需要注意/表示整除,除法和加法的顺序不同可能会导致结果不同。

public int getAgeVar() {
   if (people.size() == 0) {
       return 0;
  } else {
       int mean = getAgeMean();
       return (ageVarSum - 2 * ageMeanSum * mean + mean * mean * people.size())
               / people.size();
  }
}
queryGroupValueSum

在addPerson和depPerson时,更新group中的valueSum

for (Person i : people) {   //addPerson
   valueSum += i.queryValue(person);
}
for (Person i : people) {   //delPerson
   valueSum -= i.queryValue(person);
}

并在addRelation时遍历所有group,更新valueSum

for (Group group : groups.values()) {
   if (group.hasPerson(people.get(id1)) && group.hasPerson(people.get(id2))) {
   //group中同时包含person1和person2
      ((GroupClass) group).addValue(value);
  }
}

Network扩展

Advertiser发送AdMessage
/*@ public normal_behavior
 @ requires containsMessage(id) && getMessage(id) instanceof AdMessage) &&
 @         getMessage(id).getType() == 0 &&
 @         getMessage(id).getPerson1().isLinked(getMessage(id).getPerson2()) &&
 @         getMessage(id).getPerson1() != getMessage(id).getPerson2() &&
 @ getMessage(id).getPerson1().isLinked(getMessage(id).producer) &&
 @ getMessage(id).producer.contains(getMessage(id).product);
 @ 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();
 @ also
 @ public exceptional_behavior
 @ signals (MessageIdNotFoundException e) !containsMessage(id) ||
 @ !(getMessage(id) instanceof AdMessage) ||
 @ !(getMessage(id).getType() == 0);
 @ signals (RelationNotFoundException e) containsMessage(id) &&
 @ (getMessage(id) instanceof AdMessage) &&
 @         getMessage(id).getType() == 0 &&
 @         (!getMessage(id).getPerson1().isLinked(getMessage(id).getPerson2()) ||
 @ !getMessage(id).getPerson1().isLinked(getMessage(id).producer))
 @ signals (ProductIdNotFoundException e) containsMessage(id) &&
 @ (getMessage(id) instanceof AdMessage) &&
 @         getMessage(id).getType() == 0 &&
 @         getMessage(id).getPerson1().isLinked(getMessage(id).getPerson2()) &&
 @         getMessage(id).getPerson1() != getMessage(id).getPerson2() &&
 @ getMessage(id).getPerson1().isLinked(getMessage(id).producer) &&
 @         !getMessage(id).producer.contains(getMessage(id).product);
 @*/
public void sendAdMessage(int id) throws
       RelationNotFoundException, MessageIdNotFoundException,
       ProductIdNotFoundException;
Customer发送BuyMessage
/*@ public normal_behavior
 @ requires containsMessage(id) && getMessage(id).getType() == 0 &&
 @ getMessage(id) instance of BuyMessage &&
 @ getMessage(id).getPerson1 instance of Customer &&
 @ (\exist int i;0 <= i && i < getMessage(id).getPerson1.prefer.length;
 @ getMessage(id).getPerson1.prefer[i] == getMessage(id).product) &&
 @ getMessage(id).getPerson2 instance of Producer &&
 @ (\exist int i;0 <= i && i < getMessage(id).getPerson2.products.length;
 @ getMessage(id).getPerson2.products[i] == getMessage(id).product) &&
 @         (!(\exist Person i; i instance of Advertiser &&
 @ (\exist int j;0 <= j && j < getMessage(id).getPerson1.acquaintance.length;
 @ getMessage(id).getPerson1.acquaintance[j] == i) &&
 @ (\exist int k;0 <= k && k < getMessage(id).getPerson2.acquaintance.length;
 @ getMessage(id).getPerson2.acquaintance[k] == i)) ||
 @ getMessage(id).getPerson2.getProductNum(getMessage(id).product) <
 @ getMessage(id).num ||
 @ getMessage(id).getPerson1.money < getMessage(id).product.price);
 @ ensures \result == -1;
 @ also
 @ public normal_behavior
 @ requires containsMessage(id) && getMessage(id).getType() == 0 &&
 @ getMessage(id) instance of BuyMessage &&
 @ getMessage(id).getPerson1 instance of Customer &&
 @ (\exist int i;0 <= i && i < getMessage(id).getPerson1.prefer.length;
 @ getMessage(id).getPerson1.prefer[i] == getMessage(id).product) &&
 @ getMessage(id).getPerson2 instance of Producer &&
 @ (\exist int i;0 <= i && i < getMessage(id).getPerson2.products.length;
 @ getMessage(id).getPerson2.products[i] == getMessage(id).product) &&
 @         (\exist Person i; i instance of Advertiser &&
 @ (\exist int j;0 <= j && j < getMessage(id).getPerson1.acquaintance.length;
 @ getMessage(id).getPerson1.acquaintance[j] == i) &&
 @ (\exist int k;0 <= k && k < getMessage(id).getPerson2.acquaintance.length;
 @ getMessage(id).getPerson2.acquaintance[k] == i)) &&
 @ getMessage(id).getPerson2.getProductNum(getMessage(id).product) >=
 @ getMessage(id).num &&
 @ getMessage(id).getPerson1.money >= getMessage(id).product.price;
 @ assignable messages, getMessage(id).product;
 @ assignable getMessage(id).getPerson1().socialValue,
 @   getMessage(id).getPerson1().money;
 @ assignable getMessage(id).getPerson2().messages, getMessage(id).getPerson2().money,
 @           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 (\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;
 @ ensures (\old(getMessage(id)).getPerson1().getMoney() ==
 @         \old(getMessage(id).getPerson1().getMoney()) -
 @ \old(getMessage(id)).product.price * \old(getMessage(id).num);
 @ ensures (\old(getMessage(id)).getPerson2().getMoney() ==
 @         \old(getMessage(id).getPerson2().getMoney()) +
 @ \old(getMessage(id)).product.price * \old(getMessage(id).num);
 @ ensures \old(getMessage(id)).product.sales += \old(getMessage(id).num;
 @ also
 @ public exceptional_behavior
 @ signals (MessageIdNotFoundException e) !containsMessage(id) ||
 @ getMessage(id).getType() != 0 ||
 @ !getMessage(id) instance of BuyMessage ||
 @ !getMessage(id).getPerson1 instance of Customer ||
 @ !(\exist int i;0 <= i && i < getMessage(id).getPerson1.prefer.length;
 @ getMessage(id).getPerson1.prefer[i] == getMessage(id).product) ||
 @ !getMessage(id).getPerson2 instance of Producer
 @ signals (ProductIdNotFoundException e) containsMessage(id) &&
 @ getMessage(id).getType() == 0 &&
 @ getMessage(id) instance of BuyMessage &&
 @ getMessage(id).getPerson1 instance of Customer &&
 @ (\exist int i;0 <= i && i < getMessage(id).getPerson1.prefer.length;
 @ getMessage(id).getPerson1.prefer[i] == getMessage(id).product) &&
 @ getMessage(id).getPerson2 instance of Producer &&
 @ !(\exist int i;0 <= i && i < getMessage(id).getPerson2.products.length;
 @ getMessage(id).getPerson2.products[i] == getMessage(id).product)
 @*/
public int sendIndirectMessage(int id) throws
       MessageIdNotFoundException, ProductIdNotFoundException;
查询销售额
/*@ public normal_behavior
 @ requires (\exists int i; 0 <= i && i < productIdList.length; productIdList[i] == id);
 @ ensures (\exists int i; 0 <= i && i < productIdList.length; productIdList[i] == id &&
 @         \result == productIdList[i].price * productIdList[i].sales);
 @ also
 @ public exceptional_behavior
 @ requires !(\exists int i; 0 <= i && i < productIdList.length;
 @ productIdList[i] == id);
 @ signals_only ProductIdNotFoundException;
 @*/
public /*@ pure @*/ int querySales(int id) throws ProductIdNotFoundException;
 

标签:OO,总结,old,getPerson2,int,getMessage,&&,id,单元
来源: https://www.cnblogs.com/rrmmffll/p/16341310.html