/// <summary> /// Generate graph assuming a simple, undirected, and symmetric adjacency matrix /// </summary> /// <param name="adjacencyMatrix"></param> /// <returns></returns> public static Graph <int> GenerateGraphForAdjacencyMatrix(int[,] adjacencyMatrix) { int length = adjacencyMatrix.GetLength(0); var G = new Graph <int>(); int maxDegree = adjacencyMatrix.GetLength(0) - 1; for (int i = 0; i < length; i++) { G.AddNode(new GraphNode <int>(i, maxDegree)); } for (int i = 0; i < length; i++) { for (int j = 0; j < length; j++) { if (adjacencyMatrix[i, j] != 0) { G.TotalEdges++; IGraphNode <int> .AddMutualNeighbor(G.graphStructure[i], G.graphStructure[j]); } } } return(G); }
/// <summary> /// Generate a graph that matches the given degree sequence. Returns null if unable to actualize. /// </summary> /// <param name="degreeSequence"></param> /// <returns></returns> public static Graph <int> GenerateGraphForDegreeSequence(int[] degreeSequence) { var degreeSequenceList = new List <DegreeSequenceData>(degreeSequence.Length); int sumDegreeSequence = 0; var G = new Graph <int>(); for (int i = 0; i < degreeSequence.Length; i++) { var node = new GraphNode <int>(i); sumDegreeSequence += degreeSequence[i]; degreeSequenceList.Add(new DegreeSequenceData(node, degreeSequence[i])); G.AddNode(node); } //By handshaking lemma G.TotalEdges = sumDegreeSequence / 2; while (true) { //sort the degree sequence from greatest to least degree value //if multiple have the same degree value, pick the smaller vertex degreeSequenceList.Sort((x, y) => x == y ? x.Vertex.GetValue().CompareTo(y.Vertex.GetValue()) : y.DegreeValue.CompareTo(x.DegreeValue)); var maxDegreeData = degreeSequenceList[0]; //get the maximum degree vertex int maxDegree = maxDegreeData.DegreeValue; //if the maximum degree vertex is 0, we can terminate the algorithm if (maxDegree == 0) { return(G); } //assign its degree to 0, as we will assign edges to use up all its degrees degreeSequenceList[0].DegreeValue = 0; //not enough nodes remain to add neighbors to if (maxDegree >= degreeSequence.Length) { return(null); } //assign a connected to the next maxDegree vertices, and decrement each degree value by 1 for (int i = 1; i <= maxDegree; i++) { degreeSequenceList[i].DegreeValue--; //the neighbor node cannot be assigned, and therefore this degree sequence is not possible if (degreeSequenceList[i].DegreeValue < 0) { return(null); } //assign the vertex to each neighbor IGraphNode <int> .AddMutualNeighbor(maxDegreeData.Vertex, degreeSequenceList[i].Vertex); } } }
public static List <Graph <int> > GenerateNonIsomorphicGraphsOfOrder(int order) { var nonIsomGraphs = new List <Graph <int> >(); var emptyGraph = EmptyGraph(order); nonIsomGraphs.Add(emptyGraph); var generationQueue = new Queue <Graph <int> >(order ^ (order - 1)); generationQueue.Enqueue(emptyGraph); while (!generationQueue.IsEmpty()) { var front = generationQueue.Dequeue(); //try adding an edge... for (int i = 0; i < order; i++) { var node1 = front.graphStructure[i]; //find a missing edge for (int j = i + 1; j < order; j++) { var node2 = front.graphStructure[j]; if (!node1.GetNeighbors().Contains(node2)) { //spawn a clone var clone = front.Clone(); IGraphNode <int> .AddMutualNeighbor(clone.graphStructure[i], clone.graphStructure[j]); clone.TotalEdges++; bool graph_already_generated = false; foreach (var existing_graph in nonIsomGraphs) { if (Graph <int> .CheckGraphIsomorphism(clone, existing_graph)) { graph_already_generated = true; break; } } if (!graph_already_generated) { nonIsomGraphs.Add(clone); generationQueue.Enqueue(clone); } } } } } return(nonIsomGraphs); }
/// <summary> /// Creates a tree that has the given prufer encoding /// </summary> /// <param name="prufer"></param> /// <returns></returns> public static Tree <int> PruferEncodingToTree(int[] prufer) { var T = new Tree <int>(); var labeling = new Dictionary <int, GraphNode <int> >(); int n = 2 + prufer.Length; for (int i = 1; i <= n; i++) { var node = new GraphNode <int>(i); labeling.Add(i, node); T.AddNode(node); } //count the number of times a label appears in the encoding var pruferCount = new int[n]; foreach (var num in prufer) { //increase the number of times this label appears pruferCount[num - 1]++; } GraphNode <int> prufer_node = null; for (int prufer_index = 0; prufer_index < prufer.Length; prufer_index++) { for (int i = 1; i <= n; i++) { if (pruferCount[i - 1] == 0) { var leaf_node = labeling[i]; var neighbor_index = prufer[prufer_index]; prufer_node = labeling[neighbor_index]; IGraphNode <int> .AddMutualNeighbor(leaf_node, prufer_node); //assigned prufer for the current label pruferCount[i - 1] = -1; //decrement prufer count for neighbor label pruferCount[neighbor_index - 1]--; break; } } } //assign the last vertex to the last prufer node if (prufer_node != null) { IGraphNode <int> .AddMutualNeighbor(prufer_node, labeling[n]); } return(T); }
public static Graph <int> GenerateCompleteBipartiteGraph(int n1, int n2) { int totalNodes = n1 + n2; var G = new Graph <int>(totalNodes); for (int i = 0; i < totalNodes; i++) { G.AddNode(new GraphNode <int>(i)); } for (int i = 0; i < n1; i++) { for (int j = 0; j < n2; j++) { IGraphNode <int> .AddMutualNeighbor(G.graphStructure[i], G.graphStructure[n1 + j]); } } G.TotalEdges = n1 * n2; return(G); }
static void MakeGraph() { //Create the vertex set var A = new GraphNode <char>('A'); var B = new GraphNode <char>('B'); var C = new GraphNode <char>('C'); var D = new GraphNode <char>('D'); var E = new GraphNode <char>('E'); var F = new GraphNode <char>('F'); var G = new GraphNode <char>('G'); //Create the edge set A.AddNeighbor(D); B.AddNeighbor(G); C.AddNeighbor(E); D.AddNeighbor(B); D.AddNeighbor(C); F.AddNeighbor(E); G.AddNeighbor(A); G.AddNeighbor(F); IGraphNode <char> .AddMutualNeighbor(A, B); GraphNode <char>[] nodes = { A, B, C, D, E, F, G }; Graph <char> a_graph = new Graph <char>(nodes); foreach (var node1 in nodes) { foreach (var node2 in nodes) { if (node1 == node2) { continue; //this is not a very interesting case... } Console.WriteLine("Does a path exist from {0} to {1}?\n", node1.GetValue(), node2.GetValue()); var path = a_graph.RunDFS(node1, node2); //another way to call this function and run DFS //var path = a_graph.RunSearch(new Stack<NodePath<char>>(), node1, node2); if (path == null) { Console.WriteLine("\tNope :("); } else { Console.WriteLine("Using backtracking, the path is..."); //use a stack to figure out the order to take var reverse_backtracking = new Stack <NodePath <char> >(); while (path != null) { reverse_backtracking.Push(path); Console.Write("{0}", path.Node.GetValue()); path = path.Parent; if (path != null) { Console.Write(" <- "); } } Console.WriteLine("\n\tUsing a stack, the path in-order is "); while (!reverse_backtracking.IsEmpty()) { var top = reverse_backtracking.Pop(); Console.Write("{0}", top.Node.GetValue()); if (reverse_backtracking.Count > 0) { Console.Write(" -> "); } } Console.WriteLine("\n-------------------------------\n"); } } } }
private static void IsIsomorphic() { var a1 = new GraphNode <int>(1); var b1 = new GraphNode <int>(2); var c1 = new GraphNode <int>(3); var d1 = new GraphNode <int>(4); var e1 = new GraphNode <int>(5); var f1 = new GraphNode <int>(6); IGraphNode <int> .AddMutualNeighbor(a1, b1); IGraphNode <int> .AddMutualNeighbor(b1, c1); IGraphNode <int> .AddMutualNeighbor(b1, d1); IGraphNode <int> .AddMutualNeighbor(c1, d1); IGraphNode <int> .AddMutualNeighbor(d1, e1); IGraphNode <int> .AddMutualNeighbor(e1, f1); var G1 = new Graph <int>(a1, b1, c1, d1, e1, f1); var a2 = new GraphNode <int>(1); var b2 = new GraphNode <int>(2); var c2 = new GraphNode <int>(3); var d2 = new GraphNode <int>(4); var e2 = new GraphNode <int>(5); var f2 = new GraphNode <int>(6); IGraphNode <int> .AddMutualNeighbor(a2, b2); IGraphNode <int> .AddMutualNeighbor(b2, c2); IGraphNode <int> .AddMutualNeighbor(c2, d2); IGraphNode <int> .AddMutualNeighbor(c2, d2); IGraphNode <int> .AddMutualNeighbor(d2, e2); IGraphNode <int> .AddMutualNeighbor(e2, f2); var G2 = new Graph <int>(a2, b2, c2, d2, e2, f2); Graph <int> .CheckGraphIsomorphism(G1, G2); /* * var a1 = new GraphNode<int>(1); * var b1 = new GraphNode<int>(2); * var c1 = new GraphNode<int>(3); * var d1 = new GraphNode<int>(4); * var e1 = new GraphNode<int>(5); * var f1 = new GraphNode<int>(6); * * IGraphNode<int>.AddMutualNeighbor(a1, b1); * IGraphNode<int>.AddMutualNeighbor(b1, f1); * IGraphNode<int>.AddMutualNeighbor(b1, c1); * IGraphNode<int>.AddMutualNeighbor(c1, d1); * IGraphNode<int>.AddMutualNeighbor(d1, e1); * var G1 = new Graph<int>(a1, b1, c1, d1, e1, f1); * * var a2 = new GraphNode<int>(1); * var b2 = new GraphNode<int>(2); * var c2 = new GraphNode<int>(3); * var d2 = new GraphNode<int>(4); * var e2 = new GraphNode<int>(5); * var f2 = new GraphNode<int>(6); * * IGraphNode<int>.AddMutualNeighbor(a2, b2); * IGraphNode<int>.AddMutualNeighbor(b2, c2); * IGraphNode<int>.AddMutualNeighbor(b2, f2); * IGraphNode<int>.AddMutualNeighbor(c2, d2); * IGraphNode<int>.AddMutualNeighbor(d2, e2); * var G2 = new Graph<int>(f2, e2, d2, c2, b2, a2); * * Graph<int>.CheckGraphIsomorphism(G1, G2); * * Console.WriteLine("\n----------------------------------------------\n"); * * int numberVertices = 4; * * var g3_adj = new int[numberVertices, numberVertices]; * g3_adj[0, 1] = 1; * g3_adj[1, 2] = 1; * g3_adj[1, 3] = 1; * g3_adj[2, 3] = 1; * * var G3 = Graph<int>.GenerateGraphForAdjacencyMatrix(g3_adj, true); * * var g4_adj = new int[numberVertices, numberVertices]; * g4_adj[0, 1] = 1; * g4_adj[0, 2] = 1; * g4_adj[0, 3] = 1; * g4_adj[2, 3] = 1; * * var G4 = Graph<int>.GenerateGraphForAdjacencyMatrix(g4_adj, true); * * Graph<int>.CheckGraphIsomorphism(G3, G4); * * Console.WriteLine("\n----------------------------------------------\n"); * * numberVertices = 7; * * var g5_adj = new int[numberVertices, numberVertices]; * g5_adj[0, 1] = 1; * g5_adj[1, 2] = 1; * g5_adj[1, 3] = 1; * g5_adj[2, 3] = 1; * g5_adj[4, 5] = 1; * * var G5 = Graph<int>.GenerateGraphForAdjacencyMatrix(g5_adj, true); * * var g6_adj = new int[numberVertices, numberVertices]; * g6_adj[0, 1] = 1; * g6_adj[0, 2] = 1; * g6_adj[0, 3] = 1; * g6_adj[2, 3] = 1; * g6_adj[5, 6] = 1; * * var G6 = Graph<int>.GenerateGraphForAdjacencyMatrix(g6_adj, true); * * Graph<int>.CheckGraphIsomorphism(G5, G6); */ /* THIS IS AN ISOM TEST * var adj1 = new int[5, 5]; * adj1[0, 1] = 1; * adj1[0, 2] = 1; * adj1[3, 4] = 1; * * var adj2 = new int[5, 5]; * adj2[0, 1] = 1; * adj2[2, 3] = 1; * adj2[2, 4] = 1; * * var g1 = Graph<int>.GenerateGraphForAdjacencyMatrix(adj1); * var g2 = Graph<int>.GenerateGraphForAdjacencyMatrix(adj2); * * bool result = Graph<int>.CheckGraphIsomorphism(g1, g2); */ }