예제 #1
0
        /// <summary>
        /// Creates the join tree (or forest) of this hypergraph.
        /// If the graph is not acylic, it returns null.
        /// </summary>
        public DynamicForest GetJoinTree()
        {
            if (!IsAcyclic)
            {
                return(null);
            }

            DynamicForest forest = new DynamicForest(edgeList.Length);

            for (int eId = 0; eId < edgeList.Length; eId++)
            {
                forest.AddVertex();
            }

            for (int eId = 0; eId < edgeList.Length; eId++)
            {
                int gamma = ai.gamma[eId];

                if (gamma < 0)
                {
                    continue;
                }

                int parId = ai.R[gamma];
                forest.SetParent(eId, parId);
            }

            return(forest);
        }
예제 #2
0
        public RootedDrawing(DynamicForest forest)
        {
            if (forest == null)
            {
                throw new ArgumentNullException();
            }

            if (forest.Size == 0)
            {
                throw new ArgumentException();
            }

            this.forest = forest.Clone();

            PrepareTree();
        }
예제 #3
0
        /// <summary>
        /// Creates a copy of this forest.
        /// </summary>
        public DynamicForest Clone()
        {
            DynamicForest clone = new DynamicForest(Size);

            for (int i = 0; i < Size; i++)
            {
                clone.parentIds.Add(this.parentIds[i]);
                clone.vertexData.Add(this.vertexData[i]);
                clone.vertexList.Add(new List <int>(this.vertexList[i]));
            }

            foreach (int rId in this.rootIds)
            {
                clone.rootIds.Add(rId);
            }

            return(clone);
        }
        private void Preprocess()
        {
            hypertree.TransformToDual();

            // Generate and "draw" underlying tree.
            joinForest = hypertree.GetJoinTree();
            drawer     = new RootedDrawing(joinForest);
            data       = drawer.DrawRadial();

            // Computes colouring and max colour.
            colouring = hypertree.GetVertexColouring();
            hypertree.TransformToDual();

            maxCol = 0;
            for (int i = 0; i < colouring.Length; i++)
            {
                maxCol = Math.Max(colouring[i], maxCol);
            }

            // Counting sort to sort edges by their colour.
            edgeByColour = new int[colouring.Length];
            int[] colCounter = new int[maxCol + 1];

            for (int i = 0; i < colouring.Length; i++)
            {
                colCounter[colouring[i]]++;
            }

            for (int i = 1; i < colCounter.Length; i++)
            {
                colCounter[i] += colCounter[i - 1];
            }

            for (int i = colouring.Length - 1; i >= 0; i--)
            {
                int col = colouring[i];

                colCounter[col]--;
                int ind = colCounter[col];

                edgeByColour[ind] = i;
            }
            // End of counting sort.

            Array.Reverse(edgeByColour);

            edges = new List <int> [hypertree.NoOfEdges];
            for (int i = 0; i < edges.Length; i++)
            {
                edges[i] = new List <int>(Math.Max(hypertree.GetCardinality(i) * 2 - 2, 0));
            }

            // Use a DFS to determine the tree-edges of each hyperedge.
            // The search starts at the root.
            // Each time the search reaces a vertex v, it checks for all edges e containing v, if e is already activated.
            // If e is already activated, the tree-edge from v to its parent is part of the edge.

            bool[]      activeEdges = new bool[hypertree.NoOfEdges];
            Stack <int> verStack    = new Stack <int>();
            Stack <int> parStack    = new Stack <int>();

            int[] rootIds = joinForest.GetRoots();
            foreach (int rId in rootIds)
            {
                verStack.Push(rId);
                parStack.Push(-1);

                while (verStack.Count > 0)
                {
                    int vId = verStack.Pop();
                    int pId = parStack.Pop();

                    int[] edgeIds = hypertree.GetEdges(vId);

                    foreach (int eId in edgeIds)
                    {
                        if (activeEdges[eId])
                        {
                            edges[eId].Add(pId);
                            edges[eId].Add(vId);
                        }

                        activeEdges[eId] = true;
                    }

                    int[] neighs = joinForest[vId];

                    foreach (int nId in neighs)
                    {
                        if (nId == pId)
                        {
                            continue;
                        }

                        verStack.Push(nId);
                        parStack.Push(vId);
                    }
                }
            }

            // Now, data contains the radial coordinates of each vertex,
            // edges contains the list of tree-edges of each hyperedge,
            // colouring contains the colours of each hyperedge,
            // and edgeByColur has the edges ordered by their colour.
        }