示例#1
0
        public static List <RoadList <string> > GetCombinations(RoadList <string> toateDrumurile, int combinationLength)
        {
            List <RoadList <string> >     combinatii   = new List <RoadList <string> >();
            Combinations <Road <string> > combinations = new Combinations <Road <string> >(toateDrumurile, combinationLength);

            //string cformat = "Combinations of {{A B C D}} choose 2: size = {0}";
            //Console.WriteLine(String.Format(cformat, combinations.Count));

            foreach (IList <Road <string> > c in combinations)
            {
                RoadList <string> listadrumuri = new RoadList <string>();
                foreach (Road <string> road in c)
                {
                    listadrumuri.Add(road);
                }
                combinatii.Add(listadrumuri);
                //Console.WriteLine(String.Format("{{{0} {1}}}", c[0], c[1]));
            }

            /*foreach (RoadList<string> c in combinatii)
             * {
             *  foreach (var d in c)
             *  {
             *      Console.WriteLine(d);
             *  }
             *  Console.WriteLine("_______________________________");
             * }*/

            return(combinatii);
        }
示例#2
0
 public bool AddRoad(Road road)
 {
     if (RoadList.Count < RoadLimits)
     {
         RoadList.Add(road);
         NeighbourStationList.Add(road.Next(this), road);
         return(true);
     }
     else
     {
         return(false);
     }
 }
示例#3
0
        static void Main(string[] args)
        {
            //
            // >>>>>>>>>>>>>>>>>>>>>>>>>> CITESTE DIN FISIER <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
            //
            try
            {
                _drumuriInitiale = GetInitialRoads();

                int maximumDrumuri = nrOrase * (nrOrase - 1) / 2;

                Console.WriteLine("Unic? {0}", Utilities.AllUnique(_drumuriInitiale));
                Console.WriteLine("Numarul de drumuri existente = {0}", nrDrumuri);
                Console.WriteLine("Numarul maxim de drumuri posibile = {0}", maximumDrumuri);
                Console.WriteLine("Numarul de drumuri posibile = {0}", maximumDrumuri);
            }
            catch (Exception e)
            {
                Console.WriteLine($"Exception occured:\n{e.Message}");
            }

            //
            // >>>>>>>>>>>>>>>>>>>>>>>>>> INAINTE DE EXPLOZIE <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
            //
            int[,] adjMatrix = new int[nrOrase, nrOrase];
            Topologie        = new Dictionary <int, GraphNode <string> >();
            foreach (drum d in _drumuriInitiale)
            {
                adjMatrix[d.oras1 - 1, d.oras2 - 1] = 1;
                adjMatrix[d.oras2 - 1, d.oras1 - 1] = 1;
            }
            //PrintMatrix(adjMatrix);

            Graph <string> PlanetaInitiala = new Graph <string>();

            //adauga planetele in obiectul Graph
            for (int i = 0; i < nrOrase; i++)
            {
                PlanetaInitiala.AddNode((i + 1).ToString());
                //Topologie.Add(i+1,);
            }
            //adauga drumurile in obiectul Graph
            foreach (drum d in _drumuriInitiale)
            {
                GraphNode <string> from = (GraphNode <string>)PlanetaInitiala.Nodes.FindByValue(d.oras1.ToString());
                GraphNode <string> to   = (GraphNode <string>)PlanetaInitiala.Nodes.FindByValue(d.oras2.ToString());
                PlanetaInitiala.AddUndirectedEdge(from, to);
            }
            PlanetaInitiala.PrintGraph();
            //_________________________________ Avem PlanetaInitiala __________________________________________

            //
            // >>>>>>>>>>>>>>>>>>>>>>>>>> DUPA EXPLOZIE <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
            //
            // Creaza noaua matrice de drumuri dupa explozie
            int[,] NewAdjMatrix = new int[nrOrase, nrOrase];
            for (int i = 0; i < nrOrase; i++)
            {
                for (int j = 0; j < nrOrase; j++)
                {
                    if ((adjMatrix[i, j] == 0) & (i != j))
                    {
                        NewAdjMatrix[i, j] = 1;
                    }
                }
            }
            //Console.WriteLine("++++++++++++++++++++++++++++++++++++");
            //PrintMatrix(NewAdjMatrix);

            //Adauga orasele initiale
            Graph <string> PlanetaDupaExplozie_DinFisier = new Graph <string>();

            for (int i = 0; i < PlanetaInitiala.Count; i++)
            {
                PlanetaDupaExplozie_DinFisier.AddNode((i + 1).ToString());
            }
            //Adauga drumurile dupa explozie
            //Console.WriteLine("Dupa explozie au fost adaugate {0} drumuri.", GraphFromMatrix(out PlanetaDupaExplozie, NewAdjMatrix)); //au fost adaugate drumurile in Graf
            GraphFromMatrix(out PlanetaDupaExplozie_DinFisier, NewAdjMatrix);
            PlanetaDupaExplozie_DinFisier.PrintGraph();
            //____________________________________ Avem PlanetaDupaExplozie ______________________________________

            nrOraseDinFisier   = nrOrase;
            nrDrumuriDinFisier = nrDrumuri;

            bool EXISTA_SOLUTIE         = false;
            bool ADAUGA_ORAS_PUNCT_MORT = false;

            int numardewhileuri = 0;

            while (!EXISTA_SOLUTIE)
            {
                //
                // >>>>>>>>>>>>>>>>>>>>>>>>>> VERIFICA DACA MAI TREBUIE ADAUGATE ORASE <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
                //
                int NumarInitialDeOrase = nrOrase;
                int NumarNouDeOrase     = nrOrase;

                int maxDrumuri = nrOrase * (nrOrase - 1) / 2; // cand adaug un oras se schimba numarul maxim de drumuri posibile

                int    AddNewCities_01       = maxDrumuri % 2;
                double NumarDrumuriDeAdaugat = maxDrumuri / 2 - nrDrumuri; //nrDrumuri ramane acelasi citit din fisier, nu adaug niciun drum, doar orase

                // conditiile in care se adauga un oras nou: daca in declaratie sunt TRUE => se adauga un oras nou
                // se adauga un oras nou cand CEL PUTIN UNA din conditii este FALSE
                bool conditia1 = (AddNewCities_01 == 0);                                       // daca restul e zero = se pot genera atatea drumuri cate au fost, daca restul e 1, numarul total de drumuri e impar si trebuie sa adaug oras
                bool conditia2 = (NumarDrumuriDeAdaugat >= 0);                                 // daca NumarDrumuriDeAdaugat >= 0 inseamna ca dupa explozie raman destule drumuri ca sa pot reconstitui graful initial
                bool conditia3 = (NumarDrumuriDeAdaugat == Math.Floor(NumarDrumuriDeAdaugat)); // numarul de drumuri care trebuie adaugate trebuie sa fie intreg, duh!
                bool conditia4 = ADAUGA_ORAS_PUNCT_MORT;

                while ((!conditia1) | (!conditia2) | (!conditia3) | (ADAUGA_ORAS_PUNCT_MORT))
                {
                    NumarNouDeOrase++;
                    PlanetaInitiala.AddNode(NumarNouDeOrase.ToString());

                    maxDrumuri      = NumarNouDeOrase * (NumarNouDeOrase - 1) / 2;
                    AddNewCities_01 = maxDrumuri % 2;
                    if (AddNewCities_01 == 0)
                    {
                        conditia1 = true;
                    }
                    else
                    {
                        conditia1 = false;
                    }

                    NumarDrumuriDeAdaugat = maxDrumuri / 2 - nrDrumuri;
                    if (NumarDrumuriDeAdaugat >= 0)
                    {
                        conditia2 = true;
                    }
                    else
                    {
                        conditia2 = false;
                    }


                    if (NumarDrumuriDeAdaugat == Math.Floor(NumarDrumuriDeAdaugat))
                    {
                        conditia3 = true;
                    }
                    else
                    {
                        conditia3 = false;
                    }

                    if (ADAUGA_ORAS_PUNCT_MORT)
                    {
                        conditia4 = false;
                        ADAUGA_ORAS_PUNCT_MORT = false;
                    }
                }
                int NumarDeOraseAdaugate = NumarNouDeOrase - NumarInitialDeOrase;
                nrOrase = NumarNouDeOrase;

                Console.WriteLine("Au mai fost adaugate {0} orase.", NumarDeOraseAdaugate);
                Console.WriteLine("Numar total de orase dupa adaugare de orase = {0}", nrOrase);

                Graph <string> PlanetaDupaExplozie = new Graph <string>();
                if (NumarDeOraseAdaugate > 0) // Recalculeaza si PlanetaDupaExplozie daca s-au modificat numarul de orase
                {
                    PlanetaDupaExplozie = CreazaPlanetaDupaExplozie(PlanetaInitiala);
                }
                else
                {
                    PlanetaDupaExplozie = PlanetaDupaExplozie_DinFisier; // DUBIOUS ??????????? - copiere de referinta, eh plm
                }
                Console.WriteLine("++++++++++++++++++++++++++++++++++");
                PlanetaInitiala.PrintGraph();
                PlanetaDupaExplozie.PrintGraph();
                Console.WriteLine("++++++++++++++++++++++++++++++++++");
                //____________________________________ Avem numarul de orase corect ______________________________________


                //
                // >>>>>>>>>>>>>>>>>>>>>>>>>> VERIFICA DACA MAI TREBUIE ADAUGATE DRUMURI NOI <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
                //
                Console.WriteLine("Inaine de explozie au fost {0} drumuri.", PlanetaInitiala.EdgeCount);
                Console.WriteLine("Dupa explozie sunt {0} drumuri.", PlanetaDupaExplozie.EdgeCount);
                Console.WriteLine("Numar corect de drumuri? -> {0}", (PlanetaInitiala.EdgeCount + PlanetaDupaExplozie.EdgeCount) == (nrOrase * (nrOrase - 1) / 2));
                bool AddNewRoads = PlanetaInitiala.EdgeCount < PlanetaDupaExplozie.EdgeCount;
                Console.WriteLine("Mai este nevoie de noi drumuri? -> {0}", AddNewRoads);
                int nrOfRoadsToBeAdded = 0;
                if (AddNewRoads)
                {
                    nrOfRoadsToBeAdded = ((nrOrase * (nrOrase - 1) / 2 / 2) - PlanetaInitiala.EdgeCount);
                }
                Console.WriteLine("Mai este nevoie de {0} noi drumuri.", nrOfRoadsToBeAdded);

                //
                // parcurgere si adaugare laturi
                //

                if (AddNewRoads)
                {
                    //
                    // >>>>>>>>>>>>>>>>>>>>>>>>>> ADAUGARE DRUMURI NOI <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
                    //
                    RoadList <string>                DrumuriDeAdaugat           = new RoadList <string>();   //va contine toate drumurile suplimentare care pot fi adaugate, prin asta voi merge cu foreach
                    List <RoadList <string> >        CombinatiiDrumuriDeAdaugat = new List <RoadList <string> >();
                    Dictionary <Road <string>, bool> DrumVerificat = new Dictionary <Road <string>, bool>(); //dictionar in care tin seama daca am suplimentat sau nu un drum
                    Queue <Road <string> >           DrumQueue     = new Queue <Road <string> >();
                    foreach (GraphNode <string> nod in PlanetaInitiala.Nodes)                                // parcurge fiecare nod
                    {
                        // creaza laturile posibile a fi adaugate pentru fiecare nod
                        NodeList <string> diferenta = GetDiff(PlanetaInitiala.Nodes, nod.Neighbors);
                        diferenta.Remove(nod);
                        foreach (GraphNode <string> nodNou in diferenta)
                        {
                            DrumuriDeAdaugat.Add(new Road <string>(nod, nodNou));
                        }
                    }
                    Console.WriteLine(DrumuriDeAdaugat.ToString());
                    // creaza toate combinatiile posibile de drumuri care pot fi adaugate
                    CombinatiiDrumuriDeAdaugat = GetCombinations(DrumuriDeAdaugat, nrOfRoadsToBeAdded);

                    //PlanetaInitialaDeLucru.PrintGraph();

                    // in acest punct am :
                    //          - o planeta initiala pentru care stiu cate drumuri trebuie sa adaug ca sa o fac solutie posibila
                    //          - toate combinatiile posibile de drumuri care pot fi adaugate
                    // mai departe:
                    //          - incep sa adaug perechi de drumuri in planeta initiala
                    //          - recalculez planeta dupa explozie
                    //          - verific daca cele doua topologii pot fi rezolvate
                    bool GasitSolutie = false;
                    int  pasCurent    = 0;
                    while ((!GasitSolutie) & (pasCurent < CombinatiiDrumuriDeAdaugat.Count))
                    {
                        Graph <string> PlanetaInitiala_DeLucru = new Graph <string>(PlanetaInitiala.Nodes);              // copie de lucru
                                                                                                                         //PlanetaInitiala_DeLucru.PrintGraph();
                        Graph <string> PlanetaDupaExplozie_DeLucru = CreazaPlanetaDupaExplozie(PlanetaInitiala_DeLucru); //creeaza noua planeta dupa explozie
                        //PlanetaDupaExplozie_DeLucru.PrintGraph();
                        //Console.WriteLine(CombinatiiDrumuriDeAdaugat[pasCurent].ToString());
                        PlanetaInitiala_DeLucru.AddUndirectedEdge(CombinatiiDrumuriDeAdaugat[pasCurent]); // adauga drumuri noi in planeta initiala
                        Console.WriteLine("Se adauga urmatorul drum: {0}", CombinatiiDrumuriDeAdaugat[pasCurent].ToString());
                        Console.WriteLine("Planeta initala de lucru dupa adaugare noi drumuri:");
                        PlanetaInitiala_DeLucru.PrintGraph();
                        PlanetaDupaExplozie_DeLucru = CreazaPlanetaDupaExplozie(PlanetaInitiala_DeLucru); // creeaza planeta dupa explozie din graful modificat de dinainte de exlozie
                        Console.WriteLine("Planeta dupa explozie de lucru dupa adaugare noi drumuri:");
                        PlanetaDupaExplozie_DeLucru.PrintGraph();

                        if (PoateFiSol(PlanetaInitiala_DeLucru, PlanetaDupaExplozie_DeLucru))
                        {
                            GasitSolutie = true;
                            Console.WriteLine("-----gasita la pas {0}", pasCurent);
                            // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> incepe sa schimbi nodurile intre ele <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
                        }
                        else
                        {
                            foreach (Road <string> road in CombinatiiDrumuriDeAdaugat[pasCurent])
                            {
                                PlanetaInitiala.Nodes
                            }
                            pasCurent++;
                            Console.WriteLine("Graful propus nu poate fi solutie. Se trece la urmatorul pas si se adauga alt grup de drumuri.");
                        }
                        //PlanetaInitialaDeLucru.PrintGraph();
                    }

                    if ((GasitSolutie) & (pasCurent < CombinatiiDrumuriDeAdaugat.Count)) //a fost gasita o solutie -> scrie in fisier
                    {
                        Console.WriteLine("Solutia este:");
                        Console.WriteLine("");
                        Console.WriteLine(CombinatiiDrumuriDeAdaugat[pasCurent]);
                        EXISTA_SOLUTIE = true;
                    }

                    // daca nu a fost gasita o solutie dupa ce s-au adaugat toate combinatiile de drumuri posibilie
                    // inseamna ca graful asta nu poate avea nicio solutie si atunci trebuie sa ma intorc sa adaug oras
                    if ((!GasitSolutie) & (pasCurent >= CombinatiiDrumuriDeAdaugat.Count))
                    {
                        ADAUGA_ORAS_PUNCT_MORT = true; //adauga oras
                    }
                }
                else
                {
                    Console.WriteLine("Nu mai trebuie sa adaug niciun drum nou dar trebuie sa verific daca chestia asta poate fi solutie.");
                    bool PoateFiSolutie = PoateFiSol(PlanetaInitiala, PlanetaDupaExplozie);
                    Console.WriteLine("Poate fi solutie? => {0}", PoateFiSolutie);
                    if (PoateFiSolutie)
                    {
                        //a fost gasita o solutie -> scrie in fisier
                        EXISTA_SOLUTIE = true;
                    }
                    else
                    {
                        // daca asta nu este solutie trebuie sa ma intorc sa adaug un oras
                        ADAUGA_ORAS_PUNCT_MORT = true; // adauga oras
                    }
                }
                numardewhileuri++;
            }

            Console.ReadKey();
        }