在Java中读取图形的邻接列表时,如何避免重复边?

在Java中读取图形的邻接列表时,如何避免重复边?,java,graph,Java,Graph,我有一个.txt文件,它表示图形邻接列表。它有200行,如下所示:第一列表示顶点ID,每个对应的行是顶点与之共享一条边的其他顶点的列表 1 37 79 164 155 32 87 39 113 15 18 78 175 140 200 4 160 97 191 100 91 20 69 198 196 2 123 134 10 141 13 12 43 47 3 177 101 179 77 182 117 116 36 103 51 1

我有一个.txt文件,它表示图形邻接列表。它有200行,如下所示:第一列表示顶点ID,每个对应的行是顶点与之共享一条边的其他顶点的列表

1   37  79  164 155 32  87  39  113 15  18  78  175 140 200 4   160 97  191 100 91  20  69  198 196 
2   123 134 10  141 13  12  43  47  3   177 101 179 77  182 117 116 36  103 51  154 162 128 30  
3   48  123 134 109 41  17  159 49  136 16  130 141 29  176 2   190 66  153 157 70  114 65  173 104 194 54  
4   91  171 118 125 158 76  107 18  73  140 42  193 127 100 84  121 60  81  99  80  150 55  1   35  23  93  
5   193 156 102 118 175 39  124 119 19  99  160 75  20  112 37  23  145 135 146 73  35  
6   155 56  52  120 131 160 124 119 14  196 144 25  75  76  166 35  87  26  20  32  23  
7   156 185 178 79  27  52  144 107 78  22  71  26  31  15  56  76  112 39  8   113 93  
8   185 155 171 178 108 64  164 53  140 25  100 133 9   52  191 46  20  150 144 39  62  131 42  119 127 31  7   
9   91  155 8   160 107 132 195 26  20  133 39  76  100 78  122 127 38  156 191 196 115 
10  190 184 154 49  2   182 173 170 161 47  189 101 153 50  30  109 177 148 179 16  163 116 13  90  185 
11  123 134 163 41  12  28  130 13  101 83  77  109 114 21  82  88  74  24  94  48  33  
12  161 109 169 21  24  36  65  50  2   101 159 148 54  192 88  47  11  142 43  70  182 177 179 189 194 33  
13  161 141 157 44  83  90  181 41  2   176 10  29  116 134 182 170 165 173 190 159 47  82  111 142 72  154 110 21  103 130 11  33  138 152 
14  91  156 58  122 62  113 107 73  137 25  19  40  6   139 150 46  37  76  39  127 
15  149 58  68  52  39  67  121 191 1   45  100 18  118 174 40  85  196 122 42  193 119 139 26  127 145 135 57  38  7    
我试图将此文件读入我创建的一些Java类中,但我不确定如何避免读取重复的边缘。对于每个边,在.txt文件中有两个与之关联的数字。例如,在第8行中,有一个数字9表示顶点8和9共享的边。第9行有一个数字8,表示9和8共享的同一条边

我将这段代码与BufferedReader一起使用,使每一行成为一个数组,然后为每个非第一列顶点ID添加一条新边

 

    private static UndirectedGraph constructGraph(String filename) throws IOException {
           
     UndirectedGraph graph = new UndirectedGraph();
    
    //count # of lines in the .txt file and make that many vertices
            int numLines = countLines("/home/paris/Downloads/kargercut.txt");
    
            for (int i = 0; i<=numLines; i++) {
                graph.addVertex(i);
    
            }
            
    //BufferedReader to make each row in .txt file into a split string array, from which I can parse Integers
            BufferedReader br = new BufferedReader(new FileReader("/home/paris/Downloads/kargercut.txt"));
            String s;
            ArrayList<String> vtxIDArray = new ArrayList<>();
            String[] sArray;
            
            while ((s = br.readLine()) != null ) {
                sArray = s.split(" ");
    
                for (int i = 1; i <= sArray.length - 1; i++) {
                graph.addEdge(Integer.parseInt(sArray[0]), Integer.parseInt(sArray[i]));  /*addEdge takes two vertex ID's as arguments and creates an edge in memory in all three of the aforementioned locations: one in each Vertex object, and one in the entire graph's "edgeList" ArrayList. */      
            
    }
    
            }
            System.out.println(Arrays.toString(graph.getVertexIDs()));
            
            br.close();
    
            return graph;
        }

加法:

public void addEdge(Integer end1ID, Integer end2ID) {

        Vertex end1 = findVertex(end1ID);
        Vertex end2 = findVertex(end2ID);

        if ((end1 == null) || (end2 == null)) {
            throw new IllegalArgumentException("1 or 2 of the endpoints don't exist.");
        }
        if (end1 == end2) throw new IllegalArgumentException("No self-loops allowed");


        UndirectedEdge newEdge = new UndirectedEdge(end1, end2);
        edgeList.add(newEdge);
        end1.addEdge(newEdge);
        end2.addEdge(newEdge);

    }
现在,我程序中的一条边存储在Vertex类(其每个端点)和master edgeList类中。按照当前读取文件的方式,对于每一条边,我在内存中的这三个位置中的每一个都会有两倍的边。
我不知道该怎么办。

您要做的是在
addEdge()
方法中,检查图形中是否已经存在该边。您可能希望在
UndirectedGraph
类中实现一个名为
edgeExists(int vertex1,int vertex2)
的新函数,该函数返回一个bool,指示要在vertex1和vertex2之间添加的边是否已经存在

然后,每次要添加新边时都调用该函数。如果边还不存在,请添加它,否则不要添加


edgeExists
的一个简单实现可能只是检查vertex1对象在其邻接列表中是否包含vertex2。

要正确回答这个问题,需要查看您的
Edge
类以及
addEdge()的源代码
方法。唯一的问题是,这应该允许平行边,因此相同两个顶点之间有多条边。如果我实现edgeExists,它将阻止任何平行边的形成,即使是数据中可能正确的平行边。@Jackson如果允许平行边,应该有一种机制在邻接列表中标识它们。是伯爵吗?比如,如果有8->9,8->9,那么我们也应该期待9->8,9->8?还是别的?@Jackson啊,对不起。我不知道平行边是允许的。我脑子里不知道这个问题的答案,抱歉——我正在考虑一个涉及哈希表的解决方案,或者一些跟踪现有边的东西(比如边的运行计数器,在解析输入时遇到“定向”边时,可以添加或减去)
public void addEdge(Integer end1ID, Integer end2ID) {

        Vertex end1 = findVertex(end1ID);
        Vertex end2 = findVertex(end2ID);

        if ((end1 == null) || (end2 == null)) {
            throw new IllegalArgumentException("1 or 2 of the endpoints don't exist.");
        }
        if (end1 == end2) throw new IllegalArgumentException("No self-loops allowed");


        UndirectedEdge newEdge = new UndirectedEdge(end1, end2);
        edgeList.add(newEdge);
        end1.addEdge(newEdge);
        end2.addEdge(newEdge);

    }