Мой наивный алгоритм поиска максимальной клики работает быстрее, чем алгоритм Брона-Кербоша. Что случилось?

короче, мой наивный код (в Ruby) выглядит так:

# $seen is a hash to memoize previously seen sets
# $sparse is a hash of usernames to a list of neighboring usernames
# $set is the list of output clusters

$seen = {}
def subgraph(set, adj)
    hash = (set + adj).sort
    return if $seen[hash]
    $sets.push set.sort.join(", ") if adj.empty? and set.size > 2
    adj.each {|node| subgraph(set + [node], $sparse[node] & adj)}
    $seen[hash] = true
end

$sparse.keys.each do |vertex|
    subgraph([vertex], $sparse[vertex])
end

и моя реализация Bron Kerbosch:

def bron_kerbosch(set, points, exclude)
    $sets.push set.sort.join(', ') if set.size > 2 and exclude.empty? and points.empty?
    points.each_with_index do |vertex, i|
        points[i] = nil
        bron_kerbosch(set + [vertex],
                      points & $sparse[vertex],
                      exclude & $sparse[vertex])
        exclude.push vertex
    end
end

bron_kerbosch [], $sparse.keys, []

Я также реализовал порядок поворота и вырождения, который сократил время выполнения bron_kerbosch, но недостаточно, чтобы обогнать мое начальное решение. Кажется неправильным, что это так; какое алгоритмическое понимание я упускаю? Вот это рецензия более подробно, если вам нужно увидеть полностью рабочий код. Я проверил это на псевдо-случайном устанавливает до миллиона ребер или около того.

1 ответов


Я не знаю, как вы генерируете случайные графики для своих тестов, но я полагаю, что вы используете функцию, которая генерирует число в соответствии с равномерным распределением, и, таким образом, вы получаете график, который очень однороден. Это распространенная проблема при тестировании алгоритмов на графах, очень сложно создать хорошие тестовые случаи (это часто так же сложно, как решить исходную проблему).

задача max-clique является хорошо известной NP-трудной задачей и обоими алгоритмами (наивным и Bron Kerbosch one) имеют одинаковую сложность, поэтому мы не можем ожидать глобального улучшения для всех testcase, а просто улучшения в некоторых конкретных случаях. Но поскольку вы использовали равномерное распределение для создания графика, у вас нет этого конкретного случая.

вот почему производительность обоих алгоритмов очень похожа на ваши данные. И поскольку алгоритм Bron Kerbosch немного сложнее, чем наивный, наивный быстрее.