Toplam topolojik çeşit sayısı


11

Belirli bir DAG (yönlendirilmiş asiklik grafik) için, onun topolojik tür her biri, her kenarları için tüm tepe noktaları bir permütasyon olan (u, v) DAG, u önce görüntülenen v permütasyonda.

Göreviniz, belirli bir DAG'ın toplam topolojik çeşit sayısını hesaplamaktır.

kurallar

  • Kodlamada yararlı hesaplamalar yapmadığınız sürece, grafiği temsil etmek için bitişiklik matrisi, bitişiklik listesi veya kenar listesi gibi herhangi bir biçimi kullanabilirsiniz. Ayrıca, yararlıysa, girdide köşe sayısı veya köşe listesi gibi şeylere de sahip olabilirsiniz.
  • Girişteki grafiğin her zaman bir DAG (herhangi bir döngüye sahip olmadığını) varsayabilirsiniz.
  • Programınız herhangi bir girdi için teoride çalışmalıdır. Ancak, dilinizdeki temel tamsayı türünü aşarsa başarısız olabilir.
  • Köşelerin adları herhangi bir türde ardışık değerler olabilir. Örneğin: 0 veya 1'den başlayan sayılar. (Ve elbette bu sayıya kod kaydetmiyorsanız, elbette.)
  • Bu kod golfü. En kısa kod kazanır.

Misal

Bu, farklı formatlarda aynı girdidir. Programınızın hepsini kabul etmek zorunda değilsiniz. Tepe noktaları her zaman 0'dan başlayan tamsayılardır.

Adjacency list:
[ [1 2 3 5] [2 4] [] [2] [] [3] ]
Adjacency matrix:
[ [0 1 1 1 0 1] [0 0 1 0 1 0] [0 0 0 0 0 0] [0 0 1 0 0 0] [0 0 0 0 0 0] [0 0 0 1 0 0] ]
Edge list:
6 [ [0 1] [0 2] [0 3] [0 5] [1 2] [1 4] [3 2] [5 3] ]

Bu resimde gösterilen grafik:

Örnek grafik

Çıktı şöyle olmalıdır:

9

Topolojik çeşitler:

[0 1 4 5 3 2]
[0 1 5 4 3 2]
[0 1 5 3 4 2]
[0 1 5 3 2 4]
[0 5 1 4 3 2]
[0 5 1 3 4 2]
[0 5 1 3 2 4]
[0 5 3 1 4 2]
[0 5 3 1 2 4]

İşlev? Tüm Program? Ya?
isaacg

@isaacg Ya.
jimmy23013

Yanıtlar:


4

CJam - 25

q~{_f{1$-_j@j@&!*}_!+:+}j

User23013'ın büyük yardımıyla :)

Çevrimiçi deneyin

Açıklama:

Genel algoritma xnor'ın Python çözümü ile aynıdır .
Buradaki anahtar j, hafızaya alınmış özyineleme yapan operatördür. Başlangıç ​​değerleri için bir parametre, bir değer veya dizi (f (0), f (1), vb. Gibi) ve özyinelemeyi tanımlamak için bir blok alır. jOperatör aynı bloğa yinelemeli (ve memoized) çağrı yapmak için blok içinde yeniden kullanılır. Birden fazla parametre ile de kullanılabilir, ancak burada durum böyle değildir.
user23013'ün büyük yeniliği, j'yi farklı veri türleriyle kullanmaktır ve bitişiklik listesini başlangıç ​​değerleri dizisi olarak kullanır.

q~             read and evaluate the input (vertex list followed by adjacency list)
{…}j           run the block on the vertex list, doing memoized recursion
                and using the adjacency list for initial values
    _          copy the vertex list
    f{…}       for each vertex and the vertex list
        1$-    copy the vertex and remove it from the list
                Python: "V-{v}"
        _j     copy the reduced list and call the j block recursively
                this solves the problem for the reduced vertex list
                Python: "f(G,V-{v})"
        @j     bring the vertex to the top of the stack and call the j block recursively
                in this case, it's called with a vertex rather than a list
                and the memoized value is instantly found in the list of initial values
                effectively, this gets the list of vertices adjacent to the current vertex
                Python: "G[v]"
        @&     bring the reduced list to the top of the stack and intersect
        !*     multiply the number of topological sorts of the reduced vertex list
                with 1 if the intersection was empty and 0 if not
                Python: equivalent to "*(V-G[v]==V)"
               after this loop we get an array of sub-results for the reduced vertex lists
    _!+        add 1 or 0 to the array if the array was empty or not
                because we want to get 1 for the empty array
                Python: equivalent to "V<{0}or"
    :+         add the numbers in the array
                Python: "sum(…)"

1
Girdideki köşe listesine açıkça izin vermek için düzenlendi. Şimdi 25 bayt .
jimmy23013

@ user23013 Bu ne tür bir büyücülük? : o
aditsu bıraktı çünkü SE EVIL

7

Python, 58

f=lambda G,V:V<{0}or sum(f(G,V-{v})*(V-G[v]==V)for v in V)

Giriş bir bitişik sözlük Gve bir tepe noktası kümesinden oluşur V.

G = {0:{1,2,3,5}, 1:{2,4}, 2:set(), 3:{2}, 4:set(), 5:{3}, 6:set()}
V = {0,1,2,3,4,5}

Kod özyinelemelidir. Set V, hala ziyaret edilmesi gereken tüm düğümleri saklar. Bir sonraki potansiyel düğüm için, kalan köşelerin işaret V-G[v]==Vetmediğini Vve kontrol edilip G[v]ayrılmadığını görerek uygunluğunu kontrol ederiz . Bu tür tüm uygun köşeler için, çıkarıldığında topolojik çeşitlerin sayısını ekliyoruz. Temel durum olarak, boş küme 1 verir.


Kenar listesini kullanmadığınız için +1.
jimmy23013

5

Mathematica, 80 57 51 bayt

Count[Permutations@#,l_/;l~Subsets~{2}~SubsetQ~#2]&

Tanımın çok kolay uygulanması. Sadece tüm permütasyonları üretiyorum ve bunların kaç tanesinin geçerli olduğunu sayıyorum. Bir permütasyonun geçerli olup olmadığını kontrol etmek için, permütasyondaki tüm köşe çiftlerini elde ederim. Rahatça, Subsets[l,{2}]sadece bana tüm çiftleri vermekle kalmıyor, aynı zamanda içinde bulundukları sırayı da koruyor l- sadece ihtiyacım olan şey.

Yukarıda, köşe listesi ve kenar listesi gibi bir işlev beklenmektedir.

f[{1, 2, 3, 4, 5, 6}, {{1, 2}, {1, 3}, {1, 4}, {1, 6}, {2, 3}, {2, 5}, {4, 3}, {6, 4}}]

işlevi çağırırsanız f.

Bunu golf yapmaya çalışacağım, ya da daha sonra başka bir yaklaşım kullanmaya çalışacağım.


2

Pyth, 27 bayt

Mlf!sm}_dHfq2lYyTfqSZUZ^UGG

2 giriş işlevini tanımlar g,. İlk girdi köşe sayısı, ikincisi yönlendirilen kenarların listesidir.

Test etmek için:

Code:
Mlf!sm}_dHfq2lYyTfqSZUZ^UGGghQeQ

Input:
6, [ [0, 1], [0, 2], [0, 3], [0, 5], [1, 2], [1, 4], [3, 2], [5, 3] ]

Burada deneyin.


@ user23013 ^UGGTüm Ggiriş listelerini oluşturan ifadede Boht sayımı ve listesi kullanılıyor range(len(G)).
isaacg

Demek istediğim, [0, 1, ...]doğrudan girişte kullanmanız daha kısa olacak mı?
jimmy23013

@ user23013 Hayır, aynı uzunlukta olacaktır: ^GlGvs ^UGG.
isaacg

2

Haskell'in 102 107 100 89 85 bayt

import Data.List
(%)=elemIndex
n#l=sum[1|p<-permutations[0..n],and[u%p<v%p|[u,v]<-l]]

Giriş, en yüksek köşe numarası (0 ile başlayan) ve bir kenar listesidir; burada bir kenar iki elemanlı bir listedir. Kullanım örneği:5 # [[0,1], [0,2], [0,3], [0,5], [1,2], [1,4], [3,2], [5,3]]

Nasıl çalışır: tüm permütasyon saymak pbütün kenarları olan köşe [u,v]tatmin: konumu uiçinde pkonumu daha azdır viçinde p. Bu, tanımın doğrudan uygulanmasıdır.

Düzenleme: benim ilk sürümü topolojik sıralar kendilerini döndü ve kaç tane var değil. Onu düzeltti.

Düzenleme II: Köşeleri bağlı olmayan grafikler için çalışmadı. Onu düzeltti.


Sadece köşeleri olan ancak kenarları olmayan bir test çantası eklemeyi düşünüyorum ...
jimmy23013

@ user23013: Şimdi birbirine bağlı köşeleri olmayan grafikler için çalışıyor. Daha da kısaldı.
nimi
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.