Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Mapa, wspolrzedne, obliczanie sciezki
Forum PHP.pl > Forum > PHP > Pro > Archiwum Pro
Revan
Jo!
Mam taka mape, ktora jest podzielona na kwadraty:
Kod
|--1--|--2--|--3--|--4--|--5--|
1     |     |     |     |     |
|     |     |     |     |     |
|-----|-----|-----|-----|-----|
2     |     |     |     |     |
|     |     |     |     |     |
|-----|-----|-----|-----|-----|
3     |     |     |     |     |
|     |     |     |     |     |
|-----|-----|-----|-----|-----|
4     |     |     |     |     |
|     |     |     |     |     |
|-----|-----|-----|-----|-----|
5     |     |     |     |     |
|     |     |     |     |     |
|-----|-----|-----|-----|-----|

Teraz, zalozmy ze chce przejsc z kwadratu 2,2 (p) do 4,5 (k) z tym ze pola oznaczone x sa nie do przejscia. Tak jak tu:
Kod
|--1--|--2--|--3--|--4--|--5--|
1     |     |     |     |     |
|     |     |     |     |     |
|-----|-----|-----|-----|-----|
2     |  p  |     |     |     |
|     |     |     |     |     |
|-----|-----|-----|-----|-----|
3     |     |  x  |  x  |     |
|     |     |     |     |     |
|-----|-----|-----|-----|-----|
4     |     |     |     |     |
|     |     |     |     |     |
|-----|-----|-----|-----|-----|
5     |     |     |  k  |     |
|     |     |     |     |     |
|-----|-----|-----|-----|-----|

Pomyslalem zeby zrobic petle. Kazda iteracja petli to jeden ruch. Przewiduje mozliwosc na skos. No i w kazdej sytuacji najprostrza droga bedzie wlasnie na ukos. No i zeby tak przejsc musimy przejsc przez pola 2,3 , 3,3 , 3,4 i 4,4. Na poczatek zastanawiam sie czy w ogole jest to mozliwe do obliczenia przez php. No, ale dajmy na to ze tak. Pierwsza iteracja - sprawdzamy czy mozemy wejsc na pole 2,3. Jezeli tak - idziemy do drugiej iteracji, jezeli nie - sprawdzamy czy sasiednie pola (zaczynajac od tych najblizej punktu docelowego) sa puste. Jezeli mozna wejsc na jakies pole, wchodzimy na nie, konczymy petle i wchodzimy do nowej, gdzie nastepuje ponowne liczenie sciezki, ale juz od nowego pukntu.
Dobrze mysle, i czy da to sie wykonac? Potrafil bym napisac takie cos, ale nie uwzgledniajac chodzenia na skos. Prosze o jakies sugestie, jak to rozwiazac.
Wave
Czy dobrze rozumiem że masz tablice pięciowymiarową?
dr_bonzo
Ma co najwyzej tablice 2 wymiarowa 5x5.

Revan: poszukaj o algorytmach znajdowania najkrotszej sciezki. Wg. nich wypelnialo sie kazdy kwadrat pokolei/rekurencyjnie odlegloscia od P. A po dojsciu do K cofales sie i odnajdywales najkrotsza sciezke.
matys
Poczytaj o algorytmie Dijkstry.
TomASS
Tja.... Djkikstry.....

Wg. mnie sposób zaproponowany przez kolegę Revana nie jest za dobry. A co bedzie, gdy po przeliczeniu całej mapy okaże się, że kwadrat jest niedostępny od danej strony? Że prościej byloby na około? Ale to miały być konstruktywne wnioski....smile.gif

A więc:

1. Spróbuj trzymać odległości w tzw. macierzy sąsiedztwa albo w liście sąsiedztwa
2. Do przeliczenia najkrótszej odległości użyj, zgodnie z zaleceniami kolegi matysa, algorymu Djikstry, ale to też zależy ile masz tych 'kwadratów', miast, punktów, wieszchołków.....(czy jak to nazywać). Jeśli masz bardzo dużo punktów (powiedzmy 10000 - czas wykonywania algorytmu Djiksrty jest rzędu O(m log n)) to najlepiej użyć jednego z algorytmów genetycznych. Ale jeśli tych punktów jest niewiele, to zamiast algorytmu Dikstry najlepiej użyć algorymu Floyda. W internecie jest dużo publikacji na ten temat.


Pozdrawiam serdecznie i mam nadziej, że pomogłem
dr_bonzo
O to mi chodzilo:
http://www.gamedev.net/reference/articles/article2003.asp

Cytat
Summary of the A* Method

Okay, now that you have gone through the explanation, let's lay out the step-by-step method all in one place:
Add the starting square to the open list.
Repeat the following:
a) Look for the lowest F cost square on the open list. We refer to this as the current square.
cool.gif Switch it to the closed list.
c) For each of the 8 squares adjacent to this current square …
If it is not walkable or if it is on the closed list, ignore it. Otherwise do the following.
If it isn't on the open list, add it to the open list. Make the current square the parent of this square. Record the F, G, and H costs of the square.
If it is on the open list already, check to see if this path to that square is better, using G cost as the measure. A lower G cost means that this is a better path. If so, change the parent of the square to the current square, and recalculate the G and F scores of the square. If you are keeping your open list sorted by F score, you may need to resort the list to account for the change.

d) Stop when you
Add the target square to the open list, in which case the path has been found, or
Fail to find the target square, and the open list is empty. In this case, there is no path.
Save the path. Working backwards from the target square, go from each square to its parent square until you reach the starting square. That is your path.
nospor
Kiedyś uyżywalme takiego algorytmu (nie pamiętam jak się nazwyal):

Zaczynasz od punktu koncowego.Każdemu polu do któego możesz wejśc bezposrednio z punktu koncowego przypisujesz wartość 1. Następnie każdemu polu, do którego możesz wejści z pol oznaczonych jako 1, przypisujesz wartośc 1, a tamtym polom zwiekszasz wartośc na dwa. Teraz znowu wszyskim polom do których możesz wejsc z 1 przypisujesz wartośc 1, a pozostalym zwiekszasz o 1 (czyli 1 na 2, 2 na 3). robisz tak, aż natrafisz na pole poczatkowe. Teraz masz juz wyznaczoną najkrótrzą drogę. Z punktu początkowego przeskakujesz na pole o wartości 1, stamtąd na pole o wartości 2, z 2 na 3 itd az wejdziesz na koncowe.

POzdro

w efekcie koncowym powininien otrzymać taki uklad:
Kod
|--1--|--2--|--3--|--4--|--5--|
1     |     |     |     |     |
|     |     |     |     |     |
|-----|-----|-----|-----|-----|
2     |  p  |     |     |  1  |
|     |     |     |     |     |
|-----|-----|-----|-----|-----|
3     |   1 |  x  |  x  |  2  |
|     |     |     |     |     |
|-----|-----|-----|-----|-----|
4   1 |   2 |  3  |  4  |  3  |
|     |     |     |     |     |
|-----|-----|-----|-----|-----|
5     |  3  |  4  |  k  |  4  |
|     |     |     |     |     |
|-----|-----|-----|-----|-----|

troche zamalo kratek mi sie uzupelnilo, ale mniej wiecej tak to powinno wygladac na koniec iteracji
Radarek
Cytat(Revan @ 2005-05-26 17:25:42)
Jo!
Mam taka mape, ktora jest podzielona na kwadraty:
Kod
|--1--|--2--|--3--|--4--|--5--|
1     |     |     |     |     |
|     |     |     |     |     |
|-----|-----|-----|-----|-----|
2     |     |     |     |     |
|     |     |     |     |     |
|-----|-----|-----|-----|-----|
3     |     |     |     |     |
|     |     |     |     |     |
|-----|-----|-----|-----|-----|
4     |     |     |     |     |
|     |     |     |     |     |
|-----|-----|-----|-----|-----|
5     |     |     |     |     |
|     |     |     |     |     |
|-----|-----|-----|-----|-----|

Teraz, zalozmy ze chce przejsc z kwadratu 2,2 (p) do 4,5 (k) z tym ze pola oznaczone x sa nie do przejscia. Tak jak tu:
Kod
|--1--|--2--|--3--|--4--|--5--|
1     |     |     |     |     |
|     |     |     |     |     |
|-----|-----|-----|-----|-----|
2     |  p  |     |     |     |
|     |     |     |     |     |
|-----|-----|-----|-----|-----|
3     |     |  x  |  x  |     |
|     |     |     |     |     |
|-----|-----|-----|-----|-----|
4     |     |     |     |     |
|     |     |     |     |     |
|-----|-----|-----|-----|-----|
5     |     |     |  k  |     |
|     |     |     |     |     |
|-----|-----|-----|-----|-----|

Pomyslalem zeby zrobic petle. Kazda iteracja petli to jeden ruch. Przewiduje mozliwosc na skos. No i w kazdej sytuacji najprostrza droga bedzie wlasnie na ukos. No i zeby tak przejsc musimy przejsc przez pola 2,3 , 3,3 , 3,4 i 4,4. Na poczatek zastanawiam sie czy w ogole jest to mozliwe do obliczenia przez php. No, ale dajmy na to ze tak. Pierwsza iteracja - sprawdzamy czy mozemy wejsc na pole 2,3. Jezeli tak - idziemy do drugiej iteracji, jezeli nie - sprawdzamy czy sasiednie pola (zaczynajac od tych najblizej punktu docelowego) sa puste. Jezeli mozna wejsc na jakies pole, wchodzimy na nie, konczymy petle i wchodzimy do nowej, gdzie nastepuje ponowne liczenie sciezki, ale juz od nowego pukntu.
Dobrze mysle, i czy da to sie wykonac? Potrafil bym napisac takie cos, ale nie uwzgledniajac chodzenia na skos. Prosze o jakies sugestie, jak to rozwiazac.


Widze, ze slabo znacie sie na algorytmach ;-).
Ktos wspominal algorytm Dijkstry. Tak - moznaby go w tym wypadku uzyc, ale nie ma takiej potrzeby. Dijkstry uzywa sie w przypadku kiedy odleglosci miedzy polami bylyby rozne [wagi krawedzi w grafie o roznych wartosciach].

Algorytm do rozwiazania tego problemu jest prosty.
Implementujesz sobie prosta kolejke FIFO do przechowywania pol [czyli wartosci X i Y]. Nastepnie wsadzasz na stos pole startowe i robisz tak:
1. kolejka jest pusta? -> nie znaleziono drogi, koncz dzialanie skryptu
2. pobierz z kolejki pole P, zaznacz jako przegladniete
3. jesli pole P jest polem koncowym -> znaleziono droge
3. sprawdz kazde pole sasiednie pola P [czyli pola na ktore mozna przejsc] -> jesli nie sa odwiedzone i nie sa oznaczone jako X to wsadz je do kolejki, dla kazdego wsadzanego R pola ustaw jako poprzednik jako P

Jest to algorytm przeszukiwania wszerz.
Zlozonosc tego algorytmu to O(N+8N)=O(N), gdzie N to liczba pol na szachownicy.

W momencie dojscia do pola koncowego aby wyznaczyc sciezke po ktorej nalezy sie poruszac robimy to cofajac sie po poprzednikach. Jest to dosc ogolnie opisany algorytm wiec jak masz jakies pytania to pisz, ew. szukaj na googlach "przeszukiwanie grafu wszerz"
TomASS
Cytat(Radek)
Widze, ze slabo znacie sie na algorytmach ;-).

Kogo masz na myśli? tongue.gif

Cytat(Radek)
Ktos wspominal algorytm Dijkstry. Tak - moznaby go w tym wypadku uzyc, ale nie ma takiej potrzeby. Dijkstry uzywa sie w przypadku kiedy odleglosci miedzy polami bylyby rozne [wagi krawedzi w grafie o roznych wartosciach].

A kto Ci takich bajek naopowiadał? Niby czemu tutaj go nie można użyć. Fakt, że nie jest zbyt wydajny, ale jest JEDNYM Z MOŻLIWYCH rozwiązań i w sieci można znaleźć bardzo wiele publikaci na jego temat.

Cytat(Radek)
Algorytm do rozwiazania tego problemu jest prosty.

Dla jednych jest, dla innych nie.... tongue.gif

Cytat(Radek)
Implementujesz sobie prosta kolejke FIFO do przechowywania pol [czyli wartosci X i Y]. Nastepnie wsadzasz na stos pole startowe i robisz tak:
1. kolejka jest pusta? -> nie znaleziono drogi, koncz dzialanie skryptu
2. pobierz z kolejki pole P, zaznacz jako przegladniete
3. jesli pole P jest polem koncowym -> znaleziono droge
3. sprawdz kazde pole sasiednie pola P [czyli pola na ktore mozna przejsc] -> jesli nie sa odwiedzone i nie sa oznaczone jako X to wsadz je do kolejki, dla kazdego wsadzanego R pola ustaw jako poprzednik jako P

Dobre, też dobre rozwiązanie, można by nawet powiedzieć, że najlepsze....

Cytat(Radek)
Jest to algorytm przeszukiwania wszerz.
Zlozonosc tego algorytmu to O(N+8N)=O(N), gdzie N to liczba pol na szachownicy.
W momencie dojscia do pola koncowego aby wyznaczyc sciezke po ktorej nalezy sie poruszac robimy to cofajac sie po poprzednikach. Jest to dosc ogolnie opisany algorytm wiec jak masz jakies pytania to pisz, ew. szukaj na googlach "przeszukiwanie grafu wszerz"


No nie koniecznie wszerz, można też wstecz....

Ogólnie, zgadzam się z kolegą Radkiem - poczytaj o grafach, to naprawde poteżne narzędzie i na pewno Ci się przyda w tej sytuacji.
Radarek
Cytat(TomASS @ 2005-05-27 14:16:06)
Cytat(Radek)

Widze, ze slabo znacie sie na algorytmach ;-).

Kogo masz na myśli? tongue.gif

Nikogo konkretnego tongue.gif. Po prostu nikt w poprzedzajacych odpowiedziach nie podal rozwiazania ktore jak dla mnie jest jedynym slusznym w takim wypadku smile.gif [czyli to podane przeze mnie]
Cytat(TomASS @ 2005-05-27 14:16:06)
Cytat(Radek)

Ktos wspominal algorytm Dijkstry. Tak - moznaby go w tym wypadku uzyc, ale nie ma takiej potrzeby. Dijkstry uzywa sie w przypadku kiedy odleglosci miedzy polami bylyby rozne [wagi krawedzi w grafie o roznych wartosciach].

A kto Ci takich bajek naopowiadał? Niby czemu tutaj go nie można użyć. Fakt, że nie jest zbyt wydajny, ale jest JEDNYM Z MOŻLIWYCH rozwiązań i w sieci można znaleźć bardzo wiele publikaci na jego temat.

Napisalem, ze mozna go uzyc tutaj, ale nie ma takiej potrzeby bo mozna to zrobic prosciej [przeszukiwanie wszerz jest duzo latwiej zaimplementowac od algorytmu Dijkstry]. Zlozonosc Dijkstry to O(n^2), przy implementacji kopcowej [z tego co pamietam nie jest to zbyt proste] O(n*log(n)).
Cytat(TomASS @ 2005-05-27 14:16:06)
Cytat(Radek)

Algorytm do rozwiazania tego problemu jest prosty.

Dla jednych jest, dla innych nie.... tongue.gif

Cytat(Radek)
Implementujesz sobie prosta kolejke FIFO do przechowywania pol [czyli wartosci X i Y]. Nastepnie wsadzasz na stos pole startowe i robisz tak:
1. kolejka jest pusta? -> nie znaleziono drogi, koncz dzialanie skryptu
2. pobierz z kolejki pole P, zaznacz jako przegladniete
3. jesli pole P jest polem koncowym -> znaleziono droge
3. sprawdz kazde pole sasiednie pola P [czyli pola na ktore mozna przejsc] -> jesli nie sa odwiedzone i nie sa oznaczone jako X to wsadz je do kolejki, dla kazdego wsadzanego R pola ustaw jako poprzednik jako P

Dobre, też dobre rozwiązanie, można by nawet powiedzieć, że najlepsze....

Cytat(Radek)
Jest to algorytm przeszukiwania wszerz.
Zlozonosc tego algorytmu to O(N+8N)=O(N), gdzie N to liczba pol na szachownicy.
W momencie dojscia do pola koncowego aby wyznaczyc sciezke po ktorej nalezy sie poruszac robimy to cofajac sie po poprzednikach. Jest to dosc ogolnie opisany algorytm wiec jak masz jakies pytania to pisz, ew. szukaj na googlach "przeszukiwanie grafu wszerz"


No nie koniecznie wszerz, można też wstecz....

Ogólnie, zgadzam się z kolegą Radkiem - poczytaj o grafach, to naprawde poteżne narzędzie i na pewno Ci się przyda w tej sytuacji.


Wstecz? Pierwsze slysze. Sa dwa rodzaje przeszukiwania grafow: w glab [wystarczy podmienic kolejke na stos w moim rozwiazaniu] i wszerz. O wstecz nie slyszalem.
TomASS
Szkoda, że zjechaliśmy z tematu.....

Nic więcej nie mam do dopowiedzenia (narazie) co do tematu, wybór algorytmu pozostawiam jednak autorwi posta i napewno bedzie on słuszny.

A co do wątpliwosći Radka:

Przeszukiwanie wsteczne (najczęściej tyczy się grafów skierowanych) można by podczepić do grupy przeszuiwania w głąb. Przy zastostowaniu kliku prostych zmian w algorytmie przeszukiwania w głąb, możemy przeszukiwać graf z kolejnością wsteczną i.............

Jak nie chcesz wierzyć to nie wierz, że jest przeszukiwanie wsteczne tongue.gif
Może poprostu kwalifikujesz je do przeszukiwania w głąb?

Mniejsz o to! smile.gif

Pozdrawiam i mam nadzieje, że się do czegoś przydałem
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2024 Invision Power Services, Inc.