1

既知の半径の円をMATLABでプロットします。

座標(x1、y1)(x2、y2)..(xn、yn)の観点から位置を決定する必要があるランダムな点のペアを想定します。ペアは互いに近接している必要があります。たとえば、T1とR1は近くにある必要があります。

図に示すように、4つのランダムなペア(T1、R1)..(T4、R4)があります。中心(0,0)に対して座標を決定する必要があります。

形

これをMATLABで生成するにはどうすればよいですか?

4

5 に答える 5

1

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/π回実行されます。

于 2013-01-31T08:14:11.213 に答える
0

これは、均一に分散されたポイントで非常に使いやすい低品質のソリューションです。ポイントの数が少ないと仮定すると、効率は問題になりません。より良い品質が必要な場合は、最近傍よりも強力なものを使用できます。

  1. ポイントがn個未満の場合:ランダムなポイントを生成します
  2. サークル内にある場合は保存し、そうでない場合は手順1に進みます。
  3. ペアになっていないポイントがありますが、最初のペアになっていないポイントに最も近いポイントを確認し、ペアにします

結果として、ほとんどのペアは良いはずですが、いくつかは本当に悪いことがあります。試してみることをお勧めします。必要に応じて、k-optまたはその他のローカル検索を使用してステップ4を追加することをお勧めします。そして、実際にポイントが少ない場合(たとえば、20未満)は、もちろん、すべての距離を計算して、最適な一致を見つけることができます。


一様分布をあまり気にしない場合は、さらに簡単な解決策があります。

  1. ポイントがn個未満の場合:ランダムなポイントを生成します
  2. サークル内にある場合は保存し、そうでない場合は手順1に進みます。
  3. これらのポイントのそれぞれについて、その近くにポイントを生成します
  4. サークル内にある場合は保存し、そうでない場合は手順3に進みます。
于 2013-01-31T11:18:53.733 に答える
0

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の構文を覚えていれば、本当に役立つはずです。幸運を。

于 2013-01-31T07:01:49.550 に答える
0

@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まし32。しかし4、と6は両方とも繰り返されます。(この場合、それらもペアであることは明らかです!)しかし、私が提案するのは、点4を中心2に、点6を中心に残すことです3。次に、列2から始めて、次の利用可能なポイントが8距離であることがわかります1.2326。これにより、ポイント1とポイントがペアになります6が、中心からの距離はです1.21066ポイントと8ポイント4をペアリングした場合、と1の距離が得られます。 0.75741.2778それぞれ、実際には合計距離が短くなります。したがって、「近い」ペアを見つけるのは簡単ですが、グローバルに最小値を持つペアのセットを見つけるのは困難です。このソリューションは非常に簡単にまともなものを手に入れますが、グローバルな最高のものが必要な場合は、まだかなりの作業が必要です:(

最後に、視覚化を追加します。まず、(手動で)どのポイントがペアになっているかを示すベクトルを作成します。

   I = [1 2 2 1 3 4 3 4];

それはあなたのデータに依存することを忘れないでください!これで、次のようにプロットできます。

gscatter(x, y, I)

これがあなたを近づけ、最後に私の手動ペアリングを自分で排除できることを願っています。粗い解決策を得るのはそれほど難しいことではありません。

于 2013-01-31T07:59:06.470 に答える
0

(質問が編集された後、完全に編集してください)。

このタスクを完了するには、編集前に説明したさまざまなアプローチを組み合わせる必要があると思います。

  • 緑のトーラスに中心T1、T2、T3、...を生成するには、極座標を使用します(編集:これは間違っていることが判明しました。ここでも棄却サンプリングを使用する必要があります。そうしないと、分布が均一になりません!)
  • T1、T2、T3、...の周りの円内に、まだトーラス内にある点R1、R2、R3、...を生成するには、棄却サンプリングを使用します。

これらの材料を使用すると、必要なすべてを行うことができるはずです。これが私が書いたコードです:

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;
于 2013-01-31T08:31:21.410 に答える