We know that Graph is a data structure that consists of a finite set of vertices and edges(that connect the vertices with each other). A graph can be directed(edges having a direction) or undirected(edges with no directions). However, a Random graph is a graph data structure that is generated randomly. Random Graph models are widely used in studying complex networks, social networks, communication engineering and even in biology(in studying intracellular regulatory networks, activating and inhibiting connections in biological networks etc.).
In this article, we are going to discuss some algorithms to generate various types of random graphs.
Algorithm 1:
This algorithm is based on randomly choosing the number of vertices and edges and then randomly selecting two vertices to add an edge between them.
- Randomly choose the number of vertices and edges. Say, V be the number of vertices and E be the number of edges
- Check if the chosen number of edges E is compatible with the number of vertices. As for a chosen number of vertices V, there can be at-most (V*(V-1)/2) edges (Why V*(V – 1)/2 ? it is discussed later) in an undirected graph(if it does not contain self-loops).
- Run a for loop that runs for i = 0 to i < number of edges E, and during each iteration, randomly choose two vertices and create an edge between them.
- Print the created graph.
Below is the implementation of the above approach:
Java
import java.util.*;
import java.io.*;
public class GFGRandomGraph {
public int vertices;
public int edges;
final int MAX_LIMIT = 20 ;
Random random = new Random();
public List<List<Integer> > adjacencyList;
public GFGRandomGraph()
{
this .vertices = random.nextInt(MAX_LIMIT) + 1 ;
this .edges
= random.nextInt(computeMaxEdges(vertices)) + 1 ;
adjacencyList = new ArrayList<>(vertices);
for ( int i = 0 ; i < vertices; i++)
adjacencyList.add( new ArrayList<>());
for ( int i = 0 ; i < edges; i++) {
int v = random.nextInt(vertices);
int w = random.nextInt(vertices);
addEdge(v, w);
}
}
int computeMaxEdges( int numOfVertices)
{
return numOfVertices * ((numOfVertices - 1 ) / 2 );
}
void addEdge( int v, int w)
{
adjacencyList.get(v).add(w);
adjacencyList.get(w).add(v);
}
public static void main(String[] args)
{
GFGRandomGraph randomGraph = new GFGRandomGraph();
System.out.println( "The generated random graph :" );
for ( int i = 0 ;
i < randomGraph.adjacencyList.size(); i++) {
System.out.print(i + " -> { " );
List<Integer> list
= randomGraph.adjacencyList.get(i);
if (list.isEmpty())
System.out.print( " No adjacent vertices " );
else {
int size = list.size();
for ( int j = 0 ; j < size; j++) {
System.out.print(list.get(j));
if (j < size - 1 )
System.out.print( " , " );
}
}
System.out.println( "}" );
}
}
}
|
Output
The generated random graph :
0 -> { 7 , 10 , 7 , 2 , 8 , 7 , 1}
1 -> { 5 , 8 , 8 , 3 , 4 , 12 , 8 , 7 , 9 , 0 , 7}
2 -> { 2 , 2 , 7 , 0 , 2 , 2 , 11 , 12 , 3 , 9 , 4 , 2 , 2 , 12 , 5}
3 -> { 6 , 10 , 1 , 12 , 11 , 2 , 10 , 10 , 3 , 3 , 5}
4 -> { 1 , 8 , 6 , 8 , 8 , 2 , 5 , 11}
5 -> { 1 , 5 , 5 , 8 , 4 , 2 , 11 , 3}
6 -> { 3 , 9 , 12 , 4 , 10 , 8 , 9}
7 -> { 0 , 2 , 0 , 12 , 1 , 7 , 7 , 12 , 0 , 8 , 1}
8 -> { 5 , 1 , 1 , 0 , 1 , 4 , 4 , 4 , 6 , 11 , 7}
9 -> { 6 , 12 , 1 , 2 , 9 , 9 , 6 , 9 , 9}
10 -> { 3 , 0 , 3 , 3 , 10 , 10 , 6}
11 -> { 3 , 2 , 12 , 8 , 4 , 5}
12 -> { 7 , 3 , 9 , 1 , 6 , 11 , 2 , 7 , 2}
Each time you run the above program you will get a different undirected graph.
2. Remove the repetitions of the edges
Check if the edge already exists or not at run time. Using this approach complexity of the algorithm 1 will get increase but the optimization in the memory increases.
Below is the implementation of the above approach:
Java
import java.util.*;
import java.io.*;
public class GFGRandomGraph {
public int vertices;
public int edges;
final int MAX_LIMIT = 20 ;
Random random = new Random();
public List<List<Integer> > adjacencyList;
public GFGRandomGraph()
{
this .vertices = random.nextInt(MAX_LIMIT) + 1 ;
this .edges
= random.nextInt(computeMaxEdges(vertices)) + 1 ;
adjacencyList = new ArrayList<>(vertices);
for ( int i = 0 ; i < vertices; i++)
adjacencyList.add( new ArrayList<>());
for ( int i = 0 ; i < edges; i++) {
int v = random.nextInt(vertices);
int w = random.nextInt(vertices);
if (adjacencyList.get(v).contains(w)) {
i = i - 1 ;
continue ;
}
addEdge(v, w);
}
}
int computeMaxEdges( int numOfVertices)
{
return numOfVertices * ((numOfVertices - 1 ) / 2 );
}
void addEdge( int v, int w)
{
adjacencyList.get(v).add(w);
if (v != w)
adjacencyList.get(w).add(v);
}
public static void main(String[] args)
{
GFGRandomGraph randomGraph = new GFGRandomGraph();
System.out.println( "The generated random graph :" );
for ( int i = 0 ;
i < randomGraph.adjacencyList.size(); i++) {
System.out.print(i + " -> { " );
List<Integer> list
= randomGraph.adjacencyList.get(i);
if (list.isEmpty())
System.out.print( " No adjacent vertices " );
else {
int size = list.size();
for ( int j = 0 ; j < size; j++) {
System.out.print(list.get(j));
if (j < size - 1 )
System.out.print( " , " );
}
}
System.out.println( "}" );
}
}
}
|
Output
The generated random graph :
0 -> { 7 , 0 , 9 , 16 , 8 , 3 , 14 , 17 , 10 , 1 , 6 , 11 , 5 , 4 , 12}
1 -> { 17 , 8 , 6 , 12 , 9 , 11 , 13 , 5 , 15 , 0 , 2 , 7 , 16 , 3}
2 -> { 11 , 16 , 9 , 8 , 6 , 13 , 17 , 4 , 2 , 14 , 1 , 7 , 10}
3 -> { 4 , 8 , 13 , 10 , 12 , 17 , 0 , 15 , 16 , 3 , 7 , 6 , 5 , 1}
4 -> { 3 , 17 , 5 , 15 , 16 , 8 , 2 , 7 , 13 , 6 , 9 , 4 , 11 , 14 , 12 , 0}
5 -> { 10 , 17 , 6 , 16 , 4 , 9 , 14 , 13 , 8 , 1 , 3 , 5 , 0 , 15 , 7}
6 -> { 5 , 2 , 8 , 1 , 15 , 16 , 12 , 14 , 4 , 6 , 3 , 0 , 17 , 10 , 7}
7 -> { 9 , 11 , 0 , 15 , 7 , 4 , 10 , 13 , 17 , 16 , 3 , 8 , 1 , 6 , 2 , 5 , 12}
8 -> { 16 , 3 , 2 , 1 , 17 , 6 , 13 , 0 , 15 , 4 , 14 , 5 , 7 , 12 , 9 , 11}
9 -> { 7 , 10 , 2 , 9 , 0 , 1 , 5 , 17 , 16 , 4 , 12 , 11 , 13 , 8}
10 -> { 11 , 5 , 9 , 3 , 12 , 7 , 13 , 10 , 16 , 14 , 17 , 0 , 15 , 6 , 2}
11 -> { 2 , 10 , 17 , 12 , 7 , 15 , 16 , 11 , 1 , 13 , 14 , 4 , 9 , 0 , 8}
12 -> { 12 , 11 , 3 , 1 , 6 , 10 , 16 , 15 , 8 , 9 , 4 , 13 , 0 , 7}
13 -> { 14 , 3 , 17 , 15 , 2 , 8 , 7 , 10 , 5 , 1 , 4 , 11 , 9 , 13 , 12}
14 -> { 13 , 5 , 2 , 8 , 6 , 0 , 10 , 11 , 4 , 17 , 15}
15 -> { 13 , 11 , 17 , 4 , 7 , 6 , 8 , 3 , 1 , 12 , 10 , 16 , 14 , 5}
16 -> { 2 , 8 , 5 , 0 , 4 , 6 , 11 , 12 , 9 , 3 , 10 , 7 , 17 , 15 , 1}
17 -> { 1 , 11 , 5 , 4 , 13 , 8 , 15 , 3 , 2 , 9 , 7 , 0 , 16 , 10 , 14 , 6}
Now the output undirected graph does not contain any multiple edges between the same vertices. Though the graph may contain self-loops(but now only one for each vertex). However, if you want to generate undirected graphs without self-loops, then you can add another condition to the above code
//Check if there is already an edge between v and w or v and w are equal
if((v == w ) || adjacencyList.get(v).contains(w)) {
//Reduce the value of i
//so that again v and w can be chosen
//for the same edge count
i = i - 1;
continue;
}
Now, no self-loops and multiple edges are allowed in the generated undirected graph.
Why for a given number of vertices V in an undirected graph, there can be at-most V*((V-1)/2) number of edges?
Suppose, there are V number of vertices in a directed graph. Now, if the graph doesn’t contain any self-loops and multiple edges, then each vertex can have (V-1) edges with other (V-1) vertices. So, V vertices can have at-most V*(V – 1) vertices. If the graph contains self-loops then the maximum possible number of edges is V2 (with no multiple edges). Because, each vertex can have an edge with itself also. So, for Undirected graphs, the maximum possible number of edges is V*(V – 1)/2 as the edges don’t have any directions.
Till now, we have created random undirected graphs, however, if you want to create random directed graphs, then we have to make some changes to the above implemented code —
- For a randomly chosen number of vertices V, the maximum number of possible edges is now V*(V – 1)(with no multiple edges and self-loops).
- For directed graphs with no self-loops, we need to check if the two vertices chosen randomly, are equal. If they are not, then only create an edge between them.
- For directed graphs with no multiple edges, we need to check if there is already an edge between the randomly chosen vertices. If no such edge exists, then only create an edge between them.
- When creating an edge between two vertices, we only need to add w to the adjacency list of v and not v to the adjacency list of w as this is a directed graph.
Here is the code that creates random directed graphs with no multiple edges and self-loops —
Java
import java.util.*;
import java.io.*;
public class GFGRandomGraph {
public int vertices;
public int edges;
final int MAX_LIMIT = 20 ;
Random random = new Random();
public List<List<Integer> > adjacencyList;
public GFGRandomGraph()
{
this .vertices = random.nextInt(MAX_LIMIT) + 1 ;
this .edges
= random.nextInt(computeMaxEdges(vertices)) + 1 ;
adjacencyList = new ArrayList<>(vertices);
for ( int i = 0 ; i < vertices; i++)
adjacencyList.add( new ArrayList<>());
for ( int i = 0 ; i < edges; i++) {
int v = random.nextInt(vertices);
int w = random.nextInt(vertices);
if ((v == w)
|| adjacencyList.get(v).contains(w)) {
i = i - 1 ;
continue ;
}
addEdge(v, w);
}
}
int computeMaxEdges( int numOfVertices)
{
return numOfVertices * (numOfVertices - 1 );
}
void addEdge( int v, int w)
{
adjacencyList.get(v).add(w);
}
public static void main(String[] args)
{
GFGRandomGraph randomGraph = new GFGRandomGraph();
System.out.println( "The generated random graph :" );
for ( int i = 0 ;
i < randomGraph.adjacencyList.size(); i++) {
System.out.print(i + " -> { " );
List<Integer> list
= randomGraph.adjacencyList.get(i);
if (list.isEmpty())
System.out.print( " No adjacent vertices " );
else {
int size = list.size();
for ( int j = 0 ; j < size; j++) {
System.out.print(list.get(j));
if (j < size - 1 )
System.out.print( " , " );
}
}
System.out.println( "}" );
}
}
}
|
Output
The generated random graph :
0 -> { 4 , 3 , 5 , 15 , 13}
1 -> { 2 , 6 , 9 , 7 , 12 , 4}
2 -> { 4 , 7 , 13 , 12 , 11 , 9}
3 -> { 5 , 2 , 15 , 10}
4 -> { 2 , 16 , 8 , 7}
5 -> { 7 , 16 , 10 , 0 , 9}
6 -> { 12 , 11 , 14 , 2 , 5 , 16}
7 -> { 8 , 11 , 12 , 3 , 16 , 10 , 13}
8 -> { 6 , 7 , 15 , 12 , 0 , 5 , 9 , 16}
9 -> { 3 , 4 , 16}
10 -> { 9 , 12 , 16 , 6}
11 -> { 10 , 8 , 15 , 9 , 12 , 13}
12 -> { 5 , 7 , 10 , 1}
13 -> { 16 , 2 , 10 , 3 , 1}
14 -> { 3 , 15 , 8 , 12 , 7 , 1}
15 -> { 9 , 2 , 1 , 14 , 8 , 4}
16 -> { 1 , 2 , 9 , 3 , 10 , 7}
The above output graph is a random directed graph with no self-loops and multiple edges.
The algorithm 1 is based on randomly choosing a number of vertices v and edges e and creating a graph containing v vertices and e edges. The second algorithm we are going to discuss is based on Erdos-Renyi G(v,p) Random Graph model.
Algorithm 2 (The Erdos-Renyi G(v,p) model) :
The Erdos-Renyi G(v,p) model (named after Paul Erdos and Alfred Renyi) which is considered one of the first to attempt to describe the random networks, is one of the most popular models to generate random graphs. This model generates a random graph containing v vertices and edges between any two vertices with probability p. p is the probability that there is an edge between any two vertices.
- Randomly choose a number of vertices and the probability p. The value of p is between 0.0 to 1.0.
- Iterate over each pair of vertices and generate a random number between 0.0 and 1.0. If the randomly chosen number is less than the probability p, then add an edge between the two vertices of the pair. The number of edges in the graph totally depends on the probability p.
- Print the graph.
Below is the implementation of the above approach:
Java
import java.util.*;
import java.io.*;
public class GFGRandomGraph {
public int vertices;
public float p;
final int MAX_LIMIT = 20 ;
Random random = new Random();
public List<List<Integer> > adjacencyList;
public GFGRandomGraph()
{
this .vertices = random.nextInt(MAX_LIMIT) + 1 ;
this .p = random.nextFloat();
System.out.println(
"The probability that there is an edge"
+ " between any two vertices is : " + p);
adjacencyList = new ArrayList<>(vertices);
for ( int i = 0 ; i < vertices; i++)
adjacencyList.add( new ArrayList<>());
for ( int i = 0 ; i < vertices; i++) {
for ( int j = 0 ; j < vertices; j++) {
float edgeProbability = random.nextFloat();
if (edgeProbability < p)
addEdge(i, j);
}
}
}
void addEdge( int v, int w)
{
adjacencyList.get(v).add(w);
}
public static void main(String[] args)
{
GFGRandomGraph randomGraph = new GFGRandomGraph();
System.out.println( "The generated random graph :" );
for ( int i = 0 ;
i < randomGraph.adjacencyList.size(); i++) {
System.out.print(i + " -> { " );
List<Integer> list
= randomGraph.adjacencyList.get(i);
if (list.isEmpty())
System.out.print( " No adjacent vertices " );
else {
int size = list.size();
for ( int j = 0 ; j < size; j++) {
System.out.print(list.get(j));
if (j < size - 1 )
System.out.print( " , " );
}
}
System.out.println( "}" );
}
}
}
|
Output
The probability that there is an edge between any two vertices is : 0.8065328
The generated random graph :
0 -> { 0 , 1 , 2 , 3 , 5 , 6 , 7 , 8 , 11 , 13 , 14 , 15 , 16 , 17}
1 -> { 0 , 2 , 3 , 5 , 6 , 7 , 8 , 9 , 10 , 12 , 14 , 15 , 16 , 17}
2 -> { 0 , 1 , 2 , 3 , 4 , 5 , 7 , 8 , 9 , 10 , 11 , 13 , 15 , 16 , 17}
3 -> { 0 , 1 , 2 , 3 , 4 , 5 , 6 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 , 16 , 17}
4 -> { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 , 16 , 17}
5 -> { 0 , 1 , 3 , 7 , 9 , 13 , 14 , 15 , 16 , 17}
6 -> { 1 , 2 , 3 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 , 16 , 17}
7 -> { 0 , 1 , 2 , 3 , 4 , 5 , 7 , 8 , 9 , 10 , 12 , 13 , 15 , 16 , 17}
8 -> { 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 , 16 , 17}
9 -> { 0 , 1 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 , 16 , 17}
10 -> { 0 , 1 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 , 17}
11 -> { 0 , 1 , 2 , 3 , 4 , 6 , 7 , 8 , 9 , 10 , 12 , 14 , 15 , 16 , 17}
12 -> { 0 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 11 , 12 , 13 , 14 , 15 , 16 , 17}
13 -> { 0 , 1 , 2 , 3 , 4 , 5 , 7 , 9 , 10 , 12 , 13 , 14 , 15 , 16 , 17}
14 -> { 1 , 2 , 3 , 4 , 6 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 , 17}
15 -> { 0 , 1 , 3 , 4 , 6 , 7 , 8 , 9 , 10 , 11 , 13 , 14 , 15 , 16}
16 -> { 0 , 1 , 2 , 3 , 5 , 6 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 , 16}
17 -> { 0 , 1 , 2 , 3 , 4 , 5 , 7 , 9 , 10 , 13 , 14 , 15 , 16}
The above program generates random directed graphs with self-loops.
Similar Reads
How to Generate a Random Undirected Graph for a Given Number of Edges in Java?
An undirected graph is graph, i.e, a set of objects (called vertices or nodes) that are connected together, where all the edges are bidirectional. An undirected graph is sometimes called an undirected network. In contrast, a graph where the edges point in a direction is called a directed graph. Exam
3 min read
How to Generate a Random Directed Acyclic Graph for a Given Number of Edges in Java?
A Directed Acyclic Graph is a directed graph with no directed cycles. In a directed graph, the edges are connected so that each edge only goes one way. A directed acyclic graph means that the graph is not cyclic, or that it is impossible to start at one point in the graph and traverse the entire gra
5 min read
How to Add Random Number to an Array in Java?
To generate an array of integers with random values the nextInt() method from the java.util.Random class is used. From the random number generator sequence, this method returns the next random integer value. Assigning a Random Value to an ArrayWe can assign random values to an array by two approache
2 min read
Java Program to Find a Good Feedback Edge Set in a Graph
Feedback edge set is a set of edges where F â E of a directed graph G, whose every cycle must contain at least one edge from F. In simple words, Feedback edge set is a set of edges whose removal from the graph makes the graph directed acyclic graph. Examples: Input: Output: Feedback Edge Set: ( 3 -
4 min read
Java Program to Find Independent Sets in a Graph using Graph Coloring
Independent sets are set of vertices or edges in which the pair of any two vertices or edges are not adjacent to each other. Assuming that Independent sets mean Independent sets of vertices, we have to find a set of such vertices in which any two pairs of the vertex are not adjacent to each other. U
13 min read
How to Get Random Elements from LinkedHashSet in Java?
LinkedHashSet is used to maintain the insertion order and for generating random elements from LinkedHashSet we will use Random Class to generate a random number between 0 and the LinkedHashSet size. That random number will act as the index of LinkedHashSet. We can get a random element in three ways:
3 min read
Java Program to Generate Random Hexadecimal Bytes
To generate Random Hexadecimal Bytes, first, a random byte can be generated in decimal form using Java.util.Random.nextInt() and then it can be converted to hexadecimal form using Integer.toHexString() method. 1. Java.util.Random.nextInt() The nextInt() method is used to obtain the next integer from
2 min read
How to Get Random Elements From the Vector in Java?
Vector in java is a part of Java's collections framework. Vector is a dynamic array of objects, i.e., the size of the vector can be modified as per the requirement. Vector implements the List interface. It also maintains the insertion order and the elements of the vector can be accessed using their
4 min read
Java Program to Implement the Linear Congruential Generator for Pseudo Random Number Generation
Linear Congruential Method is a class of Pseudo-Random Number Generator (PRNG) algorithms used for generating sequences of random-like numbers in a specific range. This method can be defined as: Xi+1 = aXi + c mod m where, X, is the sequence of pseudo-random numbers m, ( > 0) the modulus a, (0, m
3 min read
How to Implement an Array with Constant-Time Random Access in Java?
In Java, random access in arrays requires direct index-based addressing, it usually takes constant time, or O(1). Standard arrays in Java provide random access that is constant in time. Note: The term constant-time random access means accessing an element by index, it takes the same amount of time i
2 min read