Tìm một tập hợp các cạnh phù hợp tối đa


13

Hãy xem xét một đồ thị vô hướng được kết nối. Một tập hợp các cạnh trên biểu đồ này được định nghĩa là một tập hợp các cạnh sao cho không có hai cạnh nào trong tập hợp có chung một đỉnh. Ví dụ, hình bên trái biểu thị một bộ so khớp màu xanh lá cây, trong khi hình bên phải biểu thị một bộ không khớp màu đỏ.

nhập mô tả hình ảnh ở đây

Một bộ phù hợp được gọi là maximally matchinghoặc maximal matchingnếu không thể thêm một cạnh khác của biểu đồ vào bộ phù hợp. Vì vậy, cả hai ví dụ trên không phải là bộ khớp tối đa, nhưng cả hai bộ dưới đây có màu xanh là khớp tối đa. Lưu ý rằng kết hợp tối đa không nhất thiết phải là duy nhất. Hơn nữa, không có yêu cầu rằng kích thước của mỗi kết hợp tối đa có thể có cho một biểu đồ bằng với một kết hợp khác.nhập mô tả hình ảnh ở đây

Mục tiêu của thử thách này là viết một chương trình / hàm để tìm sự khớp tối đa của đồ thị.

Đầu vào

Giả sử tất cả các đỉnh của đồ thị đầu vào có một số đánh số nguyên liên tiếp bắt đầu từ bất kỳ giá trị số nguyên bắt đầu nào bạn chọn. Một cạnh được mô tả bởi một cặp số nguyên không có thứ tự biểu thị các đỉnh mà cạnh đó kết nối. Ví dụ, biểu đồ hiển thị ở trên có thể được mô tả với tập hợp các cạnh không có thứ tự sau đây (giả sử việc đánh số các đỉnh bắt đầu từ 0):

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

Một cách khác để mô tả biểu đồ là thông qua danh sách kề. Dưới đây là danh sách kề kề ví dụ cho biểu đồ trên:

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

Chương trình / chức năng của bạn phải lấy làm biểu đồ đầu vào từ bất kỳ nguồn nào (stdio, tham số hàm, v.v.). Bạn có thể sử dụng bất kỳ ký hiệu nào mong muốn miễn là không có thông tin không tầm thường nào được truyền đạt tới chương trình của bạn. Ví dụ, có thêm một tham số biểu thị số cạnh đầu vào là hoàn toàn chấp nhận được. Tương tự như vậy, chuyển qua một đa cạnh không có thứ tự, danh sách kề hoặc ma trận kề là tốt.

Bạn có thể giả sử:

  1. Biểu đồ được kết nối (ví dụ: có thể đạt tới bất kỳ đỉnh nào cho bất kỳ đỉnh bắt đầu nào).
  2. Có ít nhất một cạnh.
  3. Một cạnh không bao giờ kết nối một đỉnh trực tiếp với chính nó (ví dụ: cạnh (1,1)sẽ không được cung cấp làm đầu vào). Lưu ý rằng các chu kỳ vẫn có thể (ví dụ: các biểu đồ trên).
  4. Bạn có thể yêu cầu các đỉnh đầu vào bắt đầu tại bất kỳ chỉ mục nào (ví dụ: đỉnh đầu tiên có thể là 0, 1, -1, v.v.).
  5. Đánh số Vertex đang tăng liên tục từ chỉ số bắt đầu đã chọn của bạn (ví dụ: 1,2,3,4,...hoặc 0,1,2,3,...).

Đầu ra

Chương trình / chức năng của bạn sẽ xuất ra một danh sách các cạnh biểu thị một bộ khớp tối đa. Một cạnh được xác định bởi hai đỉnh mà cạnh đó kết nối. Ví dụ. đầu ra cho tập hợp màu xanh bên trái (sử dụng thứ tự đỉnh đầu vào ví dụ):

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

Lưu ý rằng thứ tự của các đỉnh không quan trọng; Vì vậy, đầu ra sau đây mô tả cùng một bộ phù hợp:

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

Đầu ra có thể là thiết bị xuất chuẩn, một tệp, giá trị trả về của hàm, v.v.

Ví dụ

Dưới đây là một vài ví dụ đầu vào (sử dụng định dạng danh sách kề). Những ví dụ này xảy ra để bắt đầu đếm đỉnh tại 0.

Lưu ý rằng không có kết quả đầu ra nào được đưa ra, thay vào đó tôi đã bao gồm mã xác thực Python 3.

[0:(1), 1:(0)]

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

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

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

Xác thực mã Python 3

Đây là mã xác thực Python 3, lấy một biểu đồ và tập hợp các cạnh và in ra xem tập hợp đó có khớp tối đa hay không. Mã này hoạt động với bất kỳ chỉ số bắt đầu đỉnh.

def is_maximal_matching(graph, edges):
    '''
    Determines if the given set of edges is a maximal matching of graph
    @param graph a graph specified in adjacency list format
    @param edges a list of edges specified as vertex pairs

    @return True if edges describes a maximal matching, False otherwise.
    Prints out some diagnostic text for why edges is not a maximal matching
    '''

    graph_vtxs = {k for k,v in graph.items()}
    vtxs = {k for k,v in graph.items()}

    # check that all vertices are valid and not used multiple times
    for e in edges:
        if(e[0] in graph_vtxs):
            if(e[0] in vtxs):
                vtxs.remove(e[0])
            else:
                print('edge (%d,%d): vertex %d is used by another edge'%(e[0],e[1],e[0]))
                return False
        else:
            print('edge (%d,%d): vertex %d is not in the graph'%(e[0],e[1],e[0]))
            return False
        if(e[1] in graph_vtxs):
            if(e[1] in vtxs):
                vtxs.remove(e[1])
            else:
                print('edge (%d,%d): vertex %d is used by another edge'%(e[0],e[1],e[1]))
                return False
        else:
            print('edge (%d,%d): vertex %d is not in the graph'%(e[0],e[1],e[0]))
            return False
        if(e[1] not in graph[e[0]]):
            print('edge (%d,%d): edge not in graph'%(e[0],e[1]))
            return False

    # check that any edges can't be added
    for v in vtxs:
        ovtxs = graph[v]
        for ov in ovtxs:
            if(ov in vtxs):
                print('could add edge (%d,%d) to maximal set'%(v,ov))
                return False

    return True

Ví dụ sử dụng:

graph = {0:[1,2], 1:[0,3,4], 2:[0,3], 3:[1,2,4,5], 4:[1,3], 5:[3,6], 6:[5]}
candidate = [(0,1),(2,3)]
is_maximal_matching(graph, candidate) // False
candidate = [(0,1),(2,3),(5,6),(0,1)]
is_maximal_matching(graph, candidate) // False
candidate = [(0,1),(2,3),(5,6)]
is_maximal_matching(graph, candidate) // True

Chấm điểm

Đây là mã golf; mã ngắn nhất thắng. Tiêu chuẩn áp dụng. Bạn có thể sử dụng bất kỳ tích hợp nào mong muốn.

Câu trả lời:


9

CJam (16 ký tự)

{M\{_2$&!*+}/2/}

Bản demo trực tuyến

Đây là một cách tiếp cận tham lam, tích lũy các cạnh không có bất kỳ đỉnh nào chung với các cạnh được tích lũy trước đó.


Tôi khá chắc chắn rằng điều này thất bại trong ví dụ thứ ba, đưa ra [[0 1] [3 4]]thay vì tập tối đa [[0 2] [1 4] [3 5]]. (Tôi đang bỏ qua các (1, 1)cạnh dường như ở trong đó do nhầm lẫn)
ETHproductions

@ETHproductions, bạn nhầm lẫn tối đa với tối đa.
Peter Taylor

3
Xin lỗi, xin lỗi về điều đó ... Tôi sẽ chỉ để lại bình luận của tôi để giúp đỡ bất kỳ ai khác đang bối rối, nếu bạn không phiền, vì đây dường như là một vấn đề định kỳ :-P
ETHproductions

7

Bình thường , 8 byte

ef{IsTty
       y  power set (gerenate all set of edges)
      t   remove the first one (the first one is
          empty and will cause problems)
 f        filter for sets T satisfying:
     T        T
    s         flatten
  {I          is invariant under deduplicate, i.e. contains no
              duplicating vertices, as the elements represent vertices
e         pick the last one (the power set is ordered from
          smallest to largest)

Hãy thử trực tuyến!

Thông số kỹ thuật

  • Đầu vào: [(0,1), (0,2), (1,3), (1,4), (2,3), (3,4), (3,5), (5,6)]
  • Đầu ra: [(1, 4), (2, 3), (5, 6)]

6

Ngôn ngữ Wolfram, 25 22 byte

Đã lưu 3 byte nhờ @MartinEnder

FindIndependentEdgeSet

Cái này lấy đầu vào là một Graphđối tượng (được định nghĩa là Graph[{1<->2,2<->3,1<-3>}]v.v.)


Bạn không cần @#&.
Martin Ender

@MartinEnder Cảm ơn.
Scott Milner

Pfft. import solve_problem; run(). Bây giờ ai đó chỉ cần viết một plugin cho Wolfram có URL thách thức codegolf và xuất ra kết quả mong muốn. Gọi nó Golf.
Draco18 không còn tin tưởng vào

5

Brachylog , 5 byte

 ⊇.c≠∧

?⊇.cL≠   implicit ? at the beginning;
         ∧ breaks implicit . at the end;
         temporary variable inserted.
?⊇.      input is a superset of output
  .cL    output concatenated is L
    L≠   L contains distinct elements

Hãy thử trực tuyến!

Điều này được đảm bảo là tối đa, vì Brachylog tìm kiếm từ tập hợp con lớn nhất.


Tôi nghĩ rằng lời giải thích của bạn có mã khác với mã thực tế của bạn.
Erik the Outgolfer

@EriktheOutgolfer Đó là vì tôi đã chèn các ký tự ẩn trong phần giải thích của mình. Mã ban đầu là trong dòng đầu tiên. Brachylog khá ngắn gọn trong khía cạnh này.
Leaky Nun

Tôi không có ý đó, nhưng mã đầu tiên kết thúc ≠∧, trong khi mã thứ hai kết thúc L≠.
Erik the Outgolfer

Nếu không , sẽ có một ẩn .ở cuối. Tất cả các phương tiện ở đây là .không được chèn vào cuối.
Leaky Nun

Đây Llà một biến tạm thời được sử dụng ở đâu, do đó khả năng của nó bị bỏ qua.
Leaky Nun

0

JavaScript (ES6), 67 byte

let f =
a=>a.map(b=>r.some(c=>c.some(d=>~b.indexOf(d)))||r.push(b),r=[])&&r

let g = a => console.log("[%s]", f(a).map(x => "[" + x + "]").join(", "))
g([[0,1]])
g([[0,1], [0,2], [1,3], [1,4], [2,3], [3,4], [3,5], [5,6]])
g([[0,1], [0,2], [1,2], [1,3], [1,4], [1,5]])
g([[0,1], [0,2], [1,2], [1,3], [2,4], [3,4], [3,5]])

Sử dụng cách tiếp cận tham lam để chơi golf tối đa.


0

JavaScript (ES6), 68 66 byte

f=a=>a[0]?[a[0],...f(a.filter(b=>!a[0].some(c=>~b.indexOf(c))))]:a
f=([b,...a])=>b?[b,...f(a.filter(c=>!c.some(c=>~b.indexOf(c))))]:a

Tôi nghĩ rằng tôi sẽ đưa ra cách tiếp cận đệ quy, và bằng cách ăn cắp thủ thuật giao lộ của @ ETHproduction, tôi đã xoay sở để cắt xén câu trả lời của anh ấy!

Tôi không phải là người đầu tiên đọc sai câu hỏi ban đầu và tôi sắp gửi hàm đệ quy sau đây để tìm một tập hợp các cạnh phù hợp tối đa, thay vì một tập hợp các cạnh khớp tối đa. Sự khác biệt tinh tế, tôi biết!

f=a=>a.map(([b,c])=>[[b,c],...f(a.filter(([d,e])=>b-d&&b-e&&c-d&&c-e))]).sort((d,e)=>e.length-d.length)[0]||[]

Phương pháp đệ quy đơn giản. Đối với mỗi phần tử đầu vào, xóa tất cả các cạnh xung đột khỏi tập hợp và tìm tập hợp tối đa các cạnh phù hợp của tập hợp con còn lại, sau đó tìm kết quả tối đa trên mỗi phần tử đầu vào. Hơi không hiệu quả đối với các bộ lớn (có thể tăng tốc 9 byte).


0

Thạch , 12 11 byte

FQ⁼F
ŒPÇÐfṪ

Hãy thử trực tuyến!

Đầu vào mẫu: [0,1],[0,2],[1,3],[1,4],[2,3],[3,4],[3,5],[5,6]

Đầu ra mẫu: [[1, 4], [2, 3], [5, 6]]

Làm thế nào nó hoạt động

FQ⁼F    - Helper function, returns 1 if a set of edges is non-matching
F       - Flatten input
 Q      - Remove repeated elements
  ⁼     - Return boolean value. Is this equal to
   F    - The flattened input list

ŒPÇÐfṪ - Main link.
ŒP     - Power set of input list of edges
   Ðf  - Remove all elements which return 1 if
  Ç    - (Helper function) it is a non-matching set
     Ṫ - Get the last element in the resultant list (the longest). 
           Always maximal because it is the longest, so any
           edge added would not be in this list (not matching)
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.