예제 #1
0
        /// <summary>
        /// Sprawdza czy graf jest drzewem
        /// </summary>
        /// <param name="g">Graf</param>
        /// <returns>true jeśli graf jest drzewem</returns>

        //void writeG(Graph g)
        //{
        //    Console.WriteLine("--------------START ------------");

        //    for (int v = 0; v < g.VerticesCount; ++v)
        //    {
        //        foreach(Edge e in g.OutEdges(v))
        //        {
        //            if (e.From < e.To)
        //                Console.Write(" ({0},{1}) ", e.From, e.To);
        //        }
        //        Console.WriteLine();
        //    }
        //    Console.WriteLine("--------------END ------------");
        //}

        //public void pp(List<int> t)
        //{
        //    Console.WriteLine("CYKL ------------------------");
        //    foreach (int i in t)
        //    {
        //        Console.Write("{0} -> ", i);
        //    }
        //    Console.WriteLine("\n--------------------");
        //}

        //public void ppp(List<Edge> t)
        //{
        //    Console.WriteLine("CYKL ------------------------");
        //    foreach (Edge e in t)
        //    {
        //        Console.Write("({0},{1}) -> ", e.From, e.To);
        //    }
        //    Console.WriteLine("\n--------------------");
        //}

        public bool IsTree(Graph g)
        {
            if (g.Directed == true)
            {
                throw new ArgumentException();
            }

            int n  = g.VerticesCount;
            int cc = 0;

            GeneralSearchGraphExtender.GeneralSearchAll <EdgesStack>(g, null, null, null, out cc, null);
            if (cc == 1 && g.EdgesCount == n - 1)
            {
                return(true);                                  // drzewo musi miec V-1 krawedzi i miec 1 spojna skladowa
            }
            else
            {
                return(false);
            }
        }
예제 #2
0
        /// <summary>
        /// Wyznacza cykle fundamentalne grafu g względem drzewa t.
        /// Każdy cykl fundamentalny zawiera dokadnie jedną krawędź spoza t.
        /// </summary>
        /// <param name="g">Graf</param>
        /// <param name="t">Drzewo rozpinające grafu g</param>
        /// <returns>Tablica cykli fundamentalnych</returns>
        /// <remarks>W przypadku braku cykli zwracać pustą (0-elementową) tablicę, a nie null</remarks>
        public Edge[][] FindFundamentalCycles(Graph g, Graph t)
        {
            if (g == null || t == null)
            {
                throw new ArgumentException();
            }
            if (IsTree(t) == false)
            {
                throw new ArgumentException();
            }
            if (g.Directed == true)
            {
                throw new ArgumentException();
            }
            if (true == IsTree(g))
            {
                return(new Edge[0][]);
            }
            int n = g.VerticesCount;

            bool[] visitedV = new bool[n];
            for (int i = 0; i < n; ++i) // do sprawdzenia czy drzewo t rozpina g
            {
                visitedV[i] = false;
            }

            List <int> p = new List <int>();

            Edge[][]            arr;// = new Edge[n][];
            int[]               V    = new int[t.VerticesCount];
            List <Edge>         le   = new List <Edge>();
            List <List <Edge> > list = new List <List <Edge> >();

            for (int i = 0; i < t.VerticesCount; ++i)
            {
                V[i] = i;
            }
            if (false == GeneralSearchGraphExtender.GeneralSearchFrom <EdgesStack>(t, 0,
                                                                                   delegate(int u)
            {
                visitedV[u] = true;
                return(true);
            }, null
                                                                                   ,
                                                                                   delegate(Edge e)
            {
                if (double.IsNaN(g.GetEdgeWeight(e.From, e.To)))
                {
                    return(false);
                }
                else
                {
                    return(true);
                }
            }, null

                                                                                   ))
            {
                throw new ArgumentException();
            }
            for (int i = 0; i < n; ++i)
            {
                if (visitedV[i] == false)
                {
                    throw new ArgumentException();                       // t nie rozpina g
                }
            }

            bool[] nr = new bool[n];
            for (int i = 0; i < n; ++i)
            {
                nr[i] = false;
            }
            Graph gg = g.Clone();


            for (int v = 0; v < n; ++v)
            {
                foreach (Edge e in gg.OutEdges(v))
                {
                    if (e.From < e.To && double.IsNaN(t.GetEdgeWeight(e.From, e.To)))
                    {
                        bool[]      nrr     = new bool[n];
                        bool[]      visited = new bool[n];
                        List <Edge> tmp     = new List <Edge>();
                        for (int i = 0; i < n; ++i)
                        {
                            nrr[i]     = false;
                            visited[i] = false;
                        }
                        bool search = true;

                        GeneralSearchGraphExtender.GeneralSearchFrom <EdgesStack>(t, e.To,
                                                                                  delegate(int u)
                        {
                            if (!search)
                            {
                                return(true);            //true;
                            }
                            visited[u] = true;
                            if (u == v)
                            {
                                nrr[u] = true;

                                search = false;
                                return(true);
                            }
                            else
                            {
                                return(true);
                            }
                        }, delegate(int w)
                        {
                            if (visited[w] == true)
                            {
                                foreach (Edge e1 in t.OutEdges(w))
                                {
                                    if (nrr[e1.To] == true)
                                    {
                                        tmp.Add(new Edge(e1.To, w));
                                        nrr[w] = true;

                                        break;
                                    }
                                }
                            }
                            return(true);
                        }, null, null

                                                                                  );
                        tmp.Add(new Edge(e.To, e.From));
                        list.Add(tmp);
                    }
                }
            }
            arr = list.Select(a => a.ToArray()).ToArray();

            return(arr);
        }
예제 #3
0
        /// <summary>
        /// Dodaje 2 cykle fundamentalne
        /// </summary>
        /// <param name="c1">Pierwszy cykl</param>
        /// <param name="c2">Drugi cykl</param>
        /// <returns>null, jeśli wynikiem nie jest cykl i suma cykli, jeśli wynik jest cyklem</returns>
        public Edge[] AddFundamentalCycles(Edge[] c1, Edge[] c2)
        {
            int        max   = -1;
            List <int> vList = new List <int>();

            foreach (Edge e1 in c1)
            {
                if (e1.From > max)
                {
                    max = e1.From;
                }
                if (e1.To > max)
                {
                    max = e1.To;
                }
            }

            foreach (Edge e1 in c2)
            {
                if (e1.From > max)
                {
                    max = e1.From;
                }
                if (e1.To > max)
                {
                    max = e1.To;
                }
            }
            bool[] b1 = new bool[max + 1];
            bool[] b2 = new bool[max + 1];

            foreach (Edge e1 in c1)
            {
                if (e1.From > max)
                {
                    max = e1.From;
                }
                if (e1.To > max)
                {
                    max = e1.To;
                }
            }

            var G = new AdjacencyListsGraph <HashTableAdjacencyList>(false, max + 1);
            int n = G.VerticesCount;

            bool[] edgeVisited = new bool[G.EdgesCount];
            bool[] vVisited    = new bool[n];
            for (int j = 0; j < edgeVisited.Length; ++j)
            {
                edgeVisited[j] = false;
            }
            List <Edge> newCycle = new List <Edge>();
            int         vtmp     = -1;

            foreach (Edge e1 in c1)
            {
                if (!c2.Contains(e1) && !c2.Contains(new Edge(e1.To, e1.From)))
                {
                    G.AddEdge(e1);
                    vVisited[e1.From] = true;
                    vVisited[e1.To]   = true;
                    vtmp = e1.From;
                }
            }
            foreach (Edge e1 in c2)
            {
                if (!c1.Contains(e1) && !c1.Contains(new Edge(e1.To, e1.From)))
                {
                    G.AddEdge(e1);
                    vVisited[e1.From] = true;
                    vVisited[e1.To]   = true;
                    vtmp = e1.From;
                }
            }

            bool[] vChecked = new bool[n];

            for (int j = 0; j < n; ++j)
            {
                vChecked[j] = false;
            }
            if (G.EdgesCount < 3)
            {
                return(null);
            }
            List <Edge> edgeList        = new List <Edge>();
            bool        repeatedVertice = GeneralSearchGraphExtender.GeneralSearchFrom <EdgesStack>(G, vtmp,
                                                                                                    delegate(int u)
            {
                if (G.OutEdges(u).Count() != 2)
                {
                    return(false);
                }
                vChecked[u] = true;
                return(true);
            }, delegate(int w)
            {
                return(true);
            },
                                                                                                    delegate(Edge e)
            {
                if (!edgeList.Contains(new Edge(e.To, e.From)))               //(e.From < e.To)
                {
                    edgeList.Add(e);
                }
                return(true);
            }
                                                                                                    , null);

            if (repeatedVertice == false)
            {
                return(null);
            }

            for (int j = 0; j < n; ++j)
            {
                if (vChecked[j] != vVisited[j])
                {
                    return(null);
                }
            }
            return(edgeList.ToArray());
        }