简体   繁体   English

编写程序以为无向图标记连接的组件

[英]Write a program to label the connected components for an undirected graph

"Write a program to label the connected components for an undirected graph. In other words, all vertices of the first component are given the first component's label, all vertices of the second component are given the second Sec. 11.8 Projects 403 component's label, and so on. Your algorithm should work by defining any two vertices connected by an edge to be members of the same equivalence class. Once all of the edges have been processed, all vertices in a given equivalence class will be connected. Use the UNION/FIND implementation from Section 6.2 to implement equivalence classes." “编写一个程序来标记一个无向图的连接组件。换句话说,第一个组件的所有顶点都被赋予了第一个组件的标签,第二个组件的所有顶点都被赋予了第二节11.8项目403组件的标签,并且算法应通过将一条边连接的两个顶点定义为相同的等价类的成员来工作,一旦处理完所有边,将连接给定等价类中的所有顶点,请使用UNION / FIND 6.2节中的实现以实现等效类。”

/** General Tree class implementation for UNION/FIND */
class ParPtrTree {
    private Integer [] array; // Node array

    public ParPtrTree(int size) {
        array = new Integer[size]; // Create node array
        for (int i=0; i<size; i++)
            array[i] = null;
    }

    /** Determine if nodes are in different trees */
    public boolean differ(int a, int b) {
        Integer root1 = FIND(a); // Find root of node a
        Integer root2 = FIND(b); // Find root of node b
        return root1 != root2; // Compare roots
    }

    /** Merge two subtrees */
    public void UNION(int a, int b) {
        Integer root1 = FIND(a); // Find root of node a
        Integer root2 = FIND(b); // Find root of node b
        if (root1 != root2)
            array[root2] = root1; // Merge
    }

    /** @return The root of curr’s tree */
    public Integer FIND(Integer curr) {
        if (array[curr] == null)
            return curr; // At root
        while (array[curr] != null)
            curr = array[curr];
        return curr;
    }

Me and a few friends have been boggling our minds at how to approach this question, it isn't clear how the input is represented, we thought of implementing the general graph structures in Shaffer's Data Structures and Algorithm Analysis in Java, doing a breadth first search to organize it as a tree and reverse the pointers so it would fit into this data structure but I'm not sure that all of that random work really applies to what were trying to accomplish. 我和几个朋友一直在思考如何解决这个问题,目前尚不清楚输入是如何表示的,我们想到了在Java的Shaffer数据结构和算法分析中实现通用图形结构,首先要广度搜索以将其组织为树并反转指针,使其适合此数据结构,但我不确定所有随机工作是否真的适用于要完成的工作。

Has anyone ever had/done this problem before? 以前有没有人做过这个问题? Our professor didn't touch upon the question itself only had it listed in his homework. 我们的教授没有碰到这个问题,只是在作业中列出了这个问题。

Well, it looks like ParPtrTree implements an equivalence relation, although I can't figure out what Par and Ptr stand for. 好吧,看起来ParPtrTree实现了等价关系,尽管我不知道ParPtr代表什么。 UNION(a,b) adds the equivalence a === b to the relation, and thus anything that a and b were already equivalent to, now all become equivalent to each other. UNION(a,b)将等式a === b到该关系中,因此ab已经等效的任何东西现在都变得等效。

Without giving you too many details: I think that the assignment is suggesting simply that: for each node N in your graph, find all the nodes N i for which there's an edge from N to N i , and call UNION( N , N i ). 如果没有给你太多的细节:我认为分配提示仅仅是:在你的图中的每个节点N,发现所有的节点N I为其中有从NN I边缘,和电联(N,N I )。 Once that's done, the equivalence classes in the equivalence relation correspond to the connected components of the graph. 完成后,等价关系中的等价类对应于图的连接组件。 How you get those classes out of the ParPtrTree , I think you'll need to figure out, but consider using a HashSet to keep track of graph nodes you've already done something with. 如何从ParPtrTree获取这些类,我想您需要弄清楚,但是考虑使用HashSet来跟踪已经完成处理的图节点。 It would be best if you could add a method to ParPtrTree to get some information, because that method would be able to access array , but I don't know if you're allowed to do that. 最好将一个方法添加到ParPtrTree以获取一些信息,因为该方法将能够访问array ,但是我不知道是否允许这样做。

Also, as I mentioned in a comment, using != on Integer objects doesn't work, because it compares references and not values. 而且,正如我在评论中提到的那样,在Integer对象上使用!=不起作用,因为它比较引用而不是值。 However, you can't blindly change it to use equals because the references could be null. 但是,您不能盲目地将其更改为使用equals因为引用可能为null。 To see if two Integer objects are equal, you need something like 要查看两个Integer对象是否相等,您需要类似

a == b || (a != null && a.equals(b))

and to test if they're different, use ! 并测试它们是否不同,请使用! on the whole thing. 在整个事情上。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM