2011-02-09 4 views
5

나는 C로 수치 시뮬레이션을위한 프로그램을 작성하고 있습니다. 시뮬레이션의 일부는 서로 다른 노드에 약간의 부동 소수점 값을 갖는 공간적으로 고정 된 노드입니다. 그것은 유향 그래프와 같습니다. 그러나 두 노드가 너무 멀리 떨어져 있으면 (컷 - 오프 길이 a보다 멀리)이 값은 0입니다.C에서 거대한 행렬을 구현하는 방법

이 모든 "상관 관계"또는 부동 값을 나타 내기 위해 2D 배열을 사용하려고 시도했지만 저는 100.000 이상의 노드를 가지고 있는데, 이것은 40GB 메모리 정도에 해당합니다.

이제 저는 그 문제에 대한 다른 해결책을 생각하려고합니다. 나는이 모든 값을 하드 디스크에 저장하고 싶지 않습니다. 나는 또한 그들을 즉시 계산하고 싶지 않다. 하나의 아이디어는 Matlab에서 사용할 수있는 것과 같은 일종의 희소 행렬이었습니다.

다른 값,이 값을 저장하는 방법이 있습니까?

저는 C가 처음이므로 너무 많은 경험을 기대하지 마십시오.

감사와 안부, 월 올리버

+2

키가 (행 x 열) 인 해시/맵의 경우는 어떻습니까? 0이 아닌 값을 가진 행렬 항목만큼 많은 요소가 있습니다. –

+0

정말 구체적인 질문이 아닙니다 ... 예, 매트릭스가 희박합니다. 일부 알고리즘을 찾아 보겠습니다. 매트릭스의 nulll 노드 비율에 대한 세부 정보 또는 시뮬레이션에 대한 자세한 정보가있는 경우 다른 사람이 그레이 표현 이외의 다른 솔루션을 제안 할 수 있습니다. – pascal

+0

... 예를 들어,이 행렬로 무엇을하고 싶습니까? – pascal

답변

4

주어진 노드의 차단 거리 내에 평균적으로 몇 개의 노드가 있는지 확인하여 메모리 요구 사항을 결정하고 디스크에 페이지해야하는지 여부를 알려줍니다. 최소한의 메모리를 차지하는 솔루션은 아마도 한 쌍의 노드를 거리에 매핑하는 해시 테이블 일 것입니다. 거리가 각면에서 동일하기 때문에 해시 테이블에 한 번만 입력하면됩니다. 두 개의 노드 번호를 숫자 순서대로 놓은 다음 결합하여 해시 키를 만듭니다. 이상적인 것은 아니지만 해시 테이블에 Posix hsearch/hcreate/hdestroy 함수를 사용할 수 있습니다.

+0

이는 좋은 생각입니다. 하나의 노드는 평균적으로 다른 노드의 0.2 %에 연결됩니다. 이것은 매개 변수에 따라 다릅니다. – janoliver

+0

그러나 조회 프로세스의 성능에 조금 걱정이됩니다. 그것은 실제로 행렬/해시 맵의 생성보다 훨씬 중요합니다. 왜냐하면 후자는 한 번만 수행되기 때문입니다 ... – janoliver

+0

@janoliver 그래서 100,000 개의 노드 중 200 개입니까? 속도 : 해시 조회는 O (1)이지만 일정 시간이 길어질 수 있습니다 (특히 메모리 부족시). (얼마를 가지고 있나?) 가장 좋은 방법은 각 노드가 노드 번호별로 정렬 된 근처 노드 목록을 포함하는 노드 배열 일 것입니다. 이진 검색은 200 노드에 대해 약 9 번의 비교를 수행합니다. 이것은 쉽게 구현할 수 있으며 필요할 때만 다른 것을 고려할 수도 있습니다. –

0

가능한 경우 스파 스 매트릭스를 사용해야합니다. scipy에서는 스파 스 매트릭스에 대한 지원을 제공하므로 파이썬으로 재생할 수 있습니다. 솔직히 말해서 거친 지원은 여전히 ​​거친 모서리를 가지고 있습니다.

matlab에 액세스 할 수 있다면 확실히 ATM이 좋을 것입니다.

스파 스 매트릭스를 사용하지 않으면 memap 기반 배열을 사용하여 40GB의 RAM이 필요하지 않지만 느린 속도를 유지할 수 있으며 낮은 수준의 희박성이있는 경우에만 실제로 이해할 수 있습니다 (100000x100000 행렬의 10-20 %에 항목이 있으면 전체 배열이 실제로 더 빨라지고 어쩌면 희소 행렬보다 적은 공간을 차지할 것입니다).

2

스파 스 인접성 매트릭스는 하나의 아이디어이거나 인접성 목록을 사용할 수 있으므로 잘라내 기 값보다 가까운 가장자리 만 저장할 수 있습니다.

+0

안녕하세요 짐, 아이디어를 주셔서 감사합니다. 이 목록을 간략히 살펴본 후에는 두 개의 인덱스로 참조되는 간단한 float 값이이 목록 항목 중 하나보다 메모리 소비가 적습니다. – janoliver

1

또한이 노드와 관련된 다른 노드를 포함하는 각 노드에 대한 목록을 보유 할 수도 있습니다. 그러면 목록 항목의 전체 수가 2 * k이됩니다. 여기서 k은 가상 행렬의 0이 아닌 값의 수입니다.

전체 시스템을 해시/세트/맵의 조합으로 구현하는 것은 임의 액세스를 허용하는 "실제"매트릭스와 비교하여 속도/성능면에서 여전히 받아 들여질 것으로 예상됩니다.

편집 :이 솔루션은 스파 스 매트릭스 구현의 한 가지 가능한 형태입니다. (아래의 짐 발터의 노트를 참고하십시오.) 감사합니다, 짐.)

+0

확실히 2 (k-1) 노드 자체에 연결되지 않기 때문에? 주요 질문에 대한 내 의견을 참조하십시오, 나는 이것이 그것을 해결하는 방법입니다 동의합니다. – SlappyTheFish

+0

목록의 각 항목이 노드 번호와 0이 아닌 거리를 포함하는 각 노드의 목록은 폼 스파 스 행렬이며 각 노드 목록은 행 (또는 열)입니다. –

+0

@ SlappyTheFish Flinsch는 "k는 가상 행렬의 0이 아닌 값의 수입니다"- 대각선은 가상 행렬에서 모두 0이므로 k는 이미 해당 항목을 제외합니다. 목록에는 실제로 k 항목이 포함됩니다. 여기서 각 항목에는 노드 번호와 거리의 두 값이 있습니다. –

관련 문제