# OO_第三单元总结

## 一、测试

• 对于性能测试构造了菊花图，完全图等数据测试程序性能
• 对于正确性。随机生成数据，和同学对拍

## 二、架构设计

### 图模型构建和维护策略

• 对于qbs和qci指令我使用的并查集维护，并进行路径压缩，复杂度为 O(nα(n))
• 对于qlc指令，我用的Kruskal算法计算最小生成树，并用并查集优化。每次查询时对在一个联通块的点单独建图计算，复杂度为 O(mlogm)
        this.people = people;
this.edges = new ArrayList<>();
father = new int[17000];
indHashMap = new HashMap<>();
for (int i = 0; i < people.size(); i += 1) {
father[i] = i;
indHashMap.put(people.get(i).getId(), i);
}
for (Person person: people) {
ArrayList<Person> acquaintance = ((MyPerson) person).getAcquaintance();
ArrayList<Integer> value = ((MyPerson) person).getValue();
for (int i = 0; i < value.toArray().length; i += 1) {
if (indHashMap.containsKey(acquaintance.get(i).getId()) == false) {
continue;
}
Edge edge = new Edge();
edge.setEdge(person.getId(), acquaintance.get(i).getId(), value.get(i));
edges.add(edge);
}
}
edges.sort(new SortByIndex());
blockSum = people.size();
}

• 对于sim指令，我用堆优化的迪杰斯特拉算法进行计算，复杂度为 O((m+n)logn)
        Comparator<SPathNode> queueComparator = new PersonComparator();
PriorityQueue<SPathNode> priorityQueue = new PriorityQueue<>(2550, queueComparator);
HashMap<Integer, Integer> shortestDis = new HashMap<>();
shortestDis.put(stId, 0);
SPathNode stNode = new SPathNode(stId, 0);
priorityQueue.add(stNode);
int result = -1;
while (true) {
if (priorityQueue.isEmpty()) {
break;
}
SPathNode nowNode = priorityQueue.remove();
if (nowNode.getPersonId() == endId) {
if (result == -1) {
result = nowNode.getDistance();
}
else {
if (result > nowNode.getDistance()) {
result = nowNode.getDistance();
}
}
}
if (nowNode.getDistance() > shortestDis.get(nowNode.getPersonId())) {
continue;
}
ArrayList<Integer> value = ((MyPerson) getPerson(nowNode.getPersonId())).getValue();
ArrayList<Person> acquaintance =
((MyPerson) getPerson(nowNode.getPersonId())).getAcquaintance();
for (int i = 0; i < acquaintance.size(); i += 1) {
int toId = acquaintance.get(i).getId();
int newDis = nowNode.getDistance() + value.get(i);
if (!shortestDis.containsKey(toId)) {
shortestDis.put(toId, newDis);
SPathNode addNode = new SPathNode(toId, newDis);
priorityQueue.add(addNode);
}
else {
if (shortestDis.get(toId) > newDis) {
shortestDis.replace(toId, newDis);
SPathNode addNode = new SPathNode(toId, newDis);
priorityQueue.add(addNode);
}
}
}
}
return result;
}


## 三、问题与修复

• 在阅读qgva的规格时把
@ ensures \result == (people.length == 0? 0 : ((\sum int i; 0 <= i && i < people.length;
@          (people[i].getAge() - getAgeMean()) * (people[i].getAge() - getAgeMean())) /
@           people.length));


• 性能上获取network中的人时。一开始我是遍历所有的人，这样复杂度较高为O(n)的，有点点会TLE。而后改成了Hashmap做映射。

## 四、Network进行扩展

• Advertiser：持续向外发送产品广告。方法addProductInfoMessage
/*@ public normal_behavior
@ requires !(\exists int i; 0 <= i && i < messages.length; messages[i].equals(message)));
@ assignable messages, countOfProducts;
@ ensures messages.length == \old(messages.length) + 1;
@ ensures (\forall int i; 0 <= i && i < \old(messages.length);
@          (\exists int j; 0 <= j && j < messages.length; messages[j].equals(\old(messages[i]))));
@ ensures (\exists int i; 0 <= i && i < messages.length; messages[i].equals(message));
@ ensures countOfProducts.get(products) == \old(countOfProducts.get(products)) + 1;
@ also
@ public exceptional_behavior
@ signals (EqualMessageIdException e) (\exists int i; 0 <= i && i < messages.length;
@                                     messages[i].equals(message));
@*/
public void addProductInfoMessage(Product product);

• Producer：产品生产商，通过Advertiser来销售产品。方法：sendAdvertisement
/*@ public normal_behavior
@ requires containsMessage(id) && countOfProducts.get(product) != 0;
@ assignable messages, countOfProducts, advertise.advertiserProduct;
@ 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 advertise.advertiserProduct.contains(products)
@ ensures (\forall int i; 0 <= i && i < \old(advertise.advertiserProduct.size());
(\exits int j; 0 <= j && j < advertise.advertiserProduct.size();
old\(advertise.advertiserProduct.get(i)) == advertise.advertiserProduct.get(j)));
@ also
@ public exceptional_behavior
@ signals (MessageIdNotFoundException e) !containsMessage(id);
@ signals (ProductNotFoundException e) countOfProducts.get(product) == 0;
*/
public void sendAdvertisement(Product product, Advertiser advertise);

• Customer：消费者，会关注广告并选择和自己偏好匹配的产品来购买
*@ public normal_behaviour
@ requires message instanceof purchaseMessage;
@ requires contains(advertiserId) &&
@ (getPerson(advertiserId) instanceof Advertiser);
@ requires !getPerson(advertiserId).containsMessage(message.getId())

@ assignable getPerson(advertiserId).message[];
@ ensuers getPerson(advertiserId).message.length == \old(getPerson(advertiserId).message.length) &&
@ getPerson(advertiserId).containsMessage(message.getId());
@ also
@ public exceptional_behavior
@ signals (PersonIdNotFoundException e) !contains(advertiserId);
@ signals (WrongMessageTypeException e) !(message instanceof purchaseMessage);
@*/
void purchase(int advertiserId, Message message) throws
PersonIdNotFoundException, WrongMessageTypeException;


## 五、学习体会

posted @ 2022-06-06 14:36  ordered_bread  阅读(18)  评论(1编辑  收藏  举报