Directed graph and undirected graph - Java - java

I'm implementing some algorithms to teach myself about graphs and how to work with them. What would you recommend is the best way to do that in Java?
I just wanted to ask u if u can give just a short help with a short very simply class definition for directed graph and weighted directed graph?
I looked over the web but i do not want an implementation of it, just a short definition of the classes....what u think is the best data structure to use ? Adjacent Lists?
For an undirected Graph i defined it as follow:
public interface Graph {
Collection vertices(); // returns a collection of all the
// Vertex objects in the graph
Collection edges(); // returns a collection of all the
// Edge objects in the graph
Collection incidentEdges(Vertex v); // returns a collection of
// Edges incident to v
boolean isAdjacent(Vertex v, Vertex w); // return true if v and
} // w are adjacent
public class Vertex {
public boolean visited; // initially false for all vertices
}
public class Edge {
Vertex v1, v2; // undirected edge
Vertex opposite(Vertex v); // given a vertex return the one
} // at the other end of this edge

Here is a simple implementation (this should be good enough for many basic use cases):
public class Graph {
public List<Node> nodes = new ArrayList<Node>();
}
public class Node{
public List<Node> neighbors = new ArrayList<Node>();
//here you can add stuff like "public boolean visited;", if your algorithm requires it
}
(This is just an example - there are tons of ways to implement a graph structure).

The data structure to use depends on the purpose of your code... Lists usually do quite well, but if the graph is highly connected (most of the nodes are connected to most of the nodes), then a list is cumbersome, and a matrix of some kind is usually to be preferred.
For example, to use a matrix, keep a vector of nodes, then use a 2-dimensional vector of integers to reference the nodes.
Also, for making a lightweight class, you don't have to declare a class for nodes: you can provide functions for adding nodes and edges, and you can identify such elements with integers.
Having Node or Edge classes may be suitable if you plan to subclass them (for example, could be useful when doing a GUI which display a graph), but if you need the graph for some algorithms, identifying nodes/edges with integers is faster and simpler.

Related

Labels for vertices using Jung library

I started to use the Jung library for my visualization of a graph. Main problem currently is that I don't know how to set labels/metadata for my vertices. Depending on a specific attribute of a vertex, I would like to color the vertices differently. The object of class Node contains an additional Integer-value, I would like to add as an additional attribute (by getGroup()) for the vertices. The following code only visualizes the getId()-String of each node.
Any recommendation?
This is my following code in the main class:
Graph<String,Double> g = new SparseGraph<String,Double>();
List<Link> linkList = new ArrayList<Link>();
List<Node> nodeList = new ArrayList<Node>();
linkList = f.getLinks();
nodeList = f.getNodes();
for(Node nodeElement:nodeList){
g.addVertex(nodeElement.getId());
}
for(Link linkElement:linkList){
g.addEdge(linkElement.getValue(), linkElement.getSource(), linkElement.getTarget());
}
VisualizationImageServer vs =
new VisualizationImageServer(
new SpringLayout(g), new Dimension(500, 500));
vs.getRenderContext().setVertexLabelTransformer(new ToStringLabeller() {
public String transform(Object v) {
return Integer.toString(((Node)v).getGroup());
}
});
JFrame frame = new JFrame("");
frame.getContentPane().add(vs);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
You didn't specify which version of JUNG you're using, but you've got the right general idea: call setVertexLabelTransformer() with a function that converts nodes to the string that you want to render.
That said, there are a few issues with your code as written and I'm not sure I understand how you're getting the reported behavior with the code as quoted above.
(0) I don't understand why you're adding the node ID as the vertex, rather than just the Node. Are the endpoints of your Links node IDs or Nodes?
In any event, if you don't add the Node, then it's not clear from your code as written how you expect the vertex Group to be available.
(1) The vertices of the graph are node IDs, not Nodes, but you're casting the vertex object passed to transform() to a Node. I would expect this to throw a ClassCastException.
(2) Even supposing that your vertices were actually Node objects,
I'm surprised that you're reporting that the vertex ID (rather than the Group) is what's showing up on the label, because the only thing that you're asking for in the vertex label is the Group; I wouldn't expect the ID to be showing up at all.
That said, if the vertices are Node objects, and you want multiple elements to show up, it's pretty easy; just provide a function that does what you want on the Node object.
* If that function is toString(), then you can use ToStringLabeller (and that should actually be the default, so you shouldn't even need to specify it); more on that below.
* If that function is (say) getLabel(), then this should work (in Java 8):
// either of these should work
setVertexLabelTransformer(Node::getLabel())
setVertexLabelTransformer(v -> v.getLabel())
or you can do the anonymous inner class thing if you're not using Java 8.
If you don't want your vertices to be Node objects, then you'll need to provide a way of mapping vertex objects (node IDs) to nodes, such as a Map<String, Node>, and then supply that map to the function that converts vertices to labels:
setVertexLabelTransformer(v -> labelToNode.get(v).getLabel())
Note: ToStringLabeller() shouldn't generally have its transform() method overridden; it just specifies that you want to use the toString() of the object itself as the label.
// These two are equivalent
setVertexLabelTransformer(v -> v.toString())
setVertexLabelTransformer(new ToStringLabeller())
(Needless to say, ToStringLabeller() predates Java 8. :) )

Is this a proper implementation of a Graph for DFS, BFS

I'm learning about search algorithms BFS and DFS. I plan to implement both but before I do that, I need to implement my graph structure. Here's my idea:
A graph of connecting cities: Each city is represented by a Node.
Our graph will simply be an ArrayList of Nodes added as they're created, and each Node will have a list of it's neighbors, and a parent which will let us know where we came from (for path retrieval). I haven't coded anything up yet, I wanted to get some feedback on my ideas before spending the time writing up something that won't work. Here's some pseudocode-ish, code. One potential problem I can see is how we're going to deal with Nodes that we can get to from multiple places (multiple parents). If anyone has any suggestions on dealing with that, feel free to share.
public class Node{
String name;
Node parent;
ArrayList<Node> neighbors;
public addNeighbor(Node n);
public setParent(Node n);
public getNeighbors()
...
}
public static void main(String[] args){
ArrayList<Node> graph = new ArrayList<Node>();
//build node
Node node = new Node(String name);
//add neighbors
node.addNeighbor(neighbor1);
node.addNeighbor(neighbor2);
//set parent
node.setParent(parent1);
//add to graph
graph.add(node);
path = dfs(graph, startNode, goalNode);
System.out.print(path);
}
Edit: I know I could look online and find implementations of this pretty easily, but I'd prefer to come up with my own solutions.
Your implementation look good. It's the classic implentation of a graph structure (a node with a list of neighbors). Some points:
You can use backtracking to deal with multiples paths that reach the same node. If the dfs method have a recursive implementation, you need to avoid the recursive call if the Node has already a parent. But if the new path is better that the old one, then you discard the old parent, and set the new one.
Your implementation is a directional graph. In other words, you can build a graph that has a path from A to B, but has no path from B to A. I don't know if this is ok for you.
I recommend you encapsulate the building of the graph inside a wrapper, that build both paths automatically, whith a unique call to a method. That way, always you build bidirectional paths.
You can use a Set to store the neighbors. That way, there is no duplicates. Of course, you need to implements the "equals" method in the Node class.

should the adjacency information be stored in the graph object or in the vertex itself?

For purpose of the demonstrating the concept of adjacency list, I would assume that it is easy to represent the list as a list of lists and put the vertices as numbers and put them in an array where we can reference them by index directly in a graph. Once we get the index of a vertex, we can just get the respective list array.
However, for actual objects, where the vertex can't be just referenced by an array index, I would assume a separate vertex object would need to be created. In this case, my question is where should the edge information be implemented.
In OO based programming languages, such as java, I have see implementations of the adjacency list based graph implementation where the adjacency information is stored in the vertex object itself with a data member of some type of data structure, such as arrays, list, and etc. However, I have also seen people implement the adjacency edge information in the graph object itself by maintaining a list of edges.
Is it more of a personal preference as to where the edge information should be stored?
I think it depends on how you want the graph API to look like.
Suppose for example that the graph works with an arbitrary generic type representing a vertex. In this case, instead of defining a vertex wrapper for internal use (and managing adjacency in it), you can simply have an adjacency data structure as a member of the graph class:
public class Graph<V> {
private Map<V, Set<V>> adjacencies;
..
}
If on the other hand you do wish to expose a Vertex object together with its adjacencies (I don't find a good reason why), then you should be careful about the data consistency. The adjacency data must be read only for the caller (or defensively copied), otherwise the caller may alter an edge in such way that it's not symmetric anymore.
To conclude, the adjacency data maintained by the graph class seems a better option to me. It simplifies the API and the implementation, and it doesn't require special measures to protect the class invariants if you decide to expose the vertex object.

Which data structure to use for nodes in Java?

I want to create a class node, class Edge and class Graph. In class node, it must take some number as input to create nodes. Also, I want this class to have methods where I can change different attributes of the nodes. Also, it must contain a method to send and receive information from its adjacent nodes over Edge. These information receiving and sending methods should have provision to control information flow.
I am not sure which data structure to use for nodes to fulfill these requirements.
Create a class Node that has all the attributes that you want. Ex. If you want to create a Node for a binary Tree your Node class can be something like.
class Node
{
Node left;
Node right;
int info;
Node(int value)
{
this.info = value;
}
//Add more attributes or functionalities
}
This is one representation of how you can create a Node class. Depending upon your requirements the representation might change but the underlying concept remains the same.
Create your own class node.
A node is just an object. Give it some attributes (for your example you probably want weight and value).
public class Node{
private double weight;
private String value;
private ArrayList<Node> edges;
//setters and getters
}
Create a class Node which has a list of references to other Nodes (in a directed graph, this is especially usefull). An edge is not actually a "thing" to create - it's more like a connection.
The two most common ways to implement graphs are to use either an adjacency matrix or an adjacency list.
The matrix approach involves using a 2d array to determine if node i and node j are connected by asking if node[i][j] is true. Wasteful on space, but has constant time access.
Adjacency lists keep track of every adjacent node to the current node, which save on space but cost linear time in order to determine if a node is connected to it.
These articles explain it better:
Matrix
List

Representation of a graph in Java

Please how can represent a graph in Java ?
I have to apply an algorithm on a graph, the first instruction of the algorithm is to verify if the last vertices are dependent or not ?
after the construction of the graph in java , i shoud verify if the three last point are dependent or not, if they are dependent, the vertice which is the at the head of the arow is replaced by its previous, and verify if the three last point are dependent or not
etc.. until we find three vertice independants
Thank you.
You could stick to a Node class and either a Vertice class or a map <Node, Value> to get that information.
What about
public class Node {
private String description;
private Map<Node, Cost> vertices;
}
That pretty much sums up the basic structure for it. Now it can be iterated to build the paths and workout the information from it
You could also represent a graph as an adjacency matrix. This is especially good if your graph contains a lot of edges, compared to nodes.
To represent a graph in JAVA, you could as well use the ZEST API which has classes like GraphNode, GraphConnection that must be helpful to you.

Categories