A
n点のデカルト座標をリストする* 3行列である行列があるとします。私が興味を持っているのは、基本的に最大距離が離れた2つの座標であるnorthPoleとsouthPoleを見つけることです。私は、northPole と southPole にそれぞれ最小と最大の z 座標を持たせ、x 座標と y 座標を使用して関係を断ち切りたいと考えています。この問題はループを使用して簡単に実行できますが、行列 A が非常に大きいため、コードを効率的にしたいと考えています。したがって、コードが効率的になるように、組み込みの MatLab 関数を使用して northPole と southPole を見つけるのに助けが必要です。ありがとうございました!
2 に答える
あなたが提案するアルゴリズムは、最大距離が離れている2つの座標を実際には見つけられません。たとえば、距離が最大の 2 点z = 0
が
ここに 2 つの解決策があります。1 つは実際に最大距離が離れた 2 つのポイントを提供し、もう 1 つは北極-南極アルゴリズムの実装です。両方のソリューションで、私が与える関数は、ポイント自体ではなく、候補ポイントのインデックスを返すことに注意してください。ポイント自体を取得できます
north = A(iN, :);
south = A(iS, :);
解決策 1: 距離が最大になる 2 点を見つける
ファイル交換distmat
の機能を使ってみてください。ポイントの配列 ( はポイントの数、は次元) を取り、距離の配列 ( は と の間の距離)を返します。には、行列の生成に使用できる 4 つの異なるアルゴリズムがあり、最適なパフォーマンスが得られるアルゴリズムに応じて異なります。N x D
A
N
D
N x N
dist
dist(i, j)
A(i,:)
A(j,:)
distmat
この関数を使用して距離行列を作成し、 を使用max
して最大距離の候補を見つけることができます。その後、好きな方法で絆を断ち切ることができます。
次の関数では、最大距離が離れているすべてのポイントを見つけます。ペアが複数ある場合は、候補間の xy 距離に基づいて同点を解消します。
function [iN, iS] = poles(A)
% create the distance matrix
dist = distmat(A);
% find all candidate pairs of north and south poles
[~, iMax] = max(dist(:));
[iN, iS] = ind2sub(size(dist), iMax);
% If there is only one, you are done, otherwise break the ties.
if length(iMax) == 1
return
end
%
% break ties by the euclidean distance of the x-y coordinates
% note that this may not result in a unique set of north and south poles,
% but you can always break further ties.
north = A(iN, 1:2);
south = A(iS, 1:2);
tieBreak = sum(abs(north-south).^2, 2);
[~, iMax] = max(tieBreak);
iN = iN(iMax);
iS = iS(iMax);
end
解決策 2: 「北極」と「南極」を見つける
このソリューションもdistmat
関数を使用します。最初に、最大および最小の z 値を持つポイントを見つけます。同点がない場合は停止します。それ以外の場合は、最大距離を持つ '北' と '南' のポイントのペアを見つけ、上記のようにタイブレークします。
function [iN, iS] = poles(A)
% find the min and max z values
[~, iMaxZ] = max(A(:, 3));
[~, iMinZ] = min(A(:, 3));
iMaxZ = iMaxZ(:);
iMinZ = iMinZ(:);
if length(iMaxZ) == 1 && length(iMinZ) == 1
iN = iMaxZ;
iS = iMinZ;
return
end
nMax = length(iMaxZ);
nMin = length(iMinZ);
% put the north and south poles together
northSouth = A([iMaxZ; iMinZ], :);
% find the distance between them
dist = distmat(northSouth);
% restrict to only north-south pairs
dist = dist(1:nMax, nMax+1:end);
% find the maximum distance
[~, iMaxDist] = max(dist(:));
[iN, iS] = ind2sub(size(dist), iMax);
if length(iMaxDist) == 1
return
end
% break ties by the euclidean distance of the x-y coordinates
% note that this may not result in a unique set of north and south poles,
% but you can always break further ties.
north = A(iN, 1:2);
south = A(iS, 1:2);
tieBreak = sum(abs(north-south).^2, 2);
[~, iMax] = max(tieBreak);
iN = iN(iMax);
iS = iS(iMax);
end
あなたは自分で答えを説明しました。最初に最小または最大の Z 値のインデックスを見つけてから、最小の X & Y 距離を使用して同点を解消します。
zmax = max(A(:,3));
zmaxNdx = find(zmax == A(:,3));
d2 = A(zmaxNdx,1).^2 + A(zmaxNdx,2).^2;
[~, d2minNdx] = min(d2);
northpoleNdx = zmaxNdx(d2minNdx)
zmin = min(A(:,3));
zminNdx = find(zmin == A(:,3));
d2 = A(zminNdx,1).^2 + A(zminNdx,2).^2;
[~, d2minNdx] = min(d2);
southpoleNdx = zminNdx(d2minNdx)