처리해야 할 큰 행렬이 있습니다 Z
. Z
이 형식의 요소는 약 200.000 행입니다.
2 3 6 723
3 4 7 65
3 4 8 20
3 6 9 10
4 5 9 127
4 5 10 120
4 5 11 291
4 7 14 576
5 7 8 365
5 9 11 216
6 9 12 40
.....
행 반복이 없습니다. 네 번째 열은 ID 유형을 나타냅니다. 각 행의 처음 3 개 열은 오름차순으로 정렬됩니다. 행은 또한 첫 번째 열에있는 값의 오름차순입니다.
2 개의 행이 첫 번째 열에 동일한 숫자가있는 경우 첫 번째 행은 두 번째 열 에서 가장 작은 값을 가진 행입니다 . 세 번째 열에도 동일한 원칙이 적용됩니다 . 예를 들어 다음 행에서 볼 수 있습니다.
4 5 9 127
4 5 10 120
4 5 11 291
4 7 14 576
아래 형식의 행렬을 얻어야합니다. 패턴을 쉽게 볼 수 있도록 행 사이에 공백을 추가했습니다.
요약하자면, 1 열과 2 열에 행이 2 열과 3 열에있는 동일한 값 쌍을 가진 다른 모든 행이 행 바로 뒤에 와야하는 행렬을 얻어야합니다. 현재 처리되고있는 것은 매트릭스에 추가되고 다음 행은 유사한 문제로 처리됩니다.
아래에서 (3,6) 쌍을 열에 2:3
, 쌍 (3,6)을 열에 표시하십시오 1:2
. 쌍 (4,7)도 동일합니다. 쌍 (4,8)과 일치하지 않습니다.
2 3 6 723
3 6 9 10
3 4 7 65
4 7 14 576
3 4 8 20
4 5 9 127
5 9 11 216
4 5 10 120
4 5 11 291
5 7 8 365
6 9 12 40
크기를 고려할 때 매우 느린 다음 코드 Z
가 있습니다.
에서 T
행 인덱스를 수집하고 Z
있습니다. 30 분 넘게 걸렸기 때문에 완전히 실행되지 않았고, 안타깝게도 그러한 실행 시간으로는 쓸모가 없을 것입니다.
결국 나는 answer = Z2(T,:)
원하는 순서로 행이있는 행렬을 얻는 것과 같은 일을 할 수 있기를 바랐습니다 .
나는 이미 테스트 한 행과 이미 찾은 패턴에 대해 0으로 while 루프 내부를 수정하고 있기 때문에 최종 답변 변수를 추출하기 위해, Z2
복사본 Z
을 사용하고 Z
있습니다. .
Z2 = Z;
T = zeros(size(Z,1),1);
i = 0;
count = 1;
while size(T(T~=0),1) ~= size(Z,1)
i = i + 1;
if(isequal(Z(i,:),[0 0 0 0]))
continue;
end
p = find(ismember(Z(:,1:2),Z(i,2:3),'rows'));
T(count) = i;
if(~isempty(p))
T(count + 1:count + size(p,1)) = p;
end
Z(i,:) = 0;
Z(p,:) = 0;
count = count + size(p,1) + 1;
end
글쎄, 가능한 속도 향상은 다음과 같은 대체품을 만드는 것입니다.
%// p = find(ismember(Z(:,1:2),Z(i,2:3),'rows'));
p = find( all(bsxfun(@eq, Z(:,1:2), Z(i,2:3)),2) );
이것은 ismember
내장되어 있지 않기 때문에 작동하므로 MATLAB의 JIT 컴파일러로 루프를 효율적으로 가속화 할 수 없습니다.
더 많은 일을 할 수 있다고 생각하지만 먼저 이것을 시도하십시오. 내 PC (MATLAB R2010b, Win 7, 64 비트)에서는 약 10 배의 속도 향상이 있지만 확인해야 할 상황에서 컴퓨터의 프로필이 더 좋습니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다