我正在开发一个Java项目,它使用加权图来表示复杂的族树,但是我遇到了实现图的基本功能的问题。我有3个类,一个Graph
类,一个Node
类,它只是一个通用成员的包装,还有一个Tester
类。 Graph
类维护Node
个对象的列表,每个Node
保留与其相邻的节点列表和每个相邻节点的权重。我的问题是,当我创建一个使用配偶和子项的简单图表时,我无法将子项添加到节点和父项的配偶。但是,如果我可以将一个孩子添加到一个节点,然后将另一个孩子添加到配偶。例如,我可以这样做:
A --- B
| |
C D
但我不能这样做:
A --- B
|
C
由于不能这样做,我的意思是这个结构在我构建图形时反映出来,但是当我打印它时却没有。我很难过,因为我在代码中找不到任何问题,但我在下面列出了所有3个类。提前谢谢。
Graph.java
import java.util.HashSet;
public class Graph<T> {
public static double PARENT_TO_CHILD = 1.0;
public static double CHILD_TO_PARENT = -1.0;
public static double SPOUSE_TO_SPOUSE = -0.1;
private Node<T> root;
private HashSet<Node<T>> nodes;
/**
* Creates a graph with the given Node as the root.
*/
public Graph(T root){
this(new Node<T>(root));
}
public Graph(Node<T> root){
this.root = root;
nodes = new HashSet<>();
nodes.add(root);
}
/**
* Adds the given Node or T as a child of the second Node or T.
*
* @param child the Node or T to be added as a child
* @param parent the Node or T to add the child to
*/
public void addChild(T child, T parent){
addChild(new Node<T>(child), findNode(parent));
}
public void addChild(Node<T> child, Node<T> parent){
System.out.println("Adding " + child.toString() + " as a child of " + parent.toString());
addEdge(parent, child, Graph.PARENT_TO_CHILD);
}
/**
* Adds the given Node or T as a parent of the second Node or T.
*
* @param parent the Node or T to be added as a parent
* @param child the Node or T to add the parent to
*/
public void addParent(T parent, T child){
addParent(new Node<T>(parent), findNode(child));
}
public void addParent(Node<T> parent, Node<T> child){
System.out.println("Adding " + parent.toString() + " as a parent of " + child.toString());
addEdge(parent, child, Graph.PARENT_TO_CHILD);
}
/**
* Adds the given node as a spouse of the node with the given name.
*
* @param spouse the node to be added as a spouse
* @param node the Node to add the spouse to
*/
public void addSpouse(T spouse, T member){
addSpouse(new Node<T>(spouse), findNode(member));
}
public void addSpouse(Node<T> spouse, Node<T> node){
System.out.println("Adding " + spouse.toString() + " as a spouse of " + node.toString());
addEdge(node, spouse, Graph.SPOUSE_TO_SPOUSE);
}
/**
* Adds an edge between two Nodes with a weight in the Node objects.
*
* @param n1 the first vertex of the edge
* @param n2 the second vertex of the edge
* @param weight the weight from n1 to n2, inverted when linking the other way
*/
public void addEdge(Node<T> n1, Node<T> n2, double weight){
System.out.println("Adding an edge between " + n1.toString() + " and " + n2.toString() + " with weight " + weight);
n1.addEdge(n2, weight);
n2.addEdge(n1, -weight);
nodes.add(n1);
nodes.add(n2);
}
/**
* Returns a reference to the Node in the graph with the given member.
*
* @param member the member of the Node to find
* @return a reference to the found Node, or null if it was not found
*/
public Node<T> findNode(T member){
System.out.println("Looking for a Node with member: " + member.toString());
for (Node<T> node : nodes)
if (node.equalMembers(member))
return node;
System.out.println("Error: Could not find a node with member " + member.toString() + " in tree.");
return null;
}
/**
* Prints the adjacency lists of each node in the graph and their weight.
*/
public void print(){
System.out.println("\n==================================================");
for (Node<T> node : nodes){
System.out.println("Adjacency list of " + node.toString());
System.out.println(" " + node.adjacentNodesToString());
}
System.out.println("==================================================\n");
}
}
Node.java
import java.util.HashMap;
public class Node<T> {
private HashMap<Node<T>, Double> adjNodes;
private T member;
public Node(T member){
this.member = member;
adjNodes = new HashMap<>();
}
public void addEdge(Node<T> vertex, double weight){
System.out.println("Adding nodewise edge from " + toString() + " to " + vertex.toString() + " with weight " + weight);
adjNodes.put(vertex, weight);
System.out.println("Adjacent nodes of " + toString());
System.out.println(" " + adjacentNodesToString());
}
public double getWeight(Node<T> vertex){
return adjNodes.get(vertex);
}
public String adjacentNodesToString(){
if (adjNodes.size() == 0)
return "None";
String adj = "";
for (Node<T> adjNode : adjNodes.keySet())
adj += adjNode.toString() + " (weight: " + getWeight(adjNode) + ") ";
return adj.substring(0, adj.length()-4);
}
public boolean equalMembers(T otherMem){
return member.equals(otherMem);
}
@Override
public boolean equals(Object obj){
if (obj == null){
return false;
}
if (obj instanceof Node){
Node other = (Node) obj;
return member.equals(other.member);
}
return false;
}
@Override
public int hashCode(){
return member.hashCode();
}
@Override
public String toString(){
return member.toString() + " (" + hashCode() + ")" ;
}
}
Tester.java
public class Tester {
public static void main(String[] args){
graphTest();
}
public static void graphTest(){
// Create the graph with 1 as the root
Graph<Integer> g = new Graph<>(1);
g.print();
// Add 2 as a spouse of 1
g.addSpouse(2, 1);
g.print();
// Add 3 as a child of 1
g.addChild(3, 1);
g.print();
// Add 3 as a child of 2
g.addChild(3, 2); // If this was g.addChild(4, 2) it would be right
g.print();
}
}
输出
==================================================
Adjacency list of 1 (1)
None
==================================================
Looking for a Node with member: 1
Adding 2 (2) as a child of 1 (1)
Adding an edge between 1 (1) and 2 (2) with weight 1.0
Adding nodewise edge from 1 (1) to 2 (2) with weight 1.0
Adjacent nodes of 1 (1)
2 (2) (weight: 1.0)
Adding nodewise edge from 2 (2) to 1 (1) with weight -1.0
Adjacent nodes of 2 (2)
1 (1) (weight: -1.0)
==================================================
Adjacency list of 1 (1)
2 (2) (weight: 1.0)
Adjacency list of 2 (2)
1 (1) (weight: -1.0)
==================================================
Looking for a Node with member: 1
Adding 3 (3) as a child of 1 (1)
Adding an edge between 1 (1) and 3 (3) with weight 1.0
Adding nodewise edge from 1 (1) to 3 (3) with weight 1.0
Adjacent nodes of 1 (1)
2 (2) (weight: 1.0) 3 (3) (weight: 1.0)
Adding nodewise edge from 3 (3) to 1 (1) with weight -1.0
Adjacent nodes of 3 (3)
1 (1) (weight: -1.0)
==================================================
Adjacency list of 1 (1)
2 (2) (weight: 1.0) 3 (3) (weight: 1.0)
Adjacency list of 2 (2)
1 (1) (weight: -1.0)
Adjacency list of 3 (3)
1 (1) (weight: -1.0)
==================================================
Looking for a Node with member: 2
Adding 4 (4) as a child of 2 (2)
Adding an edge between 2 (2) and 4 (4) with weight 1.0
Adding nodewise edge from 2 (2) to 4 (4) with weight 1.0
Adjacent nodes of 2 (2)
1 (1) (weight: -1.0) 4 (4) (weight: 1.0)
Adding nodewise edge from 4 (4) to 2 (2) with weight -1.0
Adjacent nodes of 4 (4)
2 (2) (weight: -1.0)
==================================================
Adjacency list of 1 (1)
2 (2) (weight: 1.0) 3 (3) (weight: 1.0)
Adjacency list of 2 (2)
1 (1) (weight: -1.0) 4 (4) (weight: 1.0)
Adjacency list of 3 (3)
1 (1) (weight: -1.0)
Adjacency list of 4 (4)
2 (2) (weight: -1.0)
==================================================