Algorithmus in Python (Tiefenprioritätssuche, dfs)

Einführung

Ich habe gehört, dass es bei der Suche nach Tiefenpriorität mit Python ein Leistungsproblem mit rekursiv gibt, daher habe ich beschlossen, es mit Stack zu implementieren, und es als Memorandum im Artikel belassen. Ich hoffe es hilft dir beim Lernen und wenn du einen Rat hast, hinterlasse bitte einen Kommentar!

Thema

Dieses Mal werden wir die Zeit berücksichtigen, die benötigt wird, um einen bestimmten Scheitelpunkt zu starten und jeden Peak zu erreichen. Dies ist ein typisches Thema bei der Suche nach Tiefenprioritäten. (Ist es eher eine Bestellung als eine Zeit?) Überprüfen Sie zu diesem Zeitpunkt die Ankunftszeit ** gehende Bestellung **, überprüfen Sie die letzte verstrichene Zeit ** Rücksendung ** und notieren Sie beide zusammen mit ** Zeitstempel **. Wir werden uns mit den drei Fällen befassen. Der letzte Durchgang erfolgt unmittelbar nach Abschluss der Suche nach allen Scheitelpunkten unterhalb dieses Scheitelpunkts. Ich werde nicht näher auf dfs eingehen, aber ich werde vom Ausgangspunkt bis zu meinem Ziel tiefer gehen, und wenn ich nicht weiter gehen kann, werde ich zur vorherigen Gabelung zurückkehren und dasselbe wiederholen. Nehmen wir hier an, dass derjenige mit der jüngeren Scheitelpunktnummer bevorzugt gesucht wird.

Input-Output

Eingang

Geben Sie die Anzahl der Scheitelpunkte in der ersten Zeile als Ganzzahl ein und geben Sie dann die Scheitelpunktnummer, die Anzahl benachbarter Scheitelpunkte und die benachbarten Scheitelpunkte in der N-Linie ein, die durch Leerzeichen getrennt sind.

6
1 2 2 3
2 2 3 4
3 1 5
4 1 6
5 1 6
6 0

Ausgabe

Die Scheitelpunktnummer, die Ankunftszeit und die Suchendzeit werden in Zeile N ausgegeben, die durch Leerzeichen getrennt sind. (Nur der erstere ist in der Reihenfolge des Gehens und nur der letztere ist in der Reihenfolge der Rückkehr.)

1 1 12
2 2 11
3 3 8
4 9 10
5 4 7
6 5 6

Implementierung

Going Order

dfs_1.py


#Tiefenprioritätssuche (los)
import sys
input = sys.stdin.readline
from collections import deque

#Diagramm erstellen(In der ungerichteten Grafik#Löschen)
N = int(input())
graph = [deque([]) for _ in range(N + 1)]
for _ in range(N):
    u, k, * v = [int(x) for x in input().split()] #u ist die Scheitelpunktnummer und k ist die Anzahl benachbarter Scheitelpunkte
    v.sort()
    for i in v:
        graph[u].append(i)
        # graph[i].append(u) #Ungerichtete Grafik

time = 0
arrive_time = [-1] * (N + 1) #Ankunftszeit

#Tiefenprioritätssuche
def dfs(v):
    global time
    time += 1
    stack = [v]
    arrive_time[v] = time
    while stack:
        v = stack[-1]
        if graph[v]:
            w = graph[v].popleft()
            if arrive_time[w] < 0:
                time += 1
                arrive_time[w] = time
                stack.append(w) 
        else:
            stack.pop()          
    return arrive_time

#Isolierte Apex-Maßnahmen
for i in range(N):
    if arrive_time[i + 1] < 0:
        ans = dfs(i + 1)

#Spitzenzahl, Ankunftszeit
for j in range(N):
    temp = [j + 1, ans[j + 1]]
    print(* temp)

Zunächst wird der Graph durch eine Adjazenzliste dargestellt. Hier wird es als gerichteter Graph betrachtet, aber es kann auch als ungerichteter Graph behandelt werden, indem ein # im Code entfernt wird. Die Zeit kann als globale Variable auf einer gemeinsamen Zeitachse behandelt werden, unabhängig davon, welcher Scheitelpunkt aufgerufen wird. Wenn ein neuer Scheitelpunkt erreicht wird, wird er um +1 erhöht und in der Ankunftszeit-Ankunftszeitliste aufgezeichnet. Einige gerichtete Graphen können vom Startpeak aus nicht erreicht werden. Wenn also nicht alle Peaks erreicht wurden, wird eine Suche mit Tiefenpriorität durchgeführt. Da der Stapel Last-In-First-Out ist, wird das hintere Element herausgenommen und die benachbarten Eckpunkte werden untersucht. Entfernen Sie diese Scheitelpunkte aus der Adjazenzliste, damit Sie sehen können, was Sie untersucht haben. Wenn der Inhalt leer ist, ist die Suche nach dem Scheitelpunkt abgeschlossen. Löschen Sie ihn daher vom Stapel.

Rückgabeauftrag

dfs_2.py


#Suche nach Tiefenpriorität (Rückkehr)
import sys
input = sys.stdin.readline
from collections import deque

#Diagramm erstellen(In der ungerichteten Grafik#Löschen)
N = int(input())
graph = [deque([]) for _ in range(N + 1)]
for _ in range(N):
    u, k, * v = [int(x) for x in input().split()] #u ist die Scheitelpunktnummer und k ist die Anzahl benachbarter Scheitelpunkte
    v.sort()
    for i in v:
        graph[u].append(i)
        # graph[i].append(u) #Ungerichtete Grafik

time = 0
arrive = [-1] * (N + 1) #Bist du angekommen
finish_time = [-1] * (N + 1) #Suche Endzeit

#Tiefenprioritätssuche
def dfs(v):
    global time
    stack = [v]
    arrive[v] = 1
    while stack:
        v = stack[-1]
        if graph[v]:
            w = graph[v].popleft()
            if arrive[w] < 0:
                arrive[w] = 1
                stack.append(w) 
        else:
            time += 1
            finish_time[v] = time
            stack.pop()          
    return finish_time

#Isolierte Apex-Maßnahmen
for i in range(N):
    if arrive[i + 1] < 0:
        ans = dfs(i + 1)

#Boxennummer, Endzeit
for j in range(N):
    temp = [j + 1, ans[j + 1]]
    print(* temp)

Die verwendeten Variablen und Ideen sind fast gleich, aber dieses Mal werden wir die Zeit aufzeichnen, zu der die Suche in finish_time endete, nicht die Zeit, als sie ankam. Mit anderen Worten, wenn ein benachbarter Scheitelpunkt eines bestimmten Scheitelpunkts aus der Adjazenzliste gelöscht wird, wenn er leer wird, rückt die Zeit vor und die Zeit wird aufgezeichnet.

Gehzeit + Rückkehrzeit

dfs_3.py


#Suche nach Tiefenpriorität (gehen, zurückkehren)
import sys
input = sys.stdin.readline
from collections import deque

#Diagramm erstellen(In der ungerichteten Grafik#Löschen)
N = int(input())
graph = [deque([]) for _ in range(N + 1)]
for _ in range(N):
    u, k, * v = [int(x) for x in input().split()] #u ist die Scheitelpunktnummer und k ist die Anzahl benachbarter Scheitelpunkte
    v.sort()
    for i in v:
        graph[u].append(i)
        # graph[i].append(u) #Ungerichtete Grafik

time = 0
arrive_time = [-1] * (N + 1) #Ankunftszeit
finish_time = [-1] * (N + 1) #Suche Endzeit

#Tiefenprioritätssuche
def dfs(v):
    global time
    time += 1
    stack = [v]
    arrive_time[v] = time
    while stack:
        v = stack[-1]
        if graph[v]:
            w = graph[v].popleft()
            if arrive_time[w] < 0:
                time += 1
                arrive_time[w] = time
                stack.append(w) 
        else:
            time += 1
            finish_time[v] = time
            stack.pop()          
    return [arrive_time, finish_time]

#Isolierte Apex-Maßnahmen
for i in range(N):
    if arrive_time[i + 1] < 0:
        ans = dfs(i + 1)

#Spitzenzahl, Ankunftszeit, Endzeit
for j in range(N):
    temp = [j + 1, ans[0][j + 1], ans[1][j + 1]]
    print(* temp)

Kombinieren Sie einfach die beiden oben genannten. Mit anderen Worten, wenn ein bestimmter Scheitelpunkt erreicht ist oder weniger, läuft die Zeit weiter und sie werden in Ankunftszeit und Endzeit aufgezeichnet.

Schließlich

Ich bin keine Informationsabteilung, deshalb lerne ich anhand von Artikeln und Büchern im Internet. Insbesondere für diese Suche nach Tiefenprioritäten war es für mich als Anfänger sehr schwierig, sie umzusetzen, obwohl die Idee einfach war. (Der Code in diesem Artikel ist möglicherweise auch falsch.) Geben Sie uns daher in den Kommentaren oder auf Twitter einige Ratschläge. Wenn Sie Ratschläge zur Beschleunigung haben, zögern Sie bitte nicht, uns zu kontaktieren.

Verweise

Recommended Posts

Algorithmus in Python (Tiefenprioritätssuche, dfs)
[Python] DFS (Tiefenprioritätssuche) ATC001A
Algorithmus in Python (Dichotomie)
[Python] DFS (Tiefenprioritätssuche) ABC157D
Algorithmus in Python (Breitenprioritätssuche, bfs)
Schreiben Sie eine Suche mit Tiefenpriorität in Python
Suche nach Tiefenpriorität mit Stack in Python
Implementieren Sie die Suche nach Tiefenpriorität (DFS) und die Suche nach Breitenpriorität (BFS) in Python
Algorithmus in Python (ABC 146 C Dichotomie
Dichotomie mit Python
Genetischer Algorithmus in Python
Algorithmus in Python (Bellman-Ford-Methode, Bellman-Ford)
Lineare Suche in Python
Binäre Suche in Python
Algorithmus in Python (Dijkstra)
Ich habe versucht, AtCoders Depth Priority Search (DFS) in Python zu lösen (Ergebnis: TLE ...)
Algorithmus in Python (Haupturteil)
Suchalgorithmus mit word2vec [Python]
Binäre Suche in Python / C ++
Reproduzieren Sie die euklidische Methode der gegenseitigen Teilung in Python
Implementieren Sie den Dijkstra-Algorithmus in Python
[Python] Suche nach Tiefenpriorität und Suche nach Breitenpriorität
Schreiben Sie eine Dichotomie in Python
Python-Algorithmus
Lassen Sie uns mit Python 2 einen Investitionsalgorithmus entwickeln
Implementierung eines einfachen Algorithmus in Python 2
Algorithmus (Segmentbaum) in Python (Übung)
Führen Sie einen einfachen Algorithmus in Python aus
[Python-Algorithmus] Ein Programm, das einige deutsche Antworten aus einer Suche mit Tiefenpriorität ausgibt
Ali Buch in Python: Sec.2-5 Dyxtra-Methode
Suchen und spielen Sie YouTube-Videos mit Python
Durchsuche das Labyrinth mit dem Python A * -Algorithmus
Schreiben Sie eine einfache Giermethode in Python
Auf der Suche nach dem schnellsten FizzBuzz in Python
Ausrichtungsalgorithmus durch Einfügemethode in Python
Quadtree in Python --2
Python in der Optimierung
CURL in Python
Metaprogrammierung mit Python
Python 3.3 mit Anaconda
Geokodierung in Python
SendKeys in Python
Metaanalyse in Python
Python-Memorandum (Algorithmus)
Unittest in Python
Epoche in Python
Zwietracht in Python
Deutsch in Python
DCI in Python
Quicksort in Python
N-Gramm in Python
String-Suchalgorithmus
Programmieren mit Python
Plink in Python
Konstante in Python
FizzBuzz in Python