인접 목록 또는 행렬이 더 나은 선택은 언제입니까?


15

그래프가 희소 한 경우 목록을 사용 하고 그래프가 밀도높은 경우 행렬을 사용하겠다고 들었습니다 . 나를 위해, 그것은 단지 원시 정의입니다. 나는 그 이상을 보지 못합니다. 언제 자연스럽게 선택해야하는지 명확히 할 수 있습니까?

미리 감사드립니다!



"sparse"와 "dense"에 대한 단일 정의가 없기 때문에 이는 정의가 아닙니다. 또한 그래프의 어떤 측면에 얼마나 자주 액세스하는지와 같은 다른 고려 사항도 있습니다.
라파엘

@Raphael 다른 고려 사항에 대한 자세한 내용을 볼 수 있습니까?
user21312

1
@ user21312에서 큰 차이점은 반복성 대 가장자리 액세스입니다. 가장자리를 자주 반복 해야하는 경우 adj list가 더 유용 할 수 있습니다. 가장자리가 존재하는지 또는 그 무게 (또는 다른 정보)에 액세스해야하는 경우가 종종 있으면 행렬이 더 좋습니다.
ryan

당신의 목적을 위해, 우리는 아마도 'sparse'와 'dense'의 정의가 무엇인지에 대해 부주의 할 수 있습니다. 각 유형의 데이터 구조에 사용하려는 매트릭스 연산의 시간 복잡성을 모델링하고 '밀도의 중단 점'이 어디에 있는지 확인하십시오. @ryan의 두 번째 링크가 비슷한 것을 시도하고 있다고 생각합니다.
Apiwat Chantawibul

답변:


17

우선 희소 는 가장자리가 거의 없음을 의미 하고, 밀도 는 많은 가장자리 또는 거의 완전한 그래프를 의미합니다. 완전한 그래프에서 edge를 가지며, 여기서 n 은 노드 수입니다.n(n1)/2n

이제 행렬 표현을 사용할 때 노드 연결 정보를 저장하기 위해 행렬을 할당 합니다. 예를 들어 노드 ij 사이에 가장자리가 있으면 M [ i ] [ j ] = 1 이고 , 그렇지 않으면 M [ i ] [ j ] = 0 . 그러나 인접 목록을 사용하면 노드 배열이 있고 각 노드 는 인접 노드 만 포함하는 인접 목록 가리 킵니다 .n×nM[i][j]=1ijM[i][j]=0

그래프가 희박하고 행렬 표현을 사용하는 경우 대부분의 행렬 셀은 사용되지 않은 채로 남아있어 메모리 낭비로 이어집니다. 따라서 일반적으로 희소 그래프에는 행렬 표현을 사용하지 않습니다. 인접 목록을 선호합니다.

그러나 그래프가 밀도가 높으면 가장자리 수는 (완전한) 또는 그래프가 자체 루프를 사용하는 경우 n 2에 가깝습니다 . 그러면 행렬보다 인접 목록을 사용하는 이점이 없습니다.n(n1)/2n2

공간 복잡성 측면에서
인접 행렬 : 인접 목록 : O ( n + m ) 여기서 n 은 숫자 노드이고 m 은 모서리 수입니다.O(n2)
O(n+m)
nm

그래프가 방향이 지정되지 않은 트리 인 경우
인접 행렬 : 인접리스트 : O ( n + n )O ( n ) ( n 2 보다 낫습니다 )O(n2)
O(n+n)O(n)n2

그래프가 지시되고, 자체 루프와 함께 완성되면
인접 행렬 : 인접리스트 : O ( n + n 2 )O ( n 2 )입니다 (차이 없음).O(n2)
O(n+n2)O(n2)

마지막으로 행렬을 사용하여 구현 할 때 두 노드 사이에 가장자리가 있는지 확인하는 데 시간 이 걸리고 인접 목록을 사용하면 선형 시간이 n 단위로 걸릴 수 있습니다 .O(1)n


"인접 목록이있는 동안 선형 시간이 걸릴 수 있습니다."-인접 목록에 자연 순서가없는 경우 해시 세트가 아닌 왜 목록입니까?
Kevin

1
@Kevin 그런 다음 "list"대신 "adjacency hash"라고합니다. 왜 가능합니까? 그러나 DFS 또는 BFS 또는 체계적으로 모든 노드를 스캔하는 다른 절차를 수행하는 경우 해시 오버 목록을 사용하면 어떤 이점이 있습니까? 어쨌든 모든 인접 노드를 검사합니다.
fade2black

3
나는 가중치가 부여되지 않은 무 방향의 경우 거의 완전한 그래프의 경우 보완, 즉 희소 그래프를 저장하는 것이 더 가능할 수 있다고 덧붙입니다. 따라서 대략 절반의 가장자리가 존재할 때 행렬이 유용합니다.
M. Winter

3

간단한 유추를 제공하여 대답하기 위해. 6oz의 물을 저장해야한다면, 5 갤런 용기 또는 8oz 컵으로 그렇게 하시겠습니까?

이제 질문으로 돌아갑니다. 행렬의 대부분이 비어 있으면 왜 사용합니까? 대신 각 값을 나열하십시오. 그러나 목록이 실제로 긴 경우 행렬을 사용하여 요약하지 않는 이유 는 무엇입니까?

목록과 행렬의 추론은 실제로이 경우 간단합니다.

P.S. a list is really just a single column matrix!!! (trying to show you just how arbitrary of a decision/scenario this is)


2

Consider a graph with N nodes and E edges. Ignoring low-order terms, a bit matrix for a graph uses N2 bits no matter how many edges there are.

How many bits do you actually need, though?

Assuming that edges are independent, the number of graphs with N nodes and E edges is (N2E). The minimum number of bits required to store this subset is log2(N2E).

We will assume without loss of generality that EN22, that is, that half or fewer of the edges are present. If this is not the case, we can store the set of "non-edges" instead.

If E=N22, log2(N2E)=N2+o(N2), so the matrix representation is asymptotically optimal. If EN2, using Stirling's approximation and a little arithmetic, we find:

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

If you consider that log2N is the size of an integer which can represent a node index, the optimal representation is an array of 2E node ids, that is, an array of pairs of node indexes.

Having said that, a good measure of sparsity is the entropy, which is also the number of bits per edge of the optimal representation. If p=EN2 is the probability that an edge is present, the entropy is log2p(1p). For p12, the entropy is 2 (i.e. two bits per edge in the optimal representation), and the graph is dense. If the entropy is significantly greater than 2, and in particular if it's close to the size of a pointer, the graph is sparse.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.