在Java中读取图形的邻接列表时,如何避免重复边?
我有一个.txt文件,它表示图形邻接列表。它有200行,如下所示:第一列表示顶点ID,每个对应的行是顶点与之共享一条边的其他顶点的列表在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
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);
}