2008-08-07 22 views
37

Yönlendirilmiş bir grafiği 'serileştirmek' için basit bir algoritma arıyorum. Özellikle, yürütme sırasındaki bağımlılıklara sahip bir dizi dosyam var ve derleme zamanında doğru sırayı bulmak istiyorum. Bunu yapmanın oldukça yaygın bir şey olduğunu biliyorum - derleyiciler bunu her zaman yapıyorlar - ama google-fu'm bugün zayıf. Bunun için 'git' algoritması nedir?Grafik serileştirme

cevap

54

Topological Sort: Grafik Teoride

, topolojik bir sıralama veya yönlendirilmiş asiklik grafik (DAG) topolojik sipariş her düğüm gelir ki burada onun düğüm doğrusal sıralamadır 'un tüm düğümlerinden önce giden kenarları vardır. Her DAG bir veya daha fazla topolojik çeşitliliğe sahiptir.

Sözde kodu: dosyalarınız için

L ← Empty list where we put the sorted elements 
Q ← Set of all nodes with no incoming edges 
while Q is non-empty do 
    remove a node n from Q 
    insert n into L 
    for each node m with an edge e from n to m do 
     remove edge e from the graph 
     if m has no other incoming edges then 
      insert m into Q 
if graph has edges then 
    output error message (graph has a cycle) 
else 
    output message (proposed topologically sorted order: L) 
+8

Eh ... wikipedia doğrudan kopyalandı? – Benjol

+1

evet, lütfen kaynaklardan alıntı yapın –

+0

Teşekkürler. Bağımlılık ağacının bu yöntem kullanılarak sıralanabileceği gerçeğini eşleştirmeme yardımcı oldu. :-) –

1

Buna ihtiyaç duyan araçların ağacın derinliklerine ilk bakışta yürümesini beklerim ve bir yaprağa çarptığında, sadece işleyin (örn. Derleyin) ve grafikten çıkarın (veya işlendiği gibi işaretleyin ve işleyin) tüm yapraklar yaprakları ile işlenen düğümler).

Bir DAG olduğu sürece, bu basit yığın tabanlı yürüyüş önemsiz olmalıdır.

+0

Evet, işte böyle yapıyorsunuz. Derinlik-ilk arama (DFS) denir. Ve bir DAG'nız olduğundan emin değilseniz, arka kenarları kontrol etmelisiniz, aksi takdirde bir döngü sizi sonsuz bir döngüye gönderecektir. Bir foreach kullanımı yerine – sleske

0

Oldukça naif özyinelemeli algoritması (sözde kod) ile geldim:

Map<Object, List<Object>> source; // map of each object to its dependency list 
List<Object> dest; // destination list 

function resolve(a): 
    if (dest.contains(a)) return; 
    foreach (b in source[a]): 
     resolve(b); 
    dest.add(a); 

foreach (a in source): 
    resolve(a); 

bu en büyük sorunlarından birisi halkalı bağımlılıkları tespit etme özelliği yoktur - o (sonsuz özyinelemeye geçebiliriz yani yığın taşması; - p). Görebildiğim tek yol, özyinelemeli algoritmayı manuel bir yığınla interaktif olana çevirmek ve tekrarlanan elemanlar için yığını el ile kontrol etmektir.

Herkes daha iyi bir şey var mı? (Vikipedi)

+0

bir süre kullanın, verileri a'dan geçen iki işaretçiyi koruyun, bir öncekinden iki adım ve bir adımda bu tek adım. Önde gelen işaretçi, acutal kararları ele alır ve eğer izleyen işaretçiyi geride bırakırsa, bir döngü vardır. – Tenderdude

1

grafik döngüleri içeriyorsa, nasıl orada izin bulunmamakta edebilir yürütme emirleri? Bana göre, eğer grafik döngüleri içeriyorsa, o zaman çözümünüz yok ve bu , yukarıdaki algoritma tarafından doğru şekilde rapor ediliyor.

+0

Evet, bir grafik döngüleri içeriyorsa topolojik sıralama mümkün değildir. Bu gerçek dünyaya tekabül eder: Eğer A'dan önce A, B ve * B önce yapmanı istersem, beni tatmin edecek bir yol yoktur ;-). – sleske