Рина Сергеева
Рина Сергеева12. Juni 2018 02:34

Implementierung des Wave-Algorithmus (Lee-Algorithmus) in Java

Manchmal stehen wir vor der Aufgabe, den minimalen Weg von Punkt A nach Punkt B zu finden . "Bewegungskarte" kann Hindernisse haben und wie ein Labyrinth sein. Ähnliche Aufgaben treten bei der Spieleentwicklung, dem Leiterplattendesign und der Entwicklung von GPS-Navigatoren usw. auf.

Es gibt viele Algorithmen zum Finden des minimalen Pfads. Am einfachsten und effektivsten ist jedoch Wave Trace Algorithm (Lee's Algorithm) , der auf Breitensuchmethoden basiert.

Die Funktionsweise dieses Algorithmus ist nicht schwer zu verstehen. Es wird selbst einem Programmieranfänger klar sein.


Ich werde ein Beispiel meiner Arbeit geben. Ich habe eine Art zellulären Automaten (einen Graphen, der aus Knoten und Kanten zwischen ihnen besteht). Wir werden den Lee-Algorithmus darauf implementieren.

Die Implementierung des Algorithmus besteht aus 3 Stufen:

  1. Initialisierung von Anfangsdaten;
  2. Wellenausbreitung;
  3. Pfadwiederherstellung.

Erste Stufe - Initialisierung der Anfangsdaten

Sie benötigen ein Array von Objekten (Knoten, Zellen). Ich habe diese Klasse Node .

Jedes Objekt, außer anderen, hat ein near -Feld vom Typ zB ArrayList. In dieses Feld tragen Sie alle "Nachbarn" ( Nachbarn dieses Knotens ) ein.

Jeder Knoten ist mit „passierbar/unpassierbar“ gekennzeichnet.

Die Start- und Zielknoten werden aufgezeichnet.

Zweite Stufe - Wellenausbreitung

Sie müssen ein numerisches Array (nach Anzahl der Zellen) haben, in das die Zahlen (Markierungen) für jede Zelle geschrieben werden. Standardmäßig sind alle Zellenwerte Null.

Startknoten wird auf 1 gesetzt.

Sie prüfen alle "benachbarten" Knoten dieses Knotens auf "Passierbarkeit" und prüfen, ob auf ihnen bereits Markierungen vorhanden sind. Da sollte die Marke nur einmal gesetzt werden.

Wenn alles zufriedenstellend ist, setzen Sie markiere 1 mehr als den vorherigen Knoten. Als nächstes überprüfen Sie die "Nachbarknoten".

Also bis du die Zielzelle erreichst.

Beispielcode:
public int[] WavePropagation(int fromNode, int toNode, ElementManager elementManager) {  // распространение волны

        int[] markedNode = new int[elementManager.GetNumberOfAllNodes()]; // массив, где будут хранится "отметки" каждого узла
        int markNumber = 1;                        // счетчик
        markedNode[fromNode] = markNumber;         // инициализация стартового узла
        while (markedNode[toNode] == 0) {          // пока не достигли финишного узла
            for (int i = 0; i < markedNode.length; i++) { 
                if (markedNode[i] == markNumber) {                                          // начинаем со стартового узла
                    for (int j = 0; j < elementManager.GetNode(i).near.size(); j++) {       // просматриваем все соседние узлы
                        if(markedNode[elementManager.GetNode(i).near.get(j).number] == 0    // если он еще не получил "отметку"
                           && elementManager.GetNode(i).near.get(j).isEnable){              // если доступен 
                            markedNode[elementManager.GetNode(i).near.get(j).number] = (markNumber + 1);
                        }
                    }
                }
            }
            markNumber++;
        }
        return markedNode;
    }

Dritte Phase - Wiederherstellung des Pfades

Geben Sie den Endknoten in das Pfadarray ein.

Betrachten Sie die Markierungen aller Knoten "angrenzend" an den Endknoten. Geben Sie in das Pfadarray den Knoten ein, dessen Höhe 1 kleiner ist als die des Zielknotens.

Wiederholen Sie diese Aktion, bis der Startknoten erreicht ist.

Beispielcode:
public ArrayList<Integer> PathRecovery(int fromNode, int toNode, int[] markedNode, ElementManager elementManager) {  // восстановление пути
        ArrayList<Integer> paramsPaveTheRoute = new ArrayList<>();      // массив, где хранится путь
        if (markedNode[elementManager.GetNode(toNode).number] != 0) {   // еще раз проверяем дошел ли алгоритм до финишного узла
            paramsPaveTheRoute.add(toNode);                             // добавляем финишный узел к пути
            ElementManager.Node currentNode = elementManager.GetNode(toNode);
            while (currentNode.number != fromNode) {                     // пока не дошли до стартового узла   
                for (int i = 0; i < currentNode.near.size(); i++) {      // проверяем соседние узлы
                    if (markedNode[elementManager.GetNode(currentNode.near.get(i).number).number]
                            == markedNode[currentNode.number] - 1) {     // если значение пометки узла на 1 меньше, чем у предыдущего узла
                        currentNode = elementManager.GetNode(currentNode.near.get(i).number); //узел становится текущим
                        paramsPaveTheRoute.add(currentNode.number);      // заносится в массив
                    }
                }
            }
        }
        return paramsPaveTheRoute;
    }
Das Ergebnis des Programms:

Ich denke, Sie haben also gesehen, dass Wave Trace Algorithm (Lee's Algorithm) überhaupt nicht schwer zu implementieren ist. Es führt eine minimale Pfadsuche mit einem geringen Rechenaufwand durch. Falls gewünscht, kann dieser universelle Algorithmus kompliziert sein.

Рекомендуємо хостинг TIMEWEB
Рекомендуємо хостинг TIMEWEB
Stabiles Hosting des sozialen Netzwerks EVILEG. Wir empfehlen VDS-Hosting für Django-Projekte.

Magst du es? In sozialen Netzwerken teilen!

Kommentare

Nur autorisierte Benutzer können Kommentare posten.
Bitte Anmelden oder Registrieren
Letzte Kommentare
A
ALO1ZE19. Oktober 2024 08:19
Fb3-Dateileser auf Qt Creator Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
ИМ
Игорь Максимов5. Oktober 2024 07:51
Django – Lektion 064. So schreiben Sie eine Python-Markdown-Erweiterung Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
d
dblas55. Juli 2024 11:02
QML - Lektion 016. SQLite-Datenbank und das Arbeiten damit in QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
k
kmssr8. Februar 2024 18:43
Qt Linux - Lektion 001. Autorun Qt-Anwendung unter Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
Qt WinAPI - Lektion 007. Arbeiten mit ICMP-Ping in Qt Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
Jetzt im Forum diskutieren
J
JacobFib17. Oktober 2024 03:27
добавить qlineseries в функции Пользователь может получить любые разъяснения по интересующим вопросам, касающимся обработки его персональных данных, обратившись к Оператору с помощью электронной почты https://topdecorpro.ru…
JW
Jhon Wick1. Oktober 2024 15:52
Indian Food Restaurant In Columbus OH| Layla’s Kitchen Indian Restaurant If you're looking for a truly authentic https://www.laylaskitchenrestaurantohio.com/ , Layla’s Kitchen Indian Restaurant is your go-to destination. Located at 6152 Cleveland Ave, Colu…
КГ
Кирилл Гусарев27. September 2024 09:09
Не запускается программа на Qt: точка входа в процедуру не найдена в библиотеке DLL Написал программу на C++ Qt в Qt Creator, сбилдил Release с помощью MinGW 64-bit, бинарнику напихал dll-ки с помощью windeployqt.exe. При попытке запуска моей сбилженной программы выдаёт три оши…
F
Fynjy22. Juli 2024 04:15
при создании qml проекта Kits есть но недоступны для выбора Поставил Qt Creator 11.0.2. Qt 6.4.3 При создании проекта Qml не могу выбрать Kits, они все недоступны, хотя настроены и при создании обычного Qt Widget приложения их можно выбрать. В чем может …

Folgen Sie uns in sozialen Netzwerken