Beispiel #1
0
        /// <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);
        }
Beispiel #2
0
        /// <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);
                }
            }
        }
Beispiel #3
0
        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);
        }
Beispiel #5
0
        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);
             */
        }