I'm new to use graphs in Java, but I have implemented a code that finds the routes between two nodes using breadth first search algorithm and I need to show the output on a graph, can anyone help me in doing so .
For a beginner, I would recommend two popular graph representations:
Adjacency Matrix: https://en.wikipedia.org/wiki/Adjacency_matrix
Adjacency List: https://en.wikipedia.org/wiki/Adjacency_list
To understand and practice Breadth-first search/Depth-first search, use Adjacency Matrix because neighbors are easier to access in this data structure. It is as simple as a 2-dimension array:
int[][] adj = new int[10][20];
Example from Princeton University: http://algs4.cs.princeton.edu/41graph/AdjMatrixGraph.java.html
Related
I am trying to implement a directed weighted edge graph in Java using adjacency lists. It consists of an array with the size equal to the number of vertices, each entry of the array is a LinkedList of the successors of that each particular Vertex.
I want to add weight to each edge, I was thinking of doing this by adding a weight label to each successor Object in the LinkedList, furthermore I want to add other variables per Vertex for future use. If I want to do this, I would have to create a new Data structure for the vertices and a separate one as an adjacency lists. What would be an efficient design to combine both as a single Data structure?
You should represent your graph as a HashMap where key is label of vertices and value is vertex objects.
HashMap<String,Vertex> graph = new HashMap<String,Vertex>();
Vertex is a class encapsulating vertex attributes.There will be an attribute HashMap for adjacent vertices with weights.
HashMap<Vertex,Integer> adjListWithWeights = new HashMap<Vertex,Integer>();
You can add more functionality and attributes to your graph through Vertex class.
I have a List of n sorted Lists with m elements (Strings) each. Those elements originate from a List with a distinct order that I don't know. What I know is that all sublists maintain the element's global order. The lists are not disjoint. The union of the lists is a subset of the original list.
Now, I'm struggling to find an algorithm that would efficiently combine them back into a List (of Lists) with maximum sorting accuracy.
Is there a Solution out there for such a problem?
I am using Java, here is some sample code:
List<List<String>> elements = new ArrayList<>();
elements.add(Lists.newArrayList("A","D","F"));
elements.add(Lists.newArrayList("B","D","E"));
elements.add(Lists.newArrayList("A","B","G"));
elements.add(Lists.newArrayList("C","D","H"));
// the required method
List<List<String>> sorted = sortElements(elements);
/* expeced output:
* [["A"],["B"],["C"],["D"],["G","F","E","H"]]
*/
You are seeking for topological sorting.
Your initial lists represent directed graph arcs (A->D, D->F etc)
P.S.
Special kind of topological sort in order to explicitly divide nodes by levels is called in Russian literature "Demoucron algorithm", but I failed to find proper English description (found links to planar graph drawing articles)
Example of its work:
First of all, I'm dealing with graphs more than 1000 edges and I'm traversing adjacency lists, as well as vertices more than 100 times per second. Therefore, I really need an efficient implementation that fits my goals.
My vertices are integers and my edges are undirected, weighted.
I've seen this code.
However, it models the adjacency lists using edge objects. Which means I have to spend O(|adj|) of time when I'd like to get the adjacents of a vertex, where |adj| is the cardinality of its adjacents.
On the other hand, I'm considering to model my adjacency lists using Map<Integer, Double>[] adj.
By using this method, I would just use adj[v], v being the vertex, and get the adjacents of the vertex to iterate over.
The other method requires something like:
public Set<Integer> adj(int v)
{
Set<Integer> adjacents = new HashSet<>();
for(Edge e: adj[v])
adjacents.add(e.other(v));
return adjacents;
}
My goals are:
I want to sort a subset of vertices by their connectivities (number of adjacents) any time I want.
Also, I need to sort the adjacents of a vertex, by the weights of the edges that connect itself and its neighbors.
I want to do these without using so much space that slows down the operations. Should I consider using an adjacency matrix?
I've used th JGrapht for a library for a variety of my own graph representations. They have a weighted graph implementation here: http://jgrapht.org/javadoc/org/jgrapht/graph/SimpleWeightedGraph.html
That seems to handle a lot of what you are looking for, and I've used it to represent graphs with up to around 2000 vertices, and it handles reasonably well for my needs, though I don't remember my access rate.
I want to be able to generate random, undirected, and connected graphs in Java. In addition, I want to be able to control the maximum number of vertices in the graph. I am not sure what would be the best way to approach this problem, but here are a few I can think of:
(1) Generate a number between 0 and n and let that be the number of vertices. Then, somehow randomly link vertices together (maybe generate a random number per vertex and let that be the number of edges coming out of said vertex). Traverse the graph starting from an arbitrary vertex (say with Breadth-First-Search) and let our random graph G be all the visited nodes (this way, we make sure that G is connected).
(2) Generate a random square matrix (of 0's and 1's) with side length between 0 and n (somehow). This would be the adjacency matrix for our graph (the diagonal of the matrix should then either be all 1's or all 0's). Make a data structure from the graph and traverse the graph from any node to get a connected list of nodes and call that the graph G.
Any other way to generate a sufficiently random graph is welcomed. Note: I do not need a purely random graph, i.e., the graph you generate doesn't have to have any special mathematical properties (like uniformity of some sort). I simply need lots and lots of graphs for testing purposes of something else.
Here is the Java Node class I am using:
public class Node<T> {
T data;
ArrayList<Node> children= new ArrayList<Node>();
...}
Here is the Graph class I am using (you can tell why I am only interested in connected graphs at the moment):
public class Graph {
Node mainNode;
ArrayList<Node> V= new ArrayList<Node>();
public Graph(Node node){
mainNode= node;
}
...}
As an example, this is how I make graphs for testing purposes right now:
//The following makes a "kite" graph G (with "a" as the main node).
/* a-b
|/|
c-d
*/
Node<String> a= new Node("a");
Node<String> b= new Node("b");
Node<String> c= new Node("c");
Node<String> d= new Node("d");
a.addChild(b);
a.addChild(c);
b.addChild(a);
b.addChild(c);
b.addChild(d);
c.addChild(a);
c.addChild(b);
c.addChild(d);
d.addChild(c);
d.addChild(b);
Graph G1= new Graph(a);
Whatever you want to do with your graph, I guess its density is also an important parameter. Otherwise, you'd just generate a set of small cliques (complete graphs) using random sizes, and then connect them randomly.
If I'm correct, I'd advise you to use the Erdős-Rényi model: it's simple, not far from what you originally proposed, and allows you to control the graph density (so, basically: the number of links).
Here's a short description of this model:
Define a probability value p (the higher p and the denser the graph: 0=no link, 1=fully connected graph);
Create your n nodes (as objects, as an adjacency matrix, or anything that suits you);
Each pair of nodes is connected with a (independent) probability p. So, you have to decide of the existence of a link between them using this probability p. For example, I guess you could ranbdomly draw a value q between 0 and 1 and create the link iff q < p. Then do the same thing for each possible pair of nodes in the graph.
With this model, if your p is large enough, then it's highly probable your graph is connected (cf. the Wikipedia reference for details). In any case, if you have several components, you can also force its connectedness by creating links between nodes of distinct components. First, you have to identify each component by performing breadth-first searches (one for each component). Then, you select pairs of nodes in two distinct components, create a link between them and consider both components as merged. You repeat this process until you've got a single component remaining.
The only tricky part is ensuring that the final graph is connected. To do that, you can use a disjoint set data structure. Keep track of the number of components, initially n. Repeatedly pick pairs of random vertices u and v, adding the edge (u, v) to the graph and to the disjoint set structure, and decrementing the component count when the that structure tells you u and v belonged to different components. Stop when the component count reaches 1. (Note that using an adjacency matrix simplifies managing the case where the edge (u, v) is already present in the graph: in this case, adj[u][v] will be set to 1 a second time, which as desired has no effect.)
If you find this creates graphs that are too dense (or too sparse), then you can use another random number to add edges only k% of the time when the endpoints are already part of the same component (or when they are part of different components), for some k.
The following paper proposes an algorithm that uniformly samples connected random graphs with prescribed degree sequence, with an efficient implementation. It is available in several libraries, like Networkit or igraph.
Fast generation of random connected graphs with prescribed degrees.
Fabien Viger, Matthieu Latapy
Be careful when you make simulations on random graphs: if they are not sampled uniformly, then they may have hidden properties that impact simulations; alternatively, uniformly sampled graphs may be very different from the ones your code will meet in practice...
This is the code my friends and I have come up with so far after fiddling around. What we are trying to do is read in the adjacency matrix (input.txt), then create a directed graph out of it so we can search it using Depth-First Search. We want the output of our program to provide the order of visited nodes.
The java code:
http://pastebin.com/bAzBadxi
The input.txt file:
http://pastebin.com/r72J34uA
My question is, what do we initialize "n" to? (line 32 in the java code)
Any help will be appreciated.
Create a vertex object before you use it.
Vertex n; // before g.addVertex(n);
I am not validating your algorithm, just removing compiler error, if your algo is correct it should work fine
What you are trying to solve is a problem of topological sorting.
Topological sorting
In this case, it doesn't matter what n you initialize to, you can simply use the first vertex in the adjacency matrix as the start.
And adjacency matrix (which should be a square matrix) is a legit representation of a directed graph, you can use the matrix to search the graph directly.