Java 图形:TreeSet没有添加所有边
我正在研究一个无向图问题。我有一个Java 图形:TreeSet没有添加所有边,java,graph,set,treeset,Java,Graph,Set,Treeset,我正在研究一个无向图问题。我有一个节点类,它包含节点名和列表。然后我有了Edge类,它包含节点开始,节点结束和权重。最后我有一个Graph类,它有一个实例变量Map 我想将所有不同的边添加到一个集合中,并根据它们的边权重按递增顺序排列。因此,我选择了TreeSet以独特的排序方式存储所有边。但是当我调用addAllEdges()时,它并没有添加所有边。该图有9个顶点和14条边。然而,树集只保存了其中的10个 代码结构: 图形: class Graph { private Map<
节点
类,它包含节点名
和列表
。然后我有了Edge
类,它包含节点开始
,节点结束
和权重
。最后我有一个Graph
类,它有一个实例变量Map
我想将所有不同的边添加到一个集合中,并根据它们的边权重按递增顺序排列。因此,我选择了TreeSet
以独特的排序方式存储所有边。但是当我调用addAllEdges()
时,它并没有添加所有边。该图有9个顶点和14条边。然而,树集只保存了其中的10个
代码结构:
图形:
class Graph {
private Map<String, Node> verticesMap = new HashMap<>();
public void addEdge(String src, String dest, int weight) {
Node srcNode = verticesMap.get(src) == null ? new Node(src) : verticesMap.get(src);
Node destNode = verticesMap.get(dest) == null ? new Node(dest) : verticesMap.get(dest);
Edge edge = new Edge(srcNode, destNode, weight);
srcNode.getEdgeList().add(edge);
verticesMap.put(src, srcNode);
verticesMap.put(dest, destNode);
}
public Set<Edge> addAllEdges() {
Set<Edge> allEdgesSet = new TreeSet<>(getComparatorBasedOnEdgeWeight());
for (Node node : verticesMap.values()) {
for (Edge edge : node.getEdgeList()) {
// sysout for debugging purpose only
if(allEdgesSet.add(edge)) {
System.out.println("Added edge: " + edge);
} else {
System.out.println("Did not add edge: " + edge);
}
}
}
return allEdgesSet;
}
private Comparator<Edge> getComparatorBasedOnEdgeWeight() {
return (e1, e2) -> Integer.compare(e1.getWeight(), e2.getWeight());
}
}
class Node {
private String name;
private List<Edge> edgeList;
public Node(String name) {
this.name = name;
edgeList = new ArrayList<>();
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Node other = (Node) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
@Override
public String toString() {
return name;
}
}
class Edge {
private Node src;
private Node dest;
private int weight;
public Edge(Node src, Node dest, int weight) {
this.src = src;
this.dest = dest;
this.weight = weight;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((dest == null) ? 0 : dest.hashCode());
result = prime * result + ((src == null) ? 0 : src.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Edge other = (Edge) obj;
if (dest == null) {
if (other.dest != null)
return false;
} else if (!dest.equals(other.dest))
return false;
if (src == null) {
if (other.src != null)
return false;
} else if (!src.equals(other.src))
return false;
return true;
}
@Override
public String toString() {
return src + "-->" + dest + "[" + weight + "]";
}
}
public class Test {
public static void main(String[] args) {
Graph graph = new Graph();
graph.addEdge("A", "B", 4);
graph.addEdge("B", "A", 4);
graph.addEdge("A", "I", 8);
graph.addEdge("I", "A", 8);
graph.addEdge("B", "C", 8);
graph.addEdge("C", "B", 8);
graph.addEdge("B", "I", 11);
graph.addEdge("I", "B", 11);
graph.addEdge("C", "H", 2);
graph.addEdge("H", "C", 2);
graph.addEdge("C", "D", 7);
graph.addEdge("D", "C", 7);
graph.addEdge("C", "F", 4);
graph.addEdge("F", "C", 4);
graph.addEdge("H", "I", 7);
graph.addEdge("I", "H", 7);
graph.addEdge("H", "G", 6);
graph.addEdge("G", "H", 6);
graph.addEdge("I", "G", 1);
graph.addEdge("G", "I", 1);
graph.addEdge("G", "F", 2);
graph.addEdge("F", "G", 2);
graph.addEdge("F", "D", 14);
graph.addEdge("D", "F", 14);
graph.addEdge("F", "E", 10);
graph.addEdge("E", "F", 10);
graph.addEdge("E", "D", 9);
graph.addEdge("D", "E", 9);
graph.addAllEdges();
}
}
测试:
class Graph {
private Map<String, Node> verticesMap = new HashMap<>();
public void addEdge(String src, String dest, int weight) {
Node srcNode = verticesMap.get(src) == null ? new Node(src) : verticesMap.get(src);
Node destNode = verticesMap.get(dest) == null ? new Node(dest) : verticesMap.get(dest);
Edge edge = new Edge(srcNode, destNode, weight);
srcNode.getEdgeList().add(edge);
verticesMap.put(src, srcNode);
verticesMap.put(dest, destNode);
}
public Set<Edge> addAllEdges() {
Set<Edge> allEdgesSet = new TreeSet<>(getComparatorBasedOnEdgeWeight());
for (Node node : verticesMap.values()) {
for (Edge edge : node.getEdgeList()) {
// sysout for debugging purpose only
if(allEdgesSet.add(edge)) {
System.out.println("Added edge: " + edge);
} else {
System.out.println("Did not add edge: " + edge);
}
}
}
return allEdgesSet;
}
private Comparator<Edge> getComparatorBasedOnEdgeWeight() {
return (e1, e2) -> Integer.compare(e1.getWeight(), e2.getWeight());
}
}
class Node {
private String name;
private List<Edge> edgeList;
public Node(String name) {
this.name = name;
edgeList = new ArrayList<>();
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Node other = (Node) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
@Override
public String toString() {
return name;
}
}
class Edge {
private Node src;
private Node dest;
private int weight;
public Edge(Node src, Node dest, int weight) {
this.src = src;
this.dest = dest;
this.weight = weight;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((dest == null) ? 0 : dest.hashCode());
result = prime * result + ((src == null) ? 0 : src.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Edge other = (Edge) obj;
if (dest == null) {
if (other.dest != null)
return false;
} else if (!dest.equals(other.dest))
return false;
if (src == null) {
if (other.src != null)
return false;
} else if (!src.equals(other.src))
return false;
return true;
}
@Override
public String toString() {
return src + "-->" + dest + "[" + weight + "]";
}
}
public class Test {
public static void main(String[] args) {
Graph graph = new Graph();
graph.addEdge("A", "B", 4);
graph.addEdge("B", "A", 4);
graph.addEdge("A", "I", 8);
graph.addEdge("I", "A", 8);
graph.addEdge("B", "C", 8);
graph.addEdge("C", "B", 8);
graph.addEdge("B", "I", 11);
graph.addEdge("I", "B", 11);
graph.addEdge("C", "H", 2);
graph.addEdge("H", "C", 2);
graph.addEdge("C", "D", 7);
graph.addEdge("D", "C", 7);
graph.addEdge("C", "F", 4);
graph.addEdge("F", "C", 4);
graph.addEdge("H", "I", 7);
graph.addEdge("I", "H", 7);
graph.addEdge("H", "G", 6);
graph.addEdge("G", "H", 6);
graph.addEdge("I", "G", 1);
graph.addEdge("G", "I", 1);
graph.addEdge("G", "F", 2);
graph.addEdge("F", "G", 2);
graph.addEdge("F", "D", 14);
graph.addEdge("D", "F", 14);
graph.addEdge("F", "E", 10);
graph.addEdge("E", "F", 10);
graph.addEdge("E", "D", 9);
graph.addEdge("D", "E", 9);
graph.addAllEdges();
}
}
输出:
Added edge: A-->B[4]
Added edge: A-->I[9]
Did not add edge: B-->A[4]
Added edge: B-->C[8]
Added edge: B-->I[11]
Did not add edge: C-->B[8]
Added edge: C-->H[2]
Added edge: C-->D[7]
Did not add edge: C-->F[4]
Did not add edge: D-->C[7]
Added edge: D-->F[14]
Did not add edge: D-->E[9]
Added edge: E-->F[10]
Did not add edge: E-->D[9]
Did not add edge: F-->C[4]
Did not add edge: F-->G[2]
Did not add edge: F-->D[14]
Did not add edge: F-->E[10]
Added edge: G-->H[6]
Added edge: G-->I[1]
Did not add edge: G-->F[2]
Did not add edge: H-->C[2]
Did not add edge: H-->I[7]
Did not add edge: H-->G[6]
Did not add edge: I-->A[9]
Did not add edge: I-->B[11]
Did not add edge: I-->H[7]
Did not add edge: I-->G[1]
Edges in the TreeSet:
[G-->I[1], C-->H[2], A-->B[4], G-->H[6], C-->D[7], B-->C[8], A-->I[9], E-->F[10], B-->I[11], D-->F[14]]
上面的输出显示它正在迭代28条边(14个顶点*2)。我无法理解为什么treeSet对那些甚至不在集合中的边返回false。
treeSet
使用比较器进行排序,但也用于对象的唯一性。它不使用equals()
或hashCode()
您的比较器也需要比较节点,例如使用节点名称
此外,如果图形是真实的,则不需要执行graph.addEdge(“A”,“B”,4)
和graph.addEdge(“B”,“A”,4)
,因为它们表示相同的无向边。无向边没有“源”或“目标”
我建议您更改Edge
,将src
和dest
重命名为node1
和node2
,并确保node1
的名称小于node2
的名称
这样,您的比较器
就可以简单地比较权重
、节点1.name
和节点2.name
:
private Comparator<Edge> getComparatorBasedOnEdgeWeight() {
return (e1, e2) -> {
int cmp = Integer.compare(e1.getWeight(), e2.getWeight());
if (cmp == 0)
cmp = e1.getNode1().getName().compareTo(e2.getNode1().getName());
if (cmp == 0)
cmp = e1.getNode2().getName().compareTo(e2.getNode2().getName());
return cmp;
};
}
private Comparator getcomparatorbasedonedgewight(){
返回(e1、e2)->{
int cmp=Integer.compare(e1.getWeight(),e2.getWeight());
如果(cmp==0)
cmp=e1.getNode1().getName().compareTo(e2.getNode1().getName());
如果(cmp==0)
cmp=e1.getNode2().getName().compareTo(e2.getNode2().getName());
返回cmp;
};
}
某些边的重量相同。它们在结果集中只出现一次。(详情可在其他答案中阅读)。您应该使用列表
(例如数组列表
),而不是树集
,然后使用集合对其排序。排序(列表,您的权重比较器)
@Marco13:非常感谢您的评论。我在读安德烈亚斯的答案,你是对的。我现在会尽力解决这个问题。非常感谢你的快速解决。现在让我来做吧。谢谢