Tổng số loại cấu trúc liên kết


11

Đối với một DAG nhất định (biểu đồ chu kỳ có hướng), mỗi loại cấu trúc liên kết của nó là một hoán vị của tất cả các đỉnh, trong đó đối với mọi cạnh (u, v) trong DAG, u xuất hiện trước v trong hoán vị.

Nhiệm vụ của bạn là tính tổng số loại cấu trúc liên kết của một DAG nhất định.

Quy tắc

  • Bạn có thể sử dụng bất kỳ định dạng nào để biểu thị biểu đồ, như ma trận kề, danh sách kề hoặc danh sách cạnh, miễn là bạn không thực hiện các tính toán hữu ích trong mã hóa của mình. Bạn cũng có thể có những thứ như số đỉnh hoặc danh sách đỉnh trong đầu vào, nếu những thứ đó hữu ích.
  • Bạn có thể giả sử đồ thị trong đầu vào luôn là DAG (không có bất kỳ chu kỳ nào).
  • Chương trình của bạn nên hoạt động trên lý thuyết cho bất kỳ đầu vào. Nhưng nó có thể thất bại nếu nó vượt quá kiểu số nguyên cơ bản trong ngôn ngữ của bạn.
  • Tên của các đỉnh có thể là bất kỳ giá trị liên tiếp trong bất kỳ loại nào. Ví dụ: các số bắt đầu từ 0 hoặc 1. (Và chỉ khi bạn không lưu trữ mã trong số này, tất nhiên.)
  • Đây là môn đánh gôn. Mã ngắn nhất sẽ thắng.

Thí dụ

Đây là cùng một đầu vào trong các định dạng khác nhau. Chương trình của bạn không phải chấp nhận tất cả chúng. Các đỉnh luôn là số nguyên bắt đầu từ 0.

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] ]

Đó là biểu đồ hiển thị trong hình ảnh này:

Biểu đồ ví dụ

Đầu ra phải là:

9

Các loại cấu trúc liên kết là:

[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]

Chức năng? Toàn bộ chương trình? Hoặc?
isaacg

@isaacg Hoặc.
jimmy23013

Câu trả lời:


4

CJam - 25

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

Với sự giúp đỡ tuyệt vời từ user23013 :)

Dùng thử trực tuyến

Giải trình:

Thuật toán chung giống như trong giải pháp Python của xnor .
Chìa khóa ở đây là jtoán tử, đệ quy ghi nhớ. Nó nhận một tham số, một giá trị hoặc mảng cho (các) giá trị ban đầu (như trong f (0), f (1), v.v.) và một khối để xác định đệ quy. Các jnhà điều hành được sử dụng một lần nữa bên trong khối để thực hiện cuộc gọi đệ quy (và memoized) để cùng một khối. Nó cũng có thể được sử dụng với nhiều tham số, nhưng không phải ở đây.
Cải tiến lớn của user23013 là sử dụng j với các loại dữ liệu khác nhau, sử dụng danh sách kề là mảng các giá trị ban đầu.

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
Chỉnh sửa để rõ ràng cho phép danh sách đỉnh trong đầu vào. Bây giờ 25 byte .
jimmy23013

@ user23013 Đây là loại phép thuật gì? : o
aditsu bỏ vì SE là EVIL

7

Con trăn, 58

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

Đầu vào bao gồm một từ điển kề Gvà một tập đỉnh 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}

Mã được đệ quy. Bộ Vlưu trữ tất cả các nút vẫn cần truy cập. Đối với mỗi nút tiềm năng tiếp theo, chúng tôi kiểm tra sự phù hợp của nó bằng cách xem liệu không có đỉnh nào còn lại trỏ đến nút đó hay không, với V-G[v]==Vviệc kiểm tra xem VG[v]có phân biệt không. Đối với tất cả các đỉnh phù hợp như vậy, chúng tôi thêm số lượng các loại cấu trúc liên kết với nó được loại bỏ. Như một trường hợp cơ sở, tập hợp trống cho 1.


+1 vì không sử dụng danh sách cạnh.
jimmy23013

5

Toán học, 80 57 51 byte

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

Thực hiện rất thẳng về định nghĩa. Tôi chỉ tạo ra tất cả các hoán vị và đếm xem có bao nhiêu trong số chúng là hợp lệ. Để kiểm tra xem một hoán vị có hợp lệ không, tôi lấy tất cả các cặp đỉnh trong hoán vị. Thuận tiện, Subsets[l,{2}]không chỉ cung cấp cho tôi tất cả các cặp, nó cũng duy trì thứ tự chúng được tìm thấy trong l- chỉ những gì tôi cần.

Trên đây là một chức năng mong đợi danh sách đỉnh và danh sách cạnh, như

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

nếu bạn gọi hàm f.

Tôi sẽ cố gắng đánh gôn này, hoặc có thể sử dụng một cách tiếp cận khác sau.


2

Bình thường, 27 byte

Mlf!sm}_dHfq2lYyTfqSZUZ^UGG

Xác định hàm 2 đầu vào , g. Đầu vào đầu tiên là số đỉnh, thứ hai là danh sách các cạnh được định hướng.

Để kiểm tra:

Code:
Mlf!sm}_dHfq2lYyTfqSZUZ^UGGghQeQ

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

Hãy thử nó ở đây.


@ user23013 Số đếm và danh sách Boht đang được sử dụng, trong biểu thức ^UGG, tạo ra tất cả các Gdanh sách mục nhập của range(len(G)).
isaacg

Ý tôi là, nó sẽ ngắn hơn nếu bạn sử dụng [0, 1, ...]trực tiếp trong đầu vào?
jimmy23013

@ user23013 Không, nó sẽ là như nhau chiều dài: ^GlGvs ^UGG.
isaacg

2

Haskell, 102 107 100 89 85 byte

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

Đầu vào là số đỉnh cao nhất (bắt đầu bằng 0) và danh sách cạnh, trong đó cạnh là danh sách hai phần tử. Ví dụ sử dụng:5 # [[0,1], [0,2], [0,3], [0,5], [1,2], [1,4], [3,2], [5,3]]

Cách thức hoạt động: đếm tất cả các hoán vị pcủa các đỉnh mà tất cả các cạnh [u,v]thỏa mãn: vị trí của utrong pnhỏ hơn vị trí của vtrong p. Đó là một thực hiện trực tiếp của định nghĩa.

Chỉnh sửa: phiên bản đầu tiên của tôi trả về các loại cấu trúc liên kết và không có bao nhiêu. Đã sửa nó.

Chỉnh sửa II: không hoạt động đối với các biểu đồ không có đỉnh được kết nối. Đã sửa nó.


Tôi đang nghĩ đến việc thêm một trường hợp thử nghiệm chỉ có các đỉnh chứ không phải các cạnh ...
jimmy23013

@ user23013: hiện hoạt động cho các biểu đồ không có đỉnh được kết nối. Nó thậm chí còn trở nên ngắn hơn.
nimi
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.