Kromatik Numarayı Bulun


13

Şaşırtıcı bir şekilde, grafik boyama konusunda henüz herhangi bir zorluk yaşamadık!

Yönlendirilmemiş bir grafik verildiğinde, her köşeye iki bitişik köşe aynı rengi paylaşmayacak şekilde bir renk verebiliriz. Küçük sayı χ , bunun için gereken farklı renkler olarak adlandırılır renk sayısı grafik.

Örneğin, asgari sayıda renk kullanarak geçerli bir renklendirme aşağıda gösterilmiştir:

(Wikipedia'da bulundu)

Bu grafiğin kromatik sayısı χ = 3'tür .

Köşe bir numara verilir bir program ya da fonksiyonu Yazın , N <16 (kadar numaralandırılmış olan 1 ile N ) ve bir kenar listesinin, bir grafiğin renk sayısını belirler.

Girdi önceden işlenmediği sürece girdiyi alabilir ve çıktıyı istediğiniz formatta üretebilirsiniz. Yani, bir dize veya dizi kullanabilir, dizeye uygun sınırlayıcılar ekleyebilir veya iç içe dizi kullanabilirsiniz, ancak ne yaparsanız yapın, düzleştirilmiş yapı aşağıdaki örneklerle aynı sayıları içermelidir (aynı sırayla).

Yerleşik grafik teorisi ile ilgili işlevleri (Mathematica'nınki gibi ChromaticNumber) kullanamazsınız .

Grafiğin renklendirilemez olmasını sağlayacağı için grafiğin hiç döngüsü olmadığını (bir tepe noktasını kendisiyle birleştiren bir kenar) olduğunu varsayabilirsiniz.

Bu kod golf, en kısa cevap (bayt cinsinden) kazanır.

Örnekler

Programınız en azından bunların tümünü makul bir sürede çözmelidir. (Tüm girişleri doğru bir şekilde çözmelidir, ancak daha büyük girişler için daha uzun sürebilir.)

Gönderiyi kısaltmak için, aşağıdaki örneklerde, kenarları virgülle ayrılmış tek bir listede sunuyorum. Bunun yerine, satır sonlarını kullanabilir veya girdiyi isterseniz uygun dizi biçiminde bekleyebilirsiniz.

Üçgen (χ = 3)

3
1 2, 2 3, 1 3

6 köşeli "Halka" (χ = 2)

6
1 2, 2 3, 3 4, 4 5, 5 6, 6 1

5 köşeli "Halka" (χ = 3)

5
1 2, 2 3, 3 4, 4 5, 5 1

Yukarıdaki örnek resim (χ = 3)

6
1 2, 2 3, 3 4, 4 5, 5 6, 6 1, 1 3, 2 4, 3 5, 4 6, 5 1, 6 2

Yukarıdakilerin 7 köşe için genelleştirilmesi (χ = 4)

7
1 2, 2 3, 3 4, 4 5, 5 6, 6 7, 7 1, 1 3, 2 4, 3 5, 4 6, 5 7, 6 1, 7 2

Petersen grafiği (χ = 3)

10
1 2, 2 3, 3 4, 4 5, 5 1, 1 6, 2 7, 3 8, 4 9, 5 10, 6 8, 7 9, 8 10, 9 6, 10 7

5 köşenin yanı sıra bağlantısı kesilmiş tepe noktasının tam grafiği (χ = 5)

6
1 2, 1 3, 1 4, 1 5, 2 3, 2 4, 2 5, 3 4, 3 5, 4 5

8 köşenin tüm grafiği (χ = 8)

8
1 2, 1 3, 1 4, 1 5, 1 6, 1 7, 1 8, 2 3, 2 4, 2 5, 2 6, 2 7, 2 8, 3 4, 3 5, 3 6, 3 7, 3 8, 4 5, 4 6, 4 7, 4 8, 5 6, 5 7, 5 8, 6 7, 6 8, 7 8

15 köşeli üçgen kafes (χ = 3)

15
1 2, 1 3, 2 3, 2 4, 2 5, 3 5, 3 6, 4 5, 5 6, 4 7, 4 8, 5 8, 5 9, 6 9, 6 10, 7 8, 8 9, 9 10, 7 11, 7 12, 8 12, 8 13, 9 13, 9 14, 10 14, 10 15, 11 12, 12 13, 13 14, 14 15

Makul tanımlayabilir misiniz? 1 dakika? 10?
ThreeFx

@ThreeFx evet, 10 dakika makul. yarım gün değil. Sınırda çok titiz olmak istemiyorum, çünkü o zaman her şeyi aynı makinede test etmem gerekiyor. ancak makinenizde bir saat içinde tamamlanıp tamamlanmadığını varsayalım.
Martin Ender

Yanıtlar:


4

Python 2.7 - 122 109 111 109 108 103

f=lambda n,e,m=1:any(all(t*m//m**a%m!=t*m//m**b%m for(a,b)in e)for t in range(m**n))and m or f(n,e,m+1)

Kullanımı:

print f(5, [(1, 2), (2, 3), (3, 4), (4, 5), (5, 1)])

Kromatik sayıyı (m) artırarak kaba kuvvet uygulayın ve olası tüm renklendirmeleri kontrol edin. Bir renklendirme, baz m cinsinden bir sayı olarak tarif edilebilir. Böylece olası renklendirmeler 0, 1, ..., m ^ n-1'dir.

edit: 8 köşe tam grafik oldukça uzun sürer. Ama dizüstü bilgisayarım yaklaşık 10 dakika içinde çözüyor. Diğer test senaryoları sadece birkaç saniye sürer.


edit 2: Ön işleme izin verildiğini okuyun, böylece köşe indeksinin 0 ile başlamasına izin verin: t * m // m ** x% m'yi t // m ** a% m (-2) kısaltır. Lambda'yı çözün ve m'yi fonksiyon parametrelerine yerleştirin (-11)


düzenlemek 3: ön işleme olduğu değil izin -> geri t * m (+4) / için // basitleştirilmiş (-2).


düzenlemek 4: herhangi bir (-2) köşeli parantez kaldırmak, teşekkürler xnor.


edit 5: modulo m'yi iki kez almak yerine, sadece onları çıkarın ve daha sonra modulo (-1) kullanın. Bu aynı zamanda bir performans iyileştirmesidir. Tüm test kılıfları birlikte dizüstü bilgisayarımda yaklaşık 25 saniye sürüyor.


edit 6: 1: ve m + = 1 (-5) yerine özyinelemeli çağrı. Tekrar teşekkürler, xnor.


Güzel bir yöntem. Basit bir golf: all([...])Parens içinde yer alırsanız parantezleri kaldırabilirsiniz a,b(bu, boşluk nedeniyle burada hiçbir karaktere mal olmaz), böylece allek argümanlar için onları karıştırmaz. Ayrıca, mwhile döngüsünü kullanmak yerine bir sonraki en yüksek değere bir işlev çağrısı ile geri çekerseniz karakterleri kaydedebileceğinizden şüpheleniyorum .
xnor

Teşekkürler, özyinelemeli yaklaşım +2 karakter alır. A için m aralığı (n + 1) yaklaşımı.
Jakube

Ben özyinelemeli yaklaşım ile biraz optimize anyve and/orhile ve sonra bazı karakter kaydeder: f=lambda n,e,m=1:any(all(t*m//m**a%m!=t*m//m**b%m for(a,b)in e)for t in range(m**n))and m or f(n,e,m+1).
xnor

2

Java - 241 218

int k,j,c;int f(int n,int[]e){for(k=1;k<=n;k++)for(long p=0;p<x(n);p++){for(j=0,c=0;j<e.length;c=p%x(e[j])/x(e[j]-1)==p%x(e[j+1])/x(e[j+1]-1)?1:c,j+=2);if(c<1)return k;}return 0;}int x(int a){return(int)Math.pow(k,a);}

Kısıtlamalar göz önüne alındığında bunu yapmanın en belirgin yolu kaba kuvvettir. Her bir kromatik sayıyı gözden geçirin kve her rengi her bir tepe noktasına atayın. Hiçbir renk aynı renkte değilse, numaranız olur. Değilse, devam edin.

Bu, test durumu için en uzun süredir χ = 8(tam grafikler burada emilir), ancak yine de 15 saniyenin altındadır (tamam, en son düzenleme ile yaklaşık 100'ler).

Girdi, OP'lerin virgülle ayrılmış değerleriyle aynı sırada verilen köşe sayısı nve kenar köşe dizisidir e[].

Satır kesmeleri ile:

int k,j,c;
int f(int n,int[]e){
    for(k=1;k<=n;k++)
        for(long p=0;p<x(n);p++){
            for(j=0,c=0;
                j<e.length;
                c=p%x(e[j])/x(e[j]-1)==p%x(e[j+1])/x(e[j+1]-1)?1:c,
                j+=2);
            if(c<1)return k;
        }
    return 0;
}
int x(int a){return(int)Math.pow(k,a);}

Oh, ve bu da girdinin bir tür renklendirilebilir grafik olduğunu varsayar. Bir kenar v1'den v1'e dönerse veya köşeler yoksa, renklendirilemez ve 0 çıktısı çıkar. Kenarsız grafikler için de çalışır χ=1.


2

Python 3-162

Aynı kaba kuvvet yaklaşımını kullanır, ancak daha hızlı kombinasyon üretimi için itertools kütüphanesini kullanır. Oldukça sıradan makinemde 8 grafiği <1 dakika içinde çözer.

import itertools as I
def c(n,v):
 for i in range(1,n+1):
  for p in I.product(range(i),repeat=n):
   if(0==len([x for x in v if(p[x[0]]==p[x[1]])])):return i

8-grafik durumun tamamı için örnek kullanım:

print(c(8,[x for x in I.combinations(range(8), 2)]))

1

Haskell, 163 bayt

p x=f(length x)(transpose x)1
f a[b,c]d|or$map(\x->and$g x(h b)(h c))(sequence$replicate a[1..d])=d|0<1=f a b c(d+1)
g a=zipWith(\x y->a!!x/=a!!y)
h=map(flip(-)1)

Kullanım şöyle olurdu:

p [[1, 2],[2, 3],[3, 1]]

Temel kaba kuvvet yaklaşımı. Geçerliyse olası tüm renk kombinasyonlarını kontrol edin. Burada söyleyecek çok şey yok, ancak bunu daha da kısaltmak için herhangi bir ipucu duymaktan mutluluk duyuyorum;)


Köşeleri azaltmanın ve onu aktarmanın "önişleme" olarak sayıldığını söyleyebilirim. Ne "uygun herhangi bir biçim" ile aklıma vardı daha ziyade düz liste, iç içe liste, dize, uygun sınırlayıcılar ile dize, vb seçim olabilirdi ... ama düzleştirilmiş yapı meydan belirtilen ile aynı olmalıdır.
Martin Ender

@ MartinBüttner Pekala, değiştireceğim
ThreeFx

@ThreeFx all idaynıdır and, any idaynı orve any id$map f listsadece aynıdır any f list. Ayrıca, sen bir kaç şey yapabilirdi g: Eğer olarak yeniden tanımlayabilirsiniz g a=(and.).zipWith(\x y->a!!x/=a!!y), bu infix yapmak yerine girdi sırasını değiştirmek (\x->g x b c)ile g b chatta tamamen noktaları içermeyen yapabilir ve zaten iç. Bunlardan bazıları birlikte çalışmaz, bu yüzden hepsini deneyin ve en iyisini seçin :)
gururlu haskeller

1
@ MartinBüttner Bence, maaaaany bayt maliyetine sabittir. : D
ThreeFx

1
Girişteki köşe sayısı olmadan 7. örneği nasıl çözüyorsunuz?
Martin Ender
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.