Когда списки смежности или матрицы являются лучшим выбором?

15

Мне сказали, что мы будем использовать список, если граф разреженный, и матрицу, если граф плотный . Для меня это просто грубое определение. Я не вижу многого за этим. Можете ли вы уточнить, когда это будет естественным выбором?

Заранее спасибо!

user21312
источник
Это не определение, в основном потому, что не существует единого определения понятий «разреженный» и «плотный». Кроме того, есть и другие соображения, например, к каким аспектам графа вы обращаетесь как часто.
Рафаэль
@ Рафаэль Можете ли вы рассказать подробнее о других соображениях?
user21312
1
@ user21312, большая разница - итеративность и доступ к краям. Если вам часто нужно перебирать края, то список приставок может быть более полезным. Если вам часто нужно определить, существует ли ребро или получить доступ к его весу (или другой информации), тогда матрица может быть лучше.
Райана
Для вашей цели мы, вероятно, могли бы небрежно относиться к определению «разреженный» и «плотный». Просто смоделируйте временную сложность работы матрицы, которую вы хотите использовать для каждого типа структуры данных, и посмотрите, где находится «точка разрыва плотности». Я думаю, что вторая ссылка @ryan пытается сделать нечто подобное
Apiwat Chantawibul

Ответы:

17

Прежде всего, обратите внимание, что разреженный означает, что у вас очень мало ребер, а плотный означает много ребер, или почти полный граф. В полном графе у вас есть ребер, где n - количество узлов.n(n1)/2n

Теперь, когда мы используем матричное представление, мы выделяем матрицу для хранения информации о соединении узлов, например, M [ i ] [ j ] = 1, если между узлами i и j есть ребро , в противном случае M [ i ] [ j ] = 0 . Но если мы используем список смежности, то у нас есть массив узлов, и каждый узел указывает на свой список смежности, содержащий ТОЛЬКО соседние узлы .n×nM[i][j]=1ijM[i][j]=0

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

Но если граф плотный, то число ребер близко к (полному) или к n 2, если граф направлен с помощью самоконтроля. Тогда нет преимущества использования списка смежности над матрицей.n(n1)/2n2

С точки зрения сложности пространства
Матрица смежности: Список смежности: O ( n + m ) где n - количество узлов, - количество ребер.O(n2)
O(n+m)
nm

Когда граф является неориентированным деревом, тогда
матрица смежности: Список смежности: равно (лучше, чем )O(n2)
O(n+n)O(n)n2

Когда график направлен, завершен, с самопетлями, тогда
матрица смежности: Список смежности: есть (без разницы)O(n2)
O(n+n2)O(n2)

И, наконец, когда вы реализуете использование матрицы, проверка наличия грани между двумя узлами занимает раз, в то время как со списком смежности это может занять линейное время по n .O(1)n

fade2black
источник
«хотя со списком смежности это может занять линейное время» - учитывая, что в вашем списке смежности (вероятно) отсутствует какой-либо естественный порядок, почему это список вместо хэш-набора?
Кевин
1
@Kevin Тогда это будет называться «хэш смежности» вместо «список». Также возможно, почему нет? Но если вы просто выполняете DFS или BFS, или какую-то другую процедуру, которая систематически сканирует все узлы, то в чем преимущество использования хэширования над списком? В любом случае вы бы осмотрели все соседние узлы.
fade2black
3
Я бы добавил, что в невзвешенном неориентированном случае для почти полного графа может быть более целесообразно хранить его дополнение, то есть разреженный граф. Поэтому матрица полезна, когда присутствует примерно половина ребер.
М. Зима
3

Чтобы ответить, приведем простую аналогию. Если бы вам пришлось хранить 6 унций воды, вы бы (вообще говоря) сделали это с контейнером на 5 галлонов или чашкой на 8 унций?

Теперь вернемся к вашему вопросу. Если большая часть вашей матрицы пуста, то зачем ее использовать? Просто перечислите каждое значение вместо этого. Однако, если ваш список очень длинный, почему бы не использовать матрицу для его сжатия?

В этом случае аргументация списка против матрицы действительно так проста.

PS список - это просто матрица из одного столбца !!! (пытаюсь показать вам, насколько произвольно это решение / сценарий)

Чарльз
источник
2

NEN2

Сколько бит на самом деле вам нужно?

NE(N2E)log2(N2E)

EN22

E=N22log2(N2E)=N2+o(N2)EN2

log2(N2E)
=log2(N2)!E!(N2E)!
=2Elog2N+O(low order terms)

log2N2E

p=EN2log2p(1p)p12

Псевдоним
источник