1

私は自分自身の自己組織化マップをトレーニングして、カラー値をクラスター化しています。ここで、ノードとその直接の隣接ノードとの間のユークリッド距離を示すために、ある種のU 行列を作成したいと考えています。私の問題は、私のアルゴリズムが非常に非効率的であることです!! これをより効率的に計算する方法は確かにありますか?

function displayUmatrix(dims,weights) %#dims is [30 30], size(weights) = [900 3], 
                                      %#consisting of values between 1 and 0

hold on; 
axis off;
A = zeros(dims(1), dims(2), 3);
B = reshape(weights',[dims(1) dims(2) size(weights,1)]);
if size(weights,1)==3
    for i=1:dims(1)
        for j=1:dims(2)
            if i~=1
                if j~=1
                    A(i,j,:)=A(i,j,:)+(B(i,j,:)-B(i-1,j-1,:)).^2;
                end
                A(i,j,:)=A(i,j,:)+(B(i,j,:)-B(i-1,j,:)).^2;
                if j~=dims(2)
                    A(i,j,:)=A(i,j,:)+(B(i,j,:)-B(i-1,j+1,:)).^2;
                end
            end
            if i~=dims(1)
                if j~=1
                    A(i,j,:)=A(i,j,:)+(B(i,j,:)-B(i+1,j-1,:)).^2;
                end
                A(i,j,:)=A(i,j,:)+(B(i,j,:)-B(i+1,j,:)).^2;
                if j~=dims(2)
                    A(i,j,:)=A(i,j,:)+(B(i,j,:)-B(i+1,j+1,:)).^2;
                end
            end 
            if j~=1
                A(i,j,:)=A(i,j,:)+(B(i,j,:)-B(i,j-1,:)).^2;
            end
            if j~=dims(2)
                A(i,j,:)=A(i,j,:)+(B(i,j,:)-B(i,j+1,:)).^2;
            end
            C(i,j)=sum(A(i,j,:));
        end
    end
    D = flipud(C);
    maximum = max(max(D));
    D = D./maximum;
    imagesc(D)
else
    error('display function does only work on 3D input');
end
hold off;
drawnow;

終わり

ありがとう、マックス

4

1 に答える 1

2

次の方法で、各ポイントからその右隣までの (二乗) 距離を計算できます。

sum((B(:,1:end-1,:) - B(:,2:end,:)).^2, 3)

同様に、各点から下の点までの距離と、両方の対角線上の距離を計算します。境界上のポイントにこれらすべての値があるわけではないので、それらをゼロで埋めます。次に、距離を加算し、点がすべての近傍までの平均距離を取得するために必要な近傍の数で割ります。

これが私のコードです:

%calculate distances to neighbors
right = sum((B(:,1:end-1,:)- B(:,2:end,:)).^2, 3);
bottom = sum((B(1:end-1,:,:)- B(2:end,:,:)).^2, 3); zeros();
diag1 = sum((B(1:end-1,1:end-1,:)- B(2:end,2:end,:)).^2, 3);
diag2 = sum((B(2:end,2:end,:)- B(1:end-1,1:end-1,:)).^2, 3);

%pad them with zeros to the correct size
rightPadded = [right zeros(dim(1) , 1)];
leftPadded = [zeros(dim(1) , 1) right];

botomPadded = [bottom; zeros(1,dim(2))];
upPadded = [zeros(1,dim(2));bottom];

bottomRight = zeros(dim(1), dim(2));
bottomRight(1:end-1,1:end-1) = diag1;
upLeft = zeros(dim(1), dim(2));
upLeft(2:end,2:end) = diag1;

bottomLeft = zeros(dim(1), dim(2));
bottomLeft(1:end-1,2:end) = diag2;
upRight = zeros(dim(1), dim(2));
upRight(2:end,1:end-1) = diag2;

%add distances to all neighbors
sumDist = rightPadded + leftPadded + bottomRight + upLeft + bottomLeft + upRight;

%number of neighbors a point has
neighborNum = zeros(dim(1), dim(2)) + 8;
neighborNum([1 end],:) = 5;
neighborNum(:,[1 end]) = 5;
neighborNum([1 end],[1 end]) = 3;

%divide summed distance by number of neighbors
avgDist = sumDist./neighborNum;

すべてベクトル化されているため、バージョンよりも高速になるはずです。正確な U 行列が必要な場合は、平均距離を隣接距離とインターリーブできます。

于 2013-03-22T18:47:37.633 に答える