Dinamik bir grafikte bağlı bileşen bilgilerini korumak için en verimli algoritma ve veri yapısı nedir?


9

Yönlendirilmemiş sonlu bir seyrek grafiğim olduğunu ve aşağıdaki sorguları verimli bir şekilde çalıştırabilmem gerektiğini varsayalım:

  • bensCÖnnected(N-1,N-2) - ve arasında bir yol varsa değerini döndürür , aksi takdirdeTN-1N-2F
  • CÖnnectedN-Ödes(N-) - erişilebilen düğüm kümesini döndürürN-

Bu, grafiğin bağlı bileşenlerini önceden hesaplayarak kolayca yapılabilir. Her iki sorgu da zamanda çalışabilir .Ö(1)

Ayrıca keyfi olarak kenarları ekleyebilmem - - o zaman bileşenleri ayrık olarak ayarlanmış bir veri yapısında saklayabilirim . Bir kenar eklendiğinde, farklı bileşenlerde iki düğümü bağlarsa, bu bileşenleri birleştiririm. Bu , maliyetini ekler ve ve ( olabilir maliyetini .birddEdge(N-1,N-2)Ö(1)birddEdgeÖ(bennversebirckermbirnn(|N-Ödes|))bensCÖnnectedCÖnnectedN-ÖdesÖ(1)

Kenarları keyfi olarak da çıkartabilmem gerekirse, bu durumu ele almak için en iyi veri yapısı nedir? Bilinen biri var mı? Özetlemek gerekirse, aşağıdaki işlemleri verimli bir şekilde desteklemelidir:

  • bensCÖnnected(N-1,N-2) - ve arasında bir yol varsa değerini döndürür , aksi takdirde döndürür .TN-1N-2F
  • CÖnnectedN-Ödes(N-) - erişilebilen düğüm kümesini döndürür .N-
  • birddEdge(N-1,N-2) - iki düğüm arasına bir kenar ekler. O Not , veya her ikisi önce var olmayabilirdi.N-1N-2
  • R,emÖveEdge(N-1,N-2) - iki düğüm arasındaki mevcut bir kenarı kaldırır.

(Bunu oyun geliştirme perspektifinden ilgileniyorum - bu sorun çok az durumda ortaya çıkıyor gibi görünüyor. Belki oyuncu güç hatları inşa edebilir ve bir jeneratörün bir binaya bağlı olup olmadığını bilmemiz gerekir. Belki oyuncu kilitleyebilir ve kapıların kilidini açıyoruz ve bir düşmanın oyuncuya ulaşıp ulaşamayacağını bilmeliyiz.Ama bu çok genel bir sorun, bu yüzden bunu şöyle ifade ettim)


CÖnnectedN-Ödes muhtemelen çalıştırmak olamazdı o listesini döndürür çünkü eğer, düğümler, bu gerekir zaman. Uygulama bir potansiyel veri yapısı sadece IsConnected, AddEdge ve RemoveEdge desteklemek gerekir bu yüzden bir BFS ile, en uygunudur. Bu, sorunuzla alakalı görünüyor: stackoverflow.com/questions/7241151/…Ö(1)nΩ(n)CÖnnectedN-Ödes
Tom van der Zanden

@TomvanderZanden Halihazırda oluşturulmuş bir kümeyi (programlamada, bir işaretçi veya referans) döndürmek ... ancak kullanıcısı bunu yapamaz ve tarafından . Ö(1)CÖnnectedN-ÖdesÖ(1)bensCÖnnected
user253751

Yanıtlar:


11

Bu sorun dinamik bağlantı olarak bilinir ve teorik bilgisayar bilimleri topluluğunda aktif bir araştırma alanıdır. Burada hala bazı önemli sorunlar var.

Terminolojiyi netleştirmek için kenarları eklemek ve silmek istediğinizden tamamen dinamik bağlantı istersiniz. Holm, de Lichtenberg ve Thorup'un (J.ACM 2001) bir sonucu vardır.Ö(günlük2n) güncelleme zamanı ve Ö(günlükn/günlükgünlükn)sorgu süresi. Anladığım kadarıyla uygulanabilir. Basitçe söylemek gerekirse, veri yapısı yayılan ağaçların hiyerarşisini korur ve ağaçlardaki dinamik bağlantıyı kapsaması daha kolaydır. Ben tavsiye ederim Erik D. Demaine en iyi açıklama bakınız için notlar burada bir video için. Erik'in notu, ilgili diğer sonuçlara da işaretçiler içerir. Not olarak: tüm bu sonuçlar teorik sonuçlardır.

Bu veri yapıları kendi başına ConnectedNodes sorguları sağlamayabilir , ancak bunu başarmak kolaydır. Ek bir veri yapısı olarak grafiği (iki kat bağlantılı kenar listesi olarak söyleyin) ve belirli bir düğümden ulaşılabilen düğümleri almak için derinlik-ilk aramasını yapın.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.