Tìm số Chromatic


13

Đáng ngạc nhiên, chúng tôi chưa có bất kỳ thách thức nào về tô màu đồ thị!

Cho một đồ thị vô hướng, chúng ta có thể cung cấp cho mỗi đỉnh một màu sao cho không có hai đỉnh liền kề nào có cùng màu. Số nhỏ nhất χ của các màu riêng biệt cần thiết để đạt được điều này được gọi là số màu của đồ thị.

Ví dụ: phần sau đây cho thấy màu hợp lệ bằng cách sử dụng số lượng màu tối thiểu:

(Tìm thấy trên Wikipedia)

Vậy số màu của đồ thị này là = 3 .

Viết chương trình hoặc hàm, với một số đỉnh N <16 (được đánh số từ 1 đến N ) và danh sách các cạnh, xác định số màu của đồ thị.

Bạn có thể nhận đầu vào và tạo đầu ra ở bất kỳ định dạng thuận tiện nào, miễn là đầu vào không được xử lý trước. Nghĩa là, bạn có thể sử dụng một chuỗi hoặc một mảng, thêm các dấu phân cách thuận tiện vào chuỗi hoặc sử dụng một mảng lồng nhau, nhưng bất cứ điều gì bạn làm, cấu trúc dẹt phải chứa các số giống như các ví dụ bên dưới (theo cùng thứ tự).

Bạn không được sử dụng các hàm liên quan đến lý thuyết đồ thị tích hợp (như Mathicala's ChromaticNumber).

Bạn có thể giả sử rằng biểu đồ không có vòng lặp (một cạnh kết nối một đỉnh với chính nó) vì điều đó sẽ làm cho biểu đồ không thể xóa được.

Đây là mã golf, câu trả lời ngắn nhất (tính bằng byte) sẽ thắng.

Ví dụ

Chương trình của bạn ít nhất phải giải quyết tất cả những điều này trong một khoảng thời gian hợp lý. (Nó phải giải quyết tất cả các đầu vào một cách chính xác, nhưng có thể mất nhiều thời gian hơn cho các đầu vào lớn hơn.)

Để rút ngắn bài đăng, trong các ví dụ sau, tôi trình bày các cạnh trong một danh sách được phân tách bằng dấu phẩy. Thay vào đó, bạn có thể sử dụng ngắt dòng hoặc mong đợi đầu vào ở một số định dạng mảng thuận tiện, nếu bạn thích.

Tam giác (= 3)

3
1 2, 2 3, 1 3

"Vòng" gồm 6 đỉnh (= 2)

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

"Vòng" gồm 5 đỉnh (= 3)

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

Ví dụ hình trên (= 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

Tổng quát hóa ở trên cho 7 đỉnh (= 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

Biểu đồ Petersen (= 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

Đồ thị hoàn chỉnh gồm 5 đỉnh, cộng với đỉnh bị ngắt kết nối (= 5)

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

Đồ thị hoàn chỉnh gồm 8 đỉnh (= 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

Mạng tam giác có 15 đỉnh (= 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

Bạn có thể định nghĩa hợp lý? 1 phút? 10?
ThreeFx

@ThreeFx có, 10 phút là hợp lý. nửa ngày không. Tôi không muốn quá khắt khe về giới hạn, bởi vì sau đó tôi cần kiểm tra lại mọi thứ trên cùng một máy (của tôi). nhưng hãy nói nếu nó hoàn thành trong vòng một giờ trên máy của bạn thì tốt.
Martin Ender

Câu trả lời:


4

Con trăn 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)

Sử dụng:

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

Brute lực bằng cách tăng số lượng màu (m) và kiểm tra tất cả các màu có thể. Một màu có thể được mô tả như là một số trong cơ sở m. Vì vậy, các màu có thể là 0, 1, ..., m ^ n-1.

chỉnh sửa: Đồ thị hoàn chỉnh của 8 đỉnh mất khá nhiều thời gian. Nhưng máy tính xách tay của tôi giải quyết nó trong khoảng 10 phút. Các trường hợp thử nghiệm khác chỉ mất vài giây.


chỉnh sửa 2: Đọc rằng tiền xử lý được cho phép, vì vậy tôi để chỉ số của các đỉnh bắt đầu bằng 0: rút ngắn t * m // m ** x% m thành t // m ** a% m (-2). Hòa tan lambda và đưa m vào hàm params (-11)


chỉnh sửa 3: không cho phép tiền xử lý -> quay lại t * m (+4), đơn giản hóa // thành / (-2).


chỉnh sửa 4: xóa dấu ngoặc vuông trong bất kỳ (-2), cảm ơn xnor.


chỉnh sửa 5: thay vì lấy modulo m hai lần, chỉ cần trừ chúng và sau đó sử dụng modulo (-1). Đây cũng là một cải tiến hiệu suất. Tất cả các thử nghiệm cùng nhau mất khoảng 25 giây trên máy tính xách tay của tôi.


chỉnh sửa 6: cuộc gọi đệ quy thay vì trong khi 1: và m + = 1 (-5). Cảm ơn một lần nữa, xnor.


Phương pháp tốt đẹp. Một sân golf đơn giản: Bạn có thể loại bỏ các dấu ngoặc trong all([...])nếu bạn đặt các ô vuông a,b(chi phí không có ký tự ở đây do khoảng cách) để allkhông nhầm lẫn chúng với các đối số bổ sung. Ngoài ra, tôi nghi ngờ bạn có thể lưu ký tự nếu bạn lặp lại với lệnh gọi hàm cao nhất tiếp theo mthay vì sử dụng vòng lặp while.
xnor

Cảm ơn, cách tiếp cận đệ quy mất +2 ký tự mặc dù. A cho m trong phạm vi (n + 1) cũng có cách tiếp cận.
Jakube

Tôi đã tối ưu hóa cách tiếp cận đệ quy một chút với anyand/ormẹo, và sau đó nó lưu một số ký tự : 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);}

Cách rõ ràng nhất để làm điều này với các ràng buộc là vũ phu. Chỉ cần bước qua từng số màu kvà gán từng màu cho từng đỉnh. Nếu không có hàng xóm cùng màu, bạn có số của bạn. Nếu không, di chuyển dọc.

Việc này mất nhiều thời gian nhất cho trường hợp thử nghiệm χ = 8(đồ thị hoàn chỉnh hút ở đây), nhưng vẫn còn dưới 15 giây (ok, khoảng 100 giây với lần chỉnh sửa mới nhất).

Đầu vào là số lượng đỉnh nvà một mảng các đỉnh cạnh e[]được đưa ra theo cùng thứ tự với các giá trị được phân tách bằng dấu phẩy OP.

Với ngắt dòng:

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);}

Ồ, và điều này giả sử đầu vào là một loại biểu đồ có thể tô màu. Nếu một vòng lặp cạnh từ v1 đến v1 hoặc không có đỉnh, nó không thể được tô màu và sẽ xuất ra 0. Nó vẫn hoạt động đối với các biểu đồ không có cạnh χ=1, v.v.


2

Con trăn 3 - 162

Sử dụng cùng một cách tiếp cận brute-force, nhưng sử dụng thư viện itertools để tạo ra sự kết hợp nhanh hơn. Giải quyết 8 đồ thị hoàn chỉnh trong <1 phút trên máy khá bình thường của tôi.

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

Ví dụ sử dụng cho trường hợp 8 biểu đồ hoàn chỉnh:

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

1

Haskell, 163 byte

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)

Cách sử dụng sẽ như thế này:

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

Phương pháp vũ phu cơ bản. Kiểm tra tất cả các kết hợp màu có thể nếu chúng hợp lệ. Không có gì khác để nói ở đây ngoại trừ việc tôi rất vui khi nghe bất kỳ lời khuyên nào để rút ngắn điều này hơn nữa;)


Tôi muốn nói rằng việc giảm các đỉnh và hoán vị chúng được tính là "tiền xử lý". Điều tôi có trong đầu với "bất kỳ định dạng thuận tiện" nào là bạn có thể chọn từ danh sách phẳng, danh sách lồng nhau, chuỗi, chuỗi với các dấu phân cách thuận tiện, v.v ... nhưng cấu trúc phẳng phải giống như được chỉ định trong thử thách.
Martin Ender

@ MartinBüttner Được rồi, tôi sẽ thay đổi nó
ThreeFx

@ThreeFx all idgiống như and, any idgiống orany id$map f listgiống như chỉ any f list. Ngoài ra, bạn có thể thực hiện một số điều với g: bạn có thể xác định lại nó dưới dạng g a=(and.).zipWith(\x y->a!!x/=a!!y), làm cho nó thành phần tử, thay đổi thứ tự đầu vào để thay thế (\x->g x b c)bằng g b choặc thậm chí làm cho nó hoàn toàn không có điểm và nội tuyến. một số trong số này không hoạt động cùng nhau, vì vậy hãy thử tất cả và chọn cái tốt nhất :)
tự hào

1
@ MartinBüttner Tôi nghĩ rằng nó là cố định, với chi phí của byte maaaaany. : D
ThreeFx

1
Làm thế nào để bạn giải quyết ví dụ thứ 7 mà không có số đỉnh trong đầu vào?
Martin Ender
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.