Пример #1
0
        /// <summary>
        /// Wersja III i IV zadania
        /// Zwraca najkrótszy możliwy czas przejścia przez labirynt z użyciem co najwyżej k lasek dynamitu
        /// </summary>
        /// <param name="maze">labirynt</param>
        /// <param name="k">liczba dostępnych lasek dynamitu, dla wersji III k=1</param>
        /// <param name="path">zwracana ścieżka</param>
        /// <param name="t">czas zburzenia ściany</param>
        /// // pomysl: k+1 takich samych grafow(warstw) bez krawedzi X , a krawedzie X to takie "mosty" miedzy warstwami
        // ETAP 3 i 4
        public int FindShortestPathWithKDynamites(char[,] maze, int k, out string path, int t)
        {
            path = "";

            int X     = maze.GetLength(1);
            int Y     = maze.GetLength(0);
            int n     = X * Y; // liczba punktow w tablicy, dla ulatwienia w szukaniu numeru wierzcholka w innej warstwie grafu
            int start = -1;
            int end   = -1;
            AdjacencyListsGraph <AVLAdjacencyList> g = new AdjacencyListsGraph <AVLAdjacencyList>(true, (k + 1) * n);

            PathsInfo[] p = null;
            createGraph(maze, g, t, out start, out end, k, n);
            ShortestPathsGraphExtender.DijkstraShortestPaths(g, start, out p);
            int[] dist = new int[k + 1]; // tablica najlepszych drog dla uzycia dynamitow od 0 do k
            for (int i = 0; i <= k; ++i)
            {
                dist[i] = -1;
            }
            int min   = int.MaxValue;
            int index = 0;               // ilosc dynamitow zuzytych dla najlepszej drogi

            for (int i = 0; i <= k; ++i) // sprawdzenie dla kazdej ilosci uzytego dynamitu najlepszej drogi
            {
                int tmp = (int)p[end + i * n].Dist;
                if (!Double.IsNaN(p[end + i * n].Dist)) // jesli nie NaN to porownac z wartoscia najmniejsza
                {
                    dist[i] = tmp;
                    if (tmp < min) // jesli nowa wartosc lepsza to zapisac jako min
                    {
                        min   = tmp;
                        index = i;
                    }
                }
            }
            if (min == int.MaxValue)
            {
                return(-1); // jesli nie znaleziono sciezki to -1
            }
            else
            {
                if (X > 1)
                {
                    path = constructStringE34(PathsInfo.ConstructPath(start, end + index * n, p), X, n);
                }
                else // jesli kolejne wierzcholki grafu nie sa na tablicy po prawo/lewo, tylko gora/dol (bo wymiar 1xN czy Nx1 nie wiem)
                {
                    path = constructStringE341xN(PathsInfo.ConstructPath(start, end + index * n, p), X, n);
                }
                return(min);
            }
        }
Пример #2
0
        // ETAP 1 i 2
        public int FindShortestPath(char[,] maze, bool withDynamite, out string path, int t = 0)
        {
            path = "";
            int X = maze.GetLength(1);
            int Y = maze.GetLength(0);

            int start = -1;
            int end   = -1;
            AdjacencyListsGraph <AVLAdjacencyList> g = new AdjacencyListsGraph <AVLAdjacencyList>(true, X * Y);

            PathsInfo[] p = null;

            if (t == 0)
            {
                createGraph(maze, g, out start, out end);
            }
            else
            {
                createGraph(maze, g, t, out start, out end);
            }
            ShortestPathsGraphExtender.DijkstraShortestPaths(g, start, out p);
            int dist = (int)p[end].Dist;

            if (!Double.IsNaN(p[end].Dist))
            {
                if (X > 1)
                {
                    path = constructString(PathsInfo.ConstructPath(start, end, p));
                }
                else
                {
                    path = constructString1xN(PathsInfo.ConstructPath(start, end, p));
                }
                return(dist);
            }
            else
            {
                return(-1);
            }
        }
Пример #3
0
        /// <summary>
        /// Sprawdza możliwość przejazdu między dzielnicami-wielokątami district1 i district2,
        /// tzn. istnieją para ulic, pomiędzy którymi jest przejazd
        /// oraz fragment jednej ulicy należy do obszaru jednej z dzielnic i fragment drugiej należy do obszaru drugiej dzielnicy
        /// </summary>
        /// <returns>Informacja czy istnieje przejazd między dzielnicami</returns>
        // etap 4
        public bool CheckDistricts(Street[] streets, Point[] district1, Point[] district2, out List <int> path, out List <Point> intersections)
        {
            path          = new List <int>();
            intersections = new List <Point>();
            int   S  = streets.Length;
            int   n1 = district1.Length;
            int   n2 = district2.Length;
            Graph g  = new AdjacencyListsGraph <SimpleAdjacencyList>(false, S + 2); // 0..S-1 streets   S == district1, S + 1 == district2

            for (int i = 0; i < S; ++i)
            {
                // ulica wchodzi do district1
                for (int k = 0; k < n1; ++k)
                {
                    if (CheckIntersection(streets[i], new Street(district1[k % n1], district1[(k + 1) % n1])) != 0)
                    {
                        g.AddEdge(i, S);
                    }
                }

                // ulica wchodzi do district2
                for (int k = 0; k < n2; ++k)
                {
                    if (CheckIntersection(streets[i], new Street(district2[k % n2], district2[(k + 1) % n2])) != 0)
                    {
                        g.AddEdge(i, S + 1);
                    }
                }

                // ulica krzyzuje sie z kolejna ulica
                if (i != S - 1)
                {
                    for (int j = i + 1; j < S; ++j)
                    {
                        if (CheckIntersection(streets[i], streets[j]) != 0)
                        {
                            g.AddEdge(i, j);
                        }
                    }
                }
            }
            PathsInfo[] p = new PathsInfo[S + 2];
            ShortestPathsGraphExtender.DijkstraShortestPaths(g, S, out p);
            Edge[] e = PathsInfo.ConstructPath(S, S + 1, p);

            // jesli istnieje sciezka od S do S+1
            if (!Double.IsNaN(p[S + 1].Dist))
            {
                path = new List <int>();
                // pododawac kolejne pkty (bez S i bez S+1)
                for (int j = 0; j < e.Length - 1; ++j)
                {
                    path.Add(e[j].To);
                }

                intersections = new List <Point>();
                // przeciecia kolejnych ulic
                for (int j = 0; j < path.Count - 1; ++j)
                {
                    intersections.Add(GetIntersectionPoint(streets[path[j]], streets[path[j + 1]]));
                }
                return(true);
            }
            else
            {
                return(false);
            }
        }