Mengapa mengatakan bahwa pencarian pertama kali berjalan dalam waktu

9

Sering dinyatakan (misalnya, dalam Wikipedia ) bahwa waktu berjalan pencarian pertama kali (BFS) pada grafik G=(V,E) adalah O(|V|+|E|) . Namun, setiap grafik yang terhubung memiliki |V||E|+1 dan, bahkan dalam grafik non-terhubung, BFS tidak akan pernah melihat sebuah titik di luar komponen yang berisi awal vertex. Komponen itu paling banyak memuat |E| tepi, sehingga mengandung paling banyak |E|+1 simpul, dan mereka adalah satu-satunya yang algoritma akan mengunjungi.

Ini berarti bahwa |V|+|E|2|E|+1 , jadi mengapa tidak kita katakan bahwa waktu berjalan hanya O(|E|) ?

Ini muncul dalam komentar pada pertanyaan tentang waktu berjalan algoritma Disjkstra .

David Richerby
sumber
Mengapa Anda menganggap ada titik awal? BFS dalam masalah pencocokan maksimum misalnya dimulai dari semua simpul yang tidak cocok dalam algoritma hopcroft karp. Dalam hal ini, jika grafik yang diberikan adalah hutan dari banyak komponen yang terhubung kita akan memiliki lebih banyak simpul daripada edgers dan kita akan mengunjungi mereka semua
narek Bojikian
2
@narekBojikian Sementara BFS dapat digunakan dengan berbagai cara, ketika disajikan sebagai algoritma yang berdiri sendiri, hampir selalu memiliki simpul awal.
David Richerby

Jawaban:

9

BFS biasanya menggambarkan sesuatu seperti yang berikut ini (dari Wikipedia ).

 1  procedure BFS(G,start_v):
 2      let Q be a queue
 3      label start_v as discovered
 4      Q.enqueue(start_v)
 5      while Q is not empty
 6          v = Q.dequeue()
 7          if v is the goal:
 8              return v
 9          for all edges from v to w in G.adjacentEdges(v) do
10             if w is not labeled as discovered:
11                 label w as discovered
12                 w.parent = v
13                 Q.enqueue(w)

Masalahnya agak rumit: bersembunyi di baris 3! Pertanyaannya adalah, struktur data apa yang akan kita gunakan untuk menyimpan simpul mana yang telah ditemukan?

falseΘ(|V|)|V||E|O(|V|+|E|)

Θ(|V|)O(|V||E|)O(|E|2)|V|4|V||E||V|3

O(log|V|)O(|E|log|V|)

c|E|+1c+2c+4c++2|E|4|E| O(1)O(|E|)

O(|E|)4|E|O(|E|)O(|V|+|E|)

David Richerby
sumber
1
Saya pikir mungkin terlalu kuat untuk mengklaim bahwa tabel hash dalam praktiknya memiliki kinerja cache yang buruk. Jika diterapkan dengan chaining (yaitu, daftar tertaut), saya setuju. Tetapi jika diimplementasikan dengan sepotong memori terus menerus dan pengalamatan terbuka, tidak begitu banyak.
Juho
Jawaban yang sangat bagus! Satu catatan marjinal, tabel hash berukuran dinamis memang pilihan yang baik tidak hanya jika ada banyak komponen kecil, tetapi juga jika nilai hash untuk setiap titik dibatasi oleh konstanta yang masuk akal dan ini sering terjadi. Balasan yang bagus!
Carlos Linares López
1
David, saya memiliki pemikiran yang sama bertahun-tahun yang lalu. Saya pikir jawabannya terletak pada perspektif sejarah.
kelalaka