在java

时间:2018-01-21 03:40:38

标签: java graph weighted-graph

我正在开发一个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)
==================================================

0 个答案:

没有答案