Обновление графика JGraphT работает неправильно
Я пытаюсь реализовать своего рода технику суммирования графов, где я проверяю, есть ли у узла дочерние элементы или нет, если нет, то узел свернут в своего родителя. У меня есть 2 фрагмента кода, чтобы сделать это, но один из них не работает из-за ошибки в getEdgeSource, или, по крайней мере, я так думаю. При использовании 1-й реализации я могу пометить узлы, которые должны быть свернуты, после этого я снова зациклю все узлы в графе и добавлю их к их соответствующим родителям, а затем удалю их. Это работает отлично. Другой фрагмент кода должен сделать то же самое, но узлы не добавляются к родителю, они только удаляются. Вот фрагменты ниже: Сначала вот мой класс Node:
public class Node implements Serializable{
private static final long serialVersionUID = 1L;
public String nodeID;
public String timestamp;
public ArrayList<Node> children = new ArrayList<Node>();
public boolean tagged;
public boolean isRoot;
public Node(String a) {
nodeID = a;
}
public void addChild(Node a){
children.add(a);
}
public int getSize(){
return children.size();
}
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (!(obj instanceof Node)) {
return false;
}
Node other = (Node) obj;
return this.nodeID.equals(other.nodeID);
}
@Override
public int hashCode() {
return nodeID.hashCode();
}
}
(Рабочий код, но больше временной сложности):
public void oneLevelCollapse(DirectedGraph<Node, Edge> graph) {
graphCopy = (DirectedGraph<Node, Edge>) ((AbstractBaseGraph<Node, Edge>)graph).clone();
// iterate over every node and tag nodes to collapse
for (Node node : graphCopy.vertexSet()) {
// remove node if it has no children and only one parent
if (graphCopy.outDegreeOf(node) == 0 && graphCopy.inDegreeOf(node) == 1) {
node.tagged = true;
}
}
// iterate over every node again and collapse/delete
for (Node node : graphCopy.vertexSet()) {
for (Edge edge : graphCopy.outgoingEdgesOf(node)) {
Node child = graph.getEdgeTarget(edge);
if (child.tagged) {
node.addChild(child);
graph.removeVertex(child);
}
}
}
}
(Код, который должен работать, но не работает):
public void oneLevelCollapse(DirectedGraph<Node, Edge> graph) {
graphCopy = (DirectedGraph<Node, Edge>) ((AbstractBaseGraph<Node, Edge>)graph).clone();
// iterate over every node and tag nodes to collapse
for (Node node : graphCopy.vertexSet()) {
// remove node if it has no children and only one parent
if (graphCopy.outDegreeOf(node) == 0 && graphCopy.inDegreeOf(node) == 1) {
for (Edge edge : graphCopy.incomingEdgesOf(node)) {
graph.getEdgeSource(edge).addChild(node);
graph.removeVertex(node);
}
}
}
}
Граф не имеет самоконтроля, граф - это граф, который я изменяю, сохраняя при этом копию исходного графа, который представляет собой graphCopy.
1 ответ
Вы не предоставили код для своего класса Edge, но с DefaultEdge для класса edge, обе ваши реализации oneLevelCollapse(...) работают и пройдут этот модульный тест:
public void testJgraph() {
DirectedGraph<Node, DefaultEdge> graph = new SimpleDirectedGraph<>(DefaultEdge.class);
Node v1 = new Node("a");
Node v2 = new Node("b");
Node v3 = new Node("c");
graph.addVertex(v1);
graph.addVertex(v2);
graph.addVertex(v3);
graph.addEdge(v1, v2);
graph.addEdge(v2, v3);
oneLevelCollapse(graph);
assertEquals(2, graph.vertexSet().size());
assertTrue(graph.vertexSet().contains(v1));
assertTrue(graph.vertexSet().contains(v2));
assertEquals(v3, v2.children.get(0));
}