我想設計一個可以生成各種「映射」的函數。如何在javascript中生成彼此之間距離的隨機位置?
例如:
位置A被創建,它位於一些位置X被創建
位置B,它位於一些位置Y,我們知道X之間的距離,Y
位置C已創建,我們知道從C到B的距離,我們如何計算C到A?
使用三角形方法,我想我也可以指定一個隨機角度並計算第三面,但如果隨機添加位置D,E,F,我該怎麼辦?我會計算多個三角形,每增加一個指數級的差異?
我想設計一個可以生成各種「映射」的函數。如何在javascript中生成彼此之間距離的隨機位置?
例如:
位置A被創建,它位於一些位置X被創建
位置B,它位於一些位置Y,我們知道X之間的距離,Y
位置C已創建,我們知道從C到B的距離,我們如何計算C到A?
使用三角形方法,我想我也可以指定一個隨機角度並計算第三面,但如果隨機添加位置D,E,F,我該怎麼辦?我會計算多個三角形,每增加一個指數級的差異?
說你要生成的位置L[1..n]
列表,你只是隨機挑選下一個位置,並掃描整個L
,以保證傳輸距離超過閾值,否則,重新選取。
然後,將其推入列表L
。所以生成一個n元素列表的總運行時間是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;
}
另一種解決方法是計算每個位置之間的距離,併爲每個位置列出太近的位置。
因此,在每次選擇後,只需將O(n)合併到當前集合太近的位置。然後選擇另一個不包含在這個集合中的位置。此方法僅適用於讀取選擇列表足夠大時,以便選擇未包含在該集合中的位置的概率(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;
}
感謝你的回答。我會接受你的,因爲你投入了多少努力,但老實說,我不在乎他們在一起的時間有多長,以至於他們不在同一個位置。儘管在未來,也許我會在意我的想法。 – user1500053
如果你不關心距離,只需[洗牌](http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle)數據,這隻需要O(n)時間,這個工作大多數數據庫也是如此。 – xiaoyi
你可以嘗試這樣的事情,我沒有測試過,所以這只是概念性的。
您可以生成一個隨機放置點的數組,每個點可以保存它自己的距離數組,使用基本的三角函數計算。
function Point(x, y) {
return {
x: x,
y:y,
addRelative: function(pt) {
this.realtivePoints[pt] = abs(sqrt(pow((this.x-pt.x),2) + pow((this.y-pt.y),2)));
},
relativePoints: {}
};
var randPoints = []; // Lets assume this has a collection of random Point objects
for(var i=0; i<randPoints.length; i++) {
for(var j=0; j<randPoints.length; j++) {
randPoint[i].addRelative(randPoints[j]);
}
}
randPoints[0].relativePoints[randPoints[1]]; // Dist from first to second point.
感謝您的回答。這是我想到的,並希望有一個不那麼重的替代品。我可能沒有其他的方式去做,我不知道。 – user1500053
很酷。那麼這可以肯定地被優化。它計算從'A到B'和'B到A'的距離,所以你可以將計算量減半。 – Aesthete
這假定您知道每個點的x/y位置,並且只是預先計算所有可能的距離。我不相信這是問題陳述的一部分。 (呵呵,你不需要'abs()',因爲'sqrt()'不會返回負值。) – broofa
是的,隨着每個點的添加,它的幾何學變得更加複雜。
問題是,即使你知道三角形的所有三邊的長度,你仍然不知道方向。通過指定距離DAB和DBC(它給你DAC)
你定義ABC:爲了說明你的榜樣。但你實際上有兩個可能的三角形,ABC和ABC'。也就是說,如果通過指定第四個點D的距離來指定它與ABC上的其中一個點(例如dCD)的距離,則添加了第二個三角形,該三角形也可以具有兩個方向中的一個,從而總共四個點可能的解決方案。如您所見,定位對於確定同一三角形上兩點之間的距離無關緊要,但對於確定不同三角形上點之間的距離,方向確實無關緊要。
'會增加更多,但看起來你已經選擇了答案。 – broofa
謝謝,是的,我有點擔心。最後,我想我計劃生成這些信息並將其存儲在Dbase中,這樣我就不用擔心執行時間。 – user1500053
你是否確定?正如其他人所指出的,這是一個n平方問題。 50分意味着像「地圖」兩邊的點數可能達到1千萬億(10 ^^ 15)的可能解決方案。 – broofa
幾件事情需要知道。您準備好的選擇列表中有多少個地點?你需要在最終名單中生成多少個地點? – xiaoyi
理想情況下,這也是隨機的。拱形「位置容器」上的任何一個可能具有0到50個子位置,這些位置之間需要距離,計算結果爲 – user1500053
FWIW,我發現問題描述混亂。你知道每個位置的x/y座標,還是隻知道距離? – broofa