-1

I would be thankful if someone could help me with this Task.

Task: Implements a class Graph (directed and weighted), without using the standard Graph-classes of java.

Doesn't matter using adjacencyList or adjMatrix

My Code

import java.util.*;

public class Graph {

    static class Edge {

        char vA;
        char vB;
        double weight;

        Edge(char a, char b, double weight) {
            vA = a;
            vB = b;
            this.weight = weight;
        }

        void setWeight(double w) {
            weight = w;
        }

        double getWeight() {
            return weight;
        }
    }

    private Map<Character, LinkedList<Character>> edges = new HashMap<>();

    void addNode(char node) {
        if (!edges.containsKey(node)) {
            edges.put(node, new LinkedList<Character>());
        }
    }

    public void addEdge(char a, char b, double weight) {

        Edge e = new Edge(a, b, weight);
        a = e.vA;
        b = e.vB;
        e.setWeight(weight);

        edges.get(a).add(b);

    }

    void printNodes() {
        System.out.println(edges.keySet());

    }

    void printEdges() {
        System.out.println(edges.values());

    }

    void dfs() {
        //TODO
    }

    void dijkstra(char startNodeID){
    }


    public static void main(String... args) {
        Graph graph = new Graph();
        graph.addNode('A');
        graph.addNode('B');
        graph.addNode('C');
        graph.addNode('D');
        graph.addNode('E');
        graph.addEdge('A', 'B', 2);
        graph.addEdge('A', 'C', 3);
        graph.addEdge('B', 'D', 6);
        graph.addEdge('C', 'D', 8);
        graph.addEdge('C', 'E', 9);

        graph.printEdges();
        graph.printNodes();

    }

}

Questions:

How Can I add Edges to the LinkedList inside the hashMap?

What is wrong with my method addEdges?

How is it possible to print the Edges?

VisionTrek
  • 13
  • 3
  • Hi @VisionTrek, I understand that you have some problem, but please make others able to help you by adding some specific question about your problem to this post. Also could you describe what is the problem that you have with this code? – Kamil Jun 23 '18 at 19:13
  • Sorry @Kamil, here are some questions:How Can I add Edges to the LinkedList inside the hashMap? What is wrong with my method addEdges? How is it possible to print the Edges? – VisionTrek Jun 23 '18 at 19:58

2 Answers2

0

How Can I add Edges to the LinkedList inside the hashMap

If you want a LinkedList that contains edges define it as LinkedList<Edge> instead of LinkedList<Character>:

 private Map<Character, LinkedList<Edge>> edges = new HashMap<>();

and implement changes needed, including in addEdge :

edges.get(a).add(e);  //need to add it to b as well ? 

How is it possible to print the Edges?

Iterate over the map, get each LinkedList and print it:

void printNodes() {
    for(char node : edges.keySet()) {
        System.out.println(edges.get(node)); //requires implementing toString in Edge
    }
}

Wouldn't it serve you needs better to simply store all Edges in Set rather than Map<Character, LinkedList<Edge>> ?

c0der
  • 18,467
  • 6
  • 33
  • 65
  • Thanks for your answer! :) The first point is clear and how can I put the Edges as value of a Linkedlist into the HashMap? .... Second point, do I really need b as well, in a directed graph? I thought the Nodes are just connected in one way.... The Iteration is fine, thank you!!! :)) – VisionTrek Jun 24 '18 at 10:51
  • " do I really need b as well" - not necessarily, but if you go from b to a you need to find the relevant edge. – c0der Jun 24 '18 at 11:42
0

$1: To add Edges - see full example bellow.

$2: You are not storing the weight and the created 'Edge'-object:

public void addEdge(char a, char b, double weight) {
    Edge e = new Edge(a, b, weight); // 1. creating the Edge
    a = e.vA;            // 2. assigning the 'edge.vA'-value to 'a' ... why?
    b = e.vB;            // 3. same here with 'b'
    e.setWeight(weight); // 4. weight was already set when creating object on line 1
    edges.get(a).add(b); // 5. here you add the node 'b' to the list... what about the weight?
    // 6. now you exit the method without storing the created edge 'e'
}

$3: printEdges() works 'fine' - it's printing the values for each node in the HashMap. The output is:

[[B, C], [D], [D, E], [], []]

which reads:

  • for 'A' the connected edges are: [B and C]
  • for 'B' the connected edges is : [D]
  • for 'C' the connected edges are: [D and E]
  • for 'D' the connected edges are: []
  • for 'E' the connected edges are: []

Example to store weights and display edges:

import java.util.*;

public class Graph {

    static class Edge {

        final char vA;
        final char vB;
        final double weight;

        Edge(char a, char b, double weight) {
            this.vA = a;
            this.vB = b;
            this.weight = weight;
        }

        @Override
        // compare if 2 edges are equal
        public boolean equals(Object obj) {
            if (obj instanceof Edge) {
                Edge other = (Edge) obj;
                return this.vA == other.vA && this.vB == other.vB;
            }
            return false;
        }

        @Override
        // string representation of edge
        public String toString() {
            return String.format("[%s -> %s] : %.2f", vA, vB, weight);
        }
    }

    // The edges could be stored directly in an ArrayList, but I assume
    // you'll need to lookup all edges for a give node.
    private Map<Character, ArrayList<Edge>> edges = new HashMap<>();

    void addNode(char node) {
        if (!edges.containsKey(node)) {
            edges.put(node, new ArrayList<Edge>());
        }
    }

    public void addEdge(char a, char b, double weight) {
        Edge edge = new Edge(a, b, weight);
        if (!edges.get(a).contains(edge)) {
            edges.get(a).add(edge);
        } else {
            System.out.printf("Edge [%s -> %s] already exists!%n", edge.vA, edge.vB);
        }
    }

    void printNodes() {
        System.out.printf("%nNODES:%n%s%n", edges.keySet());
    }

    void printEdges() {
        System.out.println("EDGES:");
        edges.forEach((node, edgeList) -> {
            /**
             * Take each pair <key,value> (here <Character, ArrayList<Edge>) from 
             * the HashMap 'edges' as variables (node,edgeList), where
             * node: represents the current node, e.g.: A
             * edgeList: contains all the edges starting from 'node', e.g. [[A,B,2],[A,C,3]]
             */
            System.out.printf("%s:%n", node); // print current node
            edgeList.forEach(edge -> {
                // take each Edge from the current ArrayList<Edge> edgeList as 'edge' and ...
                System.out.printf("  %s%n", edge); // print the edge value using Edge::toString()
            });
        });
    }


    void printEdgesFor() {
        // get all pairs of the HashMap as Entry:
        for (Map.Entry<Character, ArrayList<Edge>> entry : edges.entrySet()) {
            Character node = entry.getKey(); // Entry-key = node
            ArrayList<Edge> edgeList = entry.getValue(); // Entry-value = edgeList
            System.out.printf("%s:%n", node);
            for (Edge edge: edgeList) {
                System.out.printf("  %s%n", edge.toString());
            }
        }
    }

    void printEdgesFor2() {
        // get all keys:
        for (Character node: edges.keySet()) { // get all nodes (key from HashMap 'edges')
            ArrayList<Edge> edgeList = edges.get(node); // get edgeList from HashMap 'edges' using key
            System.out.printf("%s:%n", node);
            for (Edge edge: edgeList) { // with each edge of the current edgeList..
                System.out.printf("  %s%n", edge.toString()); // print
            }
        }
    }
}
Lones NB
  • 49
  • 1
  • 4
  • Lones NB @ Thank you a lot for this explanation and example!!! $1: Adding Edges works and looks simple! I forgot about the contain method :/.... Is it necessary to compare 2 edges? $2: A thought in this way its possible to connect Nodes together including the weight if I use the method setWeight while I didnt know how to really deal with the list.... $3: What does the method forEach do? is it same like the foreach loop? is it right that you use lambda expression for anonym class?? I think a need a precisely explanation of the printEdges method :D ..thanks for your help :) – VisionTrek Jun 24 '18 at 11:12
  • instead of the forEach + lambda, you could use the for(...) loop - see updated example. [Javadoc forEach](https://docs.oracle.com/javase/8/docs/api/java/util/Map.html#forEach-java.util.function.BiConsumer-) and [examples](http://www.mkyong.com/java8/java-8-foreach-examples/) – Lones NB Jun 24 '18 at 14:20
  • awesome, I get it... How is it now possible to get the single Nodes in here with the deepthfirstSearch() method? – VisionTrek Jun 24 '18 at 16:05
  • I don't know exactly what the depthFirstSearch does, but you probably need to travel recursively through the nodes/eges. The outgoing edges of the current node can be retrieved using `edges.get(currentNode);`. – Lones NB Jun 25 '18 at 09:00
  • Hm ok and what about dijkstra(char startNodeID)? // giving all shortest ways of Parameter startNode – VisionTrek Jun 25 '18 at 09:20
  • maybe that helps: [dijkstra in java](http://www.baeldung.com/java-dijkstra) – Lones NB Jun 25 '18 at 09:25