【问题标题】:Parallel edge detection平行边缘检测
【发布时间】:2014-03-29 22:54:51
【问题描述】:

我正在解决一个问题(来自 Sedgewick 的算法,第 4.1 节,问题32)以帮助我理解,但我不知道如何继续。

“平行边检测。设计一种线性时间算法来计算(多)图中的平行边。 提示:维护一个顶点邻居的布尔数组,并通过仅根据需要重新初始化条目来重用该数组。"

如果两条边连接同一对顶点,则认为它们是平行的

有什么想法吗?

【问题讨论】:

  • 你试过什么?现在不要担心得到 O(n),只需尝试计算平行边。你会怎么做?
  • 我唯一能想到的就是显而易见的做法。假设我有一个邻接列表,我循环到列表的每个元素并计算重复次数,我也跳过了双重计数
  • 如果没有更多关于图表定义的信息,没有人会给你一个好的答案。图是一组顶点和边 G = (V, E),但没有任何与之相关的几何概念。图形是否嵌入格子中?如果是的话是什么类型(正方形,三角形,其他?)。
  • 该图以邻接列表的形式给出。意思是,这是一个二维数组,其中每个 (i,J) 表示两个顶点之间是否有边。
  • 还假设图是无向且简单的

标签: graph adjacency-list


【解决方案1】:

我认为我们可以为此使用 BFS。

主要思想是能够判断两个节点之间是否存在两条或多条路径,所以为此,我们可以使用一个集合,看看与一个Node的相邻列表对应的相邻节点是否已经在集合中。

这使用 O(n) 额外空间,但具有 O(n) 时间复杂度。

boolean bfs(int start){

 Queue<Integer> q = new Queue<Integer>();       // get a Queue
 boolean[] mark = new boolean[num_of_vertices]; 
 mark[start] = true;                            // put 1st node into Queue
 q.add(start); 
 while(!q.isEmpty()){
    int current = q.remove();
    HashSet<Integer> set = new HashSet<Integer>(); /* use a hashset for 
                                    storing nodes of current adj. list*/ 
    ArrayList<Integer> adjacentlist= graph.get(current);   // get adj. list 
    for(int x : adjacentlist){
        if(set.contains(x){  // if it already had a edge current-->x
          return true;       // then we have our parallel edge
        }
        else set.add(x);     // if not then we have a new edge 

        if(!marked[x]){      // normal bfs routine
            mark[x]=true;
            q.add(x);
        }
    }
 }
}// assumed graph has ArrayList<ArrayList<Integer>> representation    
 // undirected 

【讨论】:

    【解决方案2】:

    假设图中的顶点是整数0 .. |V|

    如果您的图是有向图,则图中的边表示为(i, j)

    这允许您生成任何边缘到整数(哈希函数)的唯一映射,该映射可以在 O(1) 中找到。

    h(i, j) = i * |V| + j 
    

    您可以在平均 O(1) 时间内在哈希表中插入/查找元组 (i, j)。对于邻接列表中的|E| 边,这意味着总运行时间将为 O(|E|) 或与邻接列表中的边数成线性关系。

    这个的python实现可能看起来像这样:

    def identify_parallel_edges(adj_list):
        # O(n) list of edges to counts
        # The Python implementation of tuple hashing implements a more sophisticated
        # version of the approach described above, but is still O(1)
        edges = {}
        for edge in adj_list:
            if edge not in edges:
                edges[edge] = 0
            edges[edge] += 1
    
        # O(n) filter non-parallel edges
        res = []
        for edge, count in edges.iteritems():
            if count > 1:
                res.append(edge)
        return res
    
    edges = [(1,0),(2,1),(1,0),(3,4)]
    print identify_parallel_edges(edges)
    

    【讨论】:

    • 我不确定您所说的 (i, j) = (min(i,j), max(i,j)) 是什么意思。我正在处理的图表是无向的
    • 我正在处理的数据结构还有数组(邻接表或矩阵)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-30
    • 1970-01-01
    • 2023-03-27
    • 1970-01-01
    • 2021-03-01
    • 1970-01-01
    • 2021-05-13
    相关资源
    最近更新 更多