Coursera Algorithm Ⅱ week1 编程作业 WordNet

全部代码:https://github.com/RedemptionC/CourseraAlgorithms/tree/master/wordnet

这是学习完有向图,无向图之后的编程作业,我们要提交的是三个类:

SAP(shortest ancestor path) :

输入是一张有向图,实现这样一些函数:给出两个点,求他们的最短祖先路径长度,如果没有就返回-1

这里的最短祖先路径是指:假设v,w有一个公共祖先x,对应的祖先路径是v-x,x-w之间的有向路径,两条路径长度之和最小时,就是最短祖先路径

如图:

除了点与点的最短祖先路径,还要求计算点集与点集之间的最短祖先路径

首先是求两点的sap:

private void setSAP(int v, int w) {
        validateV(v);
        validateV(w);
        BreadthFirstDirectedPaths breadthFirstDirectedPathsV = new BreadthFirstDirectedPaths(
                digraph, v);
        BreadthFirstDirectedPaths breadthFirstDirectedPathsW = new BreadthFirstDirectedPaths(
                digraph, w);
        HashSet<Integer> setV = new HashSet<>();
        for (int i = 0; i < digraph.V(); i++) {
            // 这里是包括自己的,因为如果A->B,那么B也可以是SAP上的公共祖先
            // 记录所有v能够到达的点,放进set
            if (breadthFirstDirectedPathsV.distTo(i) != Integer.MAX_VALUE)
                setV.add(i);
        }
        ancestor = null;
        minDistance = Integer.MAX_VALUE;
        for (int i = 0; i < digraph.V(); i++) {
            // 处理所有w能到达,并且在set里(v也能到达)的点
            if (breadthFirstDirectedPathsW.distTo(i) != Integer.MAX_VALUE && setV.contains(i)) {
                // 计算他们的距离之和,保存产生最小值时的祖先(即他们的到达的公共点)
                int t = breadthFirstDirectedPathsV.distTo(i) + breadthFirstDirectedPathsW.distTo(i);
                if (t < minDistance) {
                    minDistance = t;
                    ancestor = i;
                }
            }
        }
        this.v = v;
        this.w = w;
        if (minDistance == Integer.MAX_VALUE)
            minDistance = -1;
        if (ancestor == null)
            ancestor = -1;
    }

首先调用提供的BFS库,将v,w分别作为遍历的起点,算出pathTo,和distTo数组(这里出于各种原因考虑使用了现有的库,没有自己实现,因此在本文最后面会附上这个库的笔记),其中distTo[v]记录了起点s与v之间的距离

然后将v出发能到达的点加入到一个set,之后遍历w出发能到达,并且也出现在set中(即v能到达)的点,计算该祖先路径的长度,保存最小的,并且记下sap对应的祖先节点

然后是两个点集之间的sap:

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值