Знайдіть набір максимально узгоджуваних ребер


13

Розглянемо пов'язаний непрямий графік. Відповідний набір ребер на цьому графіку визначається як набір ребер таким чином, що жоден з двох ребер у множині не має спільної вершини. Наприклад, ліва цифра позначає відповідний набір зеленим кольором, тоді як права цифра позначає невідповідний набір червоним кольором.

введіть тут опис зображення

Кажуть, що збігається набір maximally matching, або maximal matchingякщо неможливо додати інший край графіка до відповідного набору. Отже, обидва приклади, наведені вище, - це не максимальні відповідні множини, але обидва наведені нижче набори синього кольору - це максимальні відповідники. Зауважте, що максимальні відповідники не обов'язково є унікальними. Крім того, не потрібно вимагати, щоб розмір кожного можливого максимального відповідності для графа дорівнював іншому збігу.введіть тут опис зображення

Мета цього завдання - написати програму / функцію, щоб знайти максимальну відповідність графіка.

Вхідні дані

Припустимо, що всі вершини вхідного графіка мають деяку послідовну цілу нумерацію, починаючи з будь-якого початкового цілого значення на ваш вибір. Ребро описується не упорядкованою парою цілих чисел, що позначають вершини, з якими з'єднується край. Наприклад, графік, показаний вище, може бути описаний із наступним не упорядкованим набором ребер (якщо припустити, що нумерація вершин починається з 0):

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

Альтернативний спосіб опису графіка - це список суміжності. Ось приклад списку сумісності для наведеного вище графіка:

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

Ваша програма / функція повинна приймати як вхідний графік з будь-якого джерела (stdio, параметр функції тощо). Ви можете використовувати будь-які потрібні позначення до тих пір, поки додаткова нетривіальна інформація не буде передана вашій програмі. Наприклад, наявність додаткового параметра, що позначає кількість вхідних ребер, цілком прийнятна. Аналогічно, добре проходити в не упорядкованому безлічі ребер, списку суміжності або матриці суміжності.

Ви можете припустити:

  1. Графік пов'язаний (наприклад, можна досягти будь-якої вершини з будь-якою початковою вершиною).
  2. Є хоча б один край.
  3. Край ніколи не з'єднує вершину безпосередньо до себе (наприклад, край (1,1)не буде вказаний як вхідний). Зауважте, що цикли все ще можливі (напр .: наведені вище графіки).
  4. Вам може знадобитися, щоб вершини введення починалися з будь-якого індексу (наприклад, перша вершина може бути 0, 1, -1 тощо).
  5. Нумерація вершин послідовно збільшується від обраного вихідного індексу (напр .: 1,2,3,4,...або 0,1,2,3,...).

Вихідні дані

Ваша програма / функція повинна виводити список ребер, що позначають максимальний набір відповідності. Ребро визначається двома вершинами, які з'єднують цей край. Вих. вихід для лівого синього набору (використовуючи приклад впорядкування вершин вхідних даних):

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

Зауважте, що порядок вершин не важливий; Отже, наступний вихід описує той самий набір відповідності:

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

Виходом може бути stdout, файл, значення повернення функції тощо.

Приклади

Ось кілька прикладів входів (використовуючи формат списку суміжності). Ці приклади трапляються для початку підрахунку вершин на 0.

Зауважте, що прикладів не наведено, натомість я включив код перевірки 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)]

Перевірка коду Python 3

Ось код перевірки Python 3, який містить графік та набір ребер та друкує, чи відповідає цей набір максимально чи ні. Цей код працює з будь-яким індексом вершини початку.

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

Приклад використання:

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

Оцінка балів

Це код гольфу; виграє найкоротший код. Застосовуються стандартні лазівки. Ви можете використовувати будь-які бажані вбудовані модулі.

Відповіді:


9

CJam (16 символів)

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

Демонстрація в Інтернеті

Це жадібний підхід, який накопичує краї, які не мають спільної вершини з раніше накопиченими ребрами.


Я впевнений, що це не вдається на третьому прикладі, даючи [[0 1] [3 4]]замість максимального набору [[0 2] [1 4] [3 5]]. (Я (1, 1)
ігнорую

@ETHproductions, ви плутаєте максимальний з максимальним.
Пітер Тейлор

3
Dangit, вибачте з цього приводу ... Я просто залишу свій коментар, щоб допомогти іншим, хто заплутався, якщо ви не заперечуєте, оскільки це, здається, є повторюваною проблемою :-P
ETHproductions

7

Pyth , 8 байт

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)

Спробуйте в Інтернеті!

Технічні характеристики

  • Вхід: [(0,1), (0,2), (1,3), (1,4), (2,3), (3,4), (3,5), (5,6)]
  • Вихід: [(1, 4), (2, 3), (5, 6)]

6

Мова Вольфрам, 25 22 байт

Збережено 3 байти завдяки @MartinEnder

FindIndependentEdgeSet

Це приймає введення як Graphоб'єкт (визначається як Graph[{1<->2,2<->3,1<-3>}]і т.д.)


Вам це не потрібно @#&.
Мартін Ендер

@MartinEnder Дякую
Скотт Мілнер

Pfft. import solve_problem; run(). Тепер комусь просто потрібно написати плагін для Wolfram, який бере URL-адресу виклику codegolf і видає потрібний вихід. Назвіть це Golf.
Draco18s більше не довіряє SE

5

Брахілог , 5 байт

 ⊇.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

Спробуйте в Інтернеті!

Це гарантовано максимально, оскільки Брахілог здійснює пошук із найбільшого підмножини.


Я думаю, що ваше пояснення має інший код, ніж ваш фактичний код.
Ерік Аутгольфер

@EriktheOutgolfer Це тому, що я вставив символи, явні в моєму поясненні. Оригінальний код знаходиться в першому рядку. Брахілог досить лаконічний у цьому аспекті.
Leaky Nun

Я цього не маю на увазі, але перший код закінчується ≠∧, а другий - L≠.
Ерік Аутгольфер

Без цього .в кінці буде неявна . Тут усе означає, що .це не потрібно вставляти в кінці.
Leaky Nun

Це Lтимчасова змінна, яка ніде не використовується, отже, її здатність опускатись.
Leaky Nun

0

JavaScript (ES6), 67 байт

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

Використовує жадібний підхід для досягнення максимальної гольфності.


0

JavaScript (ES6), 68 66 байт

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

Я подумав, що я дам рекурсивному підходу, і, вкравши встановлений фокус на перехрестя @ ETHproduction, мені вдалося підірвати його відповідь!

Я не був першим, хто неправильно прочитав початкове запитання, і я збирався подати наступну рекурсивну функцію, яка знаходить максимальний набір ребер, що відповідають, а не набір максимальних ребер узгодження. Тонка різниця, я знаю!

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

Простий рекурсивний підхід. Для кожного елемента введення видаляє всі суперечливі ребра з набору і знаходить максимальний набір узгоджуючих ребер решти підмножини, а потім знаходить максимальний результат по кожному вхідному елементу. Дещо неефективний для великих наборів (можливе 9-байтове прискорення).


0

Желе , 12 11 байт

FQ⁼F
ŒPÇÐfṪ

Спробуйте в Інтернеті!

Зразок введення: [0,1],[0,2],[1,3],[1,4],[2,3],[3,4],[3,5],[5,6]

Вибірка зразка: [[1, 4], [2, 3], [5, 6]]

Як це працює

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)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.