Là đồ thị của tôi?


29

Nhiệm vụ của bạn là xác định xem một đồ thị có phẳng không.

Một đồ thị là phẳng nếu nó có thể được nhúng trong mặt phẳng, hay nói cách khác nếu nó có thể được vẽ mà không có bất kỳ cạnh chéo nào.

Đầu vào: Bạn sẽ được cung cấp một biểu đồ vô hướng trong sự lựa chọn của bạn về các định dạng sau:

  • Danh sách cạnh, ví dụ [(0, 1), (0, 2), (0, 3)]

  • Bản đồ điều chỉnh, vd {0: [1, 2, 3], 1:[0], 2:[0], 3:[0]}

  • Ma trận liền kề, vd [[0, 1, 1, 1], [1, 0, 0, 0], [1, 0, 0, 0], [1, 0, 0, 0]]

Tên nút có thể là số, chuỗi hoặc tương tự, nhưng định dạng bạn đã chọn phải có thể hỗ trợ biểu đồ tùy ý. Không đặt mã trong tên nút. Sẽ không có vòng lặp tự.

Lựa chọn tiêu chuẩn của đầu vào, bao gồm STDIN, đối số dòng lệnh và đối số hàm.

Đầu ra: Bạn nên trả về một đầu ra cụ thể cho tất cả các đồ thị phẳng và một đầu ra cụ thể khác cho tất cả các đồ thị không phẳng.

Lựa chọn tiêu chuẩn đầu ra, bao gồm STDOUT, giá trị trả về của hàm.

Ví dụ:

Mặt phẳng:

[]
[(0,1), (0,2), (0,3), (0,4), (0,5), (0,6)]
[(0,1), (0,2), (0,3), (1,2), (1,3), (2,3)]
[(0,2), (0,3), (0,4), (0,5), (1,2), (1,3), (1,4), (1,5), (2,3),
 (2,5), (3,4), (4,5)]

Nonplanar:

[(0,1), (0,2), (0,3), (0,4), (1,2), (1,3), (1,4), (2,3), (2,4), (3,4)]
[(0,3), (0,4), (0,5), (1,3), (1,4), (1,5), (2,3), (2,4), (2,5)]
[(0,3), (0,4), (0,6), (1,3), (1,4), (1,5), (2,3), (2,4), (2,5), (5,6), 
 (7,8), (8,9), (7,9)]

Bất kỳ chức năng nào thực hiện rõ ràng kiểm tra phẳng hoặc tham chiếu cụ thể các nhúng nhúng phẳng đều không được phép.

Đây là mã golf. Có thể mã ngắn nhất giành chiến thắng.


Câu hỏi hay!

Thật tuyệt khi đây là một vấn đề kinh điển và vẫn còn một số cách tiếp cận khả thi, bao gồm cả những cách không được sử dụng trong mã cho các mục đích thông thường.
lirtosiast

Một trường hợp thử nghiệm cho một đồ thị không được kết nối với một thành phần phẳng và một thành phần được kết nối không phẳng sẽ tốt.
Peter Taylor

@PeterTaylor Chắc chắn, tôi sẽ thêm một.
isaacg

5
@RenaeLider Xin lỗi, nhưng tôi không hiểu. Câu hỏi không liên quan gì đến số dấu phẩy động - thậm chí nó không sử dụng số, thực sự, chỉ là nhãn.
isaacg

Câu trả lời:


14

Toán học, 201 byte

f@g_:=EdgeCount@g<9||!(h=g~IsomorphicGraphQ~CompleteGraph@#&)@5&&!h@{3,3}&&And@@(f@EdgeDelete[g,#]&&f@EdgeContract[g,#]&/@EdgeList@g);And@@(f@Subgraph[g,#]&/@ConnectedComponents[g=Graph[#<->#2&@@@#]])&

Điều này đánh giá một hàm không tên, trong đó có một danh sách cạnh như

{{0, 3}, {0, 4}, {0, 5}, {1, 3}, {1, 4}, {1, 5}, {2, 3}, {2, 4}, {2, 5}}

Đây là một cách tiếp cận đệ quy không hiệu quả khủng khiếp dựa trên định lý của Wagner :

Một đồ thị hữu hạn là phẳng khi và chỉ khi nó không có K 5 hoặc K 3,3 là nhỏ.

Ở đây, K 5 là đồ thị hoàn chỉnh với 5 đỉnh và K 3,3 là đồ thị lưỡng cực hoàn chỉnh với 3 đỉnh trong mỗi nhóm. Một đồ thị A là một thứ yếu của đồ thị B nếu nó có thể được lấy từ B bằng một chuỗi các thao tác xóa cạnh và các cơn co thắt cạnh.

Vì vậy, mã này chỉ kiểm tra xem đồ thị có phải là đẳng cấu với K 5 hay K 3,3 hay không và nếu không thì nó sẽ gọi đệ quy một lần cho mỗi lần xóa hoặc co cạnh có thể.

Điều hấp dẫn là việc xóa hoặc hợp đồng các cạnh trong một thành phần của đồ thị không được kết nối sẽ không bao giờ thoát khỏi tất cả các đỉnh ở đó, vì vậy chúng ta sẽ không bao giờ tìm thấy các đẳng cấu mong muốn. Do đó, chúng tôi áp dụng tìm kiếm này cho từng thành phần được kết nối của biểu đồ đầu vào một cách riêng biệt.

Điều này hoạt động rất nhanh đối với các đầu vào nhất định, nhưng nếu bạn thêm một vài cạnh nữa, nó sẽ nhanh chóng mất thời gian thảm khốc (và cũng mất rất nhiều bộ nhớ).

Đây là một phiên bản thụt lề của f(hàm không tên sau khi nó chỉ tạo một đối tượng đồ thị từ đầu vào:

f@g_ := 
  EdgeCount@g < 9 || 
  ! (h = g~IsomorphicGraphQ~CompleteGraph@# &)@5 && 
  ! h@{3, 3} &&
  And @@ (f@EdgeDelete[g, #] && f@EdgeContract[g, #] & /@ EdgeList@g)

Và đây là chức năng chưa được đặt tên để chuyển đổi đầu vào thành biểu đồ và gọi fcho từng thành phần được kết nối:

And @@ (
  f @ Subgraph[g, #] & /@ ConnectedComponents[
    g=Graph[# <-> #2 & @@@ #]
  ]
)&

Tôi có thể lưu một vài byte bằng cách thay đổi điều kiện kết thúc từ EdgeCount@g<9sang g==Graph@{}, nhưng điều đó sẽ làm nổ đáng kể thời gian chạy. Trường hợp thử nghiệm thứ hai sau đó mất 30 giây và trường hợp cuối cùng chưa hoàn thành.


Bạn có thể thử và loại bỏ hàm được đặt tên bằng cách sử dụng #0tham chiếu đến hàm thuần nhất trong cùng.
LegionMammal978

@ LegionMammal978 Tôi biết, nhưng nó không thực sự tiết kiệm bất cứ thứ gì, vì sau đó tôi cần dấu ngoặc đơn và cũng cần gán #cho một biến gtheo cách thủ công.
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.