既知の半径の円をMATLABでプロットします。
座標(x1、y1)(x2、y2)..(xn、yn)の観点から位置を決定する必要があるランダムな点のペアを想定します。ペアは互いに近接している必要があります。たとえば、T1とR1は近くにある必要があります。
図に示すように、4つのランダムなペア(T1、R1)..(T4、R4)があります。中心(0,0)に対して座標を決定する必要があります。
これをMATLABで生成するにはどうすればよいですか?
既知の半径の円をMATLABでプロットします。
座標(x1、y1)(x2、y2)..(xn、yn)の観点から位置を決定する必要があるランダムな点のペアを想定します。ペアは互いに近接している必要があります。たとえば、T1とR1は近くにある必要があります。
図に示すように、4つのランダムなペア(T1、R1)..(T4、R4)があります。中心(0,0)に対して座標を決定する必要があります。
これをMATLABで生成するにはどうすればよいですか?
Rを減らして円上の一様分布から点を選択する最も簡単な方法は、ギブスサンプリングを使用することです。コードは次のとおりです。
function [x y] = circular uniform (R)
while true
x = 2*R*rand() - R
y = 2*R*rand() - R
if (x*x + y*y) > R*R
return
end
end
ループは平均して4/π回実行されます。
これは、均一に分散されたポイントで非常に使いやすい低品質のソリューションです。ポイントの数が少ないと仮定すると、効率は問題になりません。より良い品質が必要な場合は、最近傍よりも強力なものを使用できます。
結果として、ほとんどのペアは良いはずですが、いくつかは本当に悪いことがあります。試してみることをお勧めします。必要に応じて、k-optまたはその他のローカル検索を使用してステップ4を追加することをお勧めします。そして、実際にポイントが少ない場合(たとえば、20未満)は、もちろん、すべての距離を計算して、最適な一致を見つけることができます。
一様分布をあまり気にしない場合は、さらに簡単な解決策があります。
Rを(0; 0)中心円の放射性とします。
(x、y):x ^ 2 + y ^ 2 <= R ^ 2(LE)が円の内側にある
x = rand()*2*R - R;
yは区間(-sqrt(R ^ 2-x ^ 2); + sqrt(R ^ 2-x ^ 2))
にある必要があるので、
y = rand()*sqrt(R^2 - x^2)*2-sqrt(R^2 - x^2);
そうだといいのですが、テストするMATLABがありません。
うまくいけば、あなたは自分自身に近いペアを見つけることができます。
わかりました、ヒントのためにもう少し時間を費やします。区間[a、b]で乱数kを見つけるには、次を使用します。
k = rand()*(b-a)+a
今でもmatlabの構文を覚えていれば、本当に役立つはずです。幸運を。
@PheuVergが提案したようにランダムポイントを生成します(わずかにベクトル化された微調整を行います)
n = 8; %must be even!
x = rand(n, 1)*2*R - R;
y = rand(n, 1).*sqrt(R^2 - x.^2).*2-sqrt(R^2 - x.^2);
次に、kmeansクラスタリングを使用してn/2センターを取得します
[~ c] = kmeans([x y], n/2);
ここで、各中心をループして、各点までの距離を見つける必要があります
dists = zeros(n, n/2);
for cc = 1:n/2
for pp = 1:n
dists(pp, cc) = sqrt((c(cc,1) - x(pp))^2 + (c(cc,2) - y(pp))^2);
end
end
ここで、distの各列の最小の2つの値を見つける必要があります
[sorted, idx] = sort(dists);
したがって、各列の上位2行が最も近い2つのポイントになります。しかし、衝突が発生する可能性があります。つまり、2つの異なる中心に最も近いポイント。したがって、繰り返される値の場合は、ループして、余分な距離が最小になるポイントのスワップを選択する必要があります。
データ例:
x =
0.7894
-0.7176
-0.5814
0.0708
0.5198
-0.2299
0.2245
-0.8941
y =
-0.0800
-0.3339
0.0012
0.9765
-0.4135
0.5733
-0.1867
0.2094
sorted =
0.1870 0 0 0.1555
0.2895 0.5030 0.5030 0.2931
0.3145 1.1733 0.6715 0.2989
1.0905 1.1733 0.7574 0.7929
1.1161 1.2326 0.8854 0.9666
1.2335 1.2778 1.0300 1.2955
1.2814 1.4608 1.2106 1.3051
1.4715 1.5293 1.2393 1.5209
idx =
5 4 6 3
7 6 4 2
1 3 3 8
6 7 8 6
3 8 7 7
2 1 2 4
4 5 1 5
8 2 5 1
これで、とがペアであり、とがペアであることが明らかに5
なり7
まし3
た2
。しかし4
、と6
は両方とも繰り返されます。(この場合、それらもペアであることは明らかです!)しかし、私が提案するのは、点4
を中心2
に、点6
を中心に残すことです3
。次に、列2から始めて、次の利用可能なポイントが8
距離であることがわかります1.2326
。これにより、ポイント1
とポイントがペアになります6
が、中心からの距離はです1.2106
。6
ポイントと8
ポイント4
をペアリングした場合、と1
の距離が得られます。 0.7574
1.2778
それぞれ、実際には合計距離が短くなります。したがって、「近い」ペアを見つけるのは簡単ですが、グローバルに最小値を持つペアのセットを見つけるのは困難です。このソリューションは非常に簡単にまともなものを手に入れますが、グローバルな最高のものが必要な場合は、まだかなりの作業が必要です:(
最後に、視覚化を追加します。まず、(手動で)どのポイントがペアになっているかを示すベクトルを作成します。
I = [1 2 2 1 3 4 3 4];
それはあなたのデータに依存することを忘れないでください!これで、次のようにプロットできます。
gscatter(x, y, I)
これがあなたを近づけ、最後に私の手動ペアリングを自分で排除できることを願っています。粗い解決策を得るのはそれほど難しいことではありません。
(質問が編集された後、完全に編集してください)。
このタスクを完了するには、編集前に説明したさまざまなアプローチを組み合わせる必要があると思います。
これらの材料を使用すると、必要なすべてを行うことができるはずです。これが私が書いたコードです:
d=859.23;
D=1432.05;
R=100;
N=400;
% Generate the angle
theta = 2*pi*rand(N,1);
% Generate the radius
r = d + (D-d)*rand(N,1);
% Get the centers of the circles
Tx = r.*cos(theta);
Ty = r.*sin(theta);
% Generate the R points
Rx=zeros(N,1);
Ry=zeros(N,1);
for i=1:N
while true
% Try
alpha = 2*pi*rand();
rr = R*rand();
Rx(i) = Tx(i) + rr*cos(alpha);
Ry(i) = Ty(i) + rr*sin(alpha);
% Check if in the correct zone
if ( (Rx(i)*Rx(i) + Ry(i)*Ry(i) > d*d) && (Rx(i)*Rx(i) + Ry(i)*Ry(i) < D*D) )
break
end
end
end
% Display
figure(1);
clf;
angle=linspace(0,2*pi,1000);
plot( d*cos(angle), d*sin(angle),'-b');
hold on;
plot( D*cos(angle), D*sin(angle),'-b');
for i=1:N
plot(Tx(i),Ty(i),'gs');
plot(Rx(i),Ry(i),'rx');
plot([Tx(i) Rx(i)],[Ty(i) Ry(i)],'-k');
end
hold off;