場所のリストを生成したい場合はL[1..n]
、次の場所をランダムに選択してスキャンしL
、距離がしきい値を超えていることを確認します。それ以外の場合は、もう一度選択します。
次に、これをリストにプッシュしますL
。したがって、要素リストを生成する合計実行時間はO(n ^ 2)です。n <1000の場合、これは十分に高速です。次のメソッドは確実に終了します。これは、読み取りから選択までのリストが比較的小さく、たとえば最大1,000,000になるように設計されています。
function generateList(orgList, numberToOutput) {
if (orgList.length < numberToOutput)
return false;
var orgListClone = orgList.slice(0);
var L = [];
while (L.length < numberToOutput && orgListClone.length > 0) {
var n = parseInt(Math.random() * orgListClone.length);
// Assume we pick n-th element in the list.
var ok = true;
for (var j = 0; j < L.length; j++)
if (distance(orgListClone[n], L[j]) < kThreshold) {
// n is not an option, swap orgListClone[n] with the last element and pop it out.
orgListClone[n] = orgListClone[orgListClone.length - 1];
orgListClone.pop();
ok = false;
break;
}
if (ok) {
// All tests passed
L.push(orgListClone[n]);
orgListClone[n] = orgListClone[orgListClone.length - 1];
orgListClone.pop();
}
}
if (L.length == numberToOutput)
return L;
// Failed to find the list
return null;
}
もう1つの解決策は、前方の各場所間の距離を計算し、各場所に対して近すぎる場所のリストを作成することです。
そのため、各ピックの後で、近すぎる場所を現在のセットにマージします。これにより、O(n)が使用されます。次に、このセットに含まれていない別の場所を選択します。この方法は、read-to-pickリストが十分に大きい場合にのみ機能するため1 - |too close list| / |read-to-pick list|
、セットに含まれていない場所を選択する確率()が大きくなります。これには合計で最大O(nm)がかかります。ここで、mは平均|近すぎるリスト|です。
function generateList(orgList, numberToOutput) {
if (orgList.length < numberToOutput)
return false;
var tooCloseSet = {};
var L = [];
var lastLengthOfL = 0;
var repickCount = 0;
for (L.length < numberToOutput) {
if (l.length == lastLengthOfL) {
if (++repickCount > 10)
return false;
} else {
lastLengthOfL = l.length;
repickCount = 0;
}
var n = parseInt(Math.random() * orgList.length);
if (n in tooCloseSet)
continue;
L.push(orgList[n]);
mergeSet(tooCloseSet, orgList[n].tooCloseList);
}
return L;
}