2016-01-06 64 views
0

我試圖通過首先創建軸座標來動態創建有限n維座標系中的位置列表。該系統只有整數作爲座標值。軸座標是AxCrd對象。 AxCrd對象具有兩個屬性:從軸向座標動態創建一個有整數座標的有限n維座標系

  1. AxCrd.dim是座標的維的句柄或名稱。例如,「x」或「y」。
  2. AxCrd.crd是座標的值。這是一個整數。例如,-4或3.

我試過編寫一個函數,它接受所有生成的AxCrd對象作爲輸入,並輸出n維空間中所有位置的列表試圖創建爲Crd對象。 Crd對象有兩個屬性:

  1. Crd.dims是一個包含座標的所有尺寸控制柄的數組。這個數組的長度是n,即等於維數。

  2. Crd.crds是一個包含上述尺寸的所有座標值的數組。這個數組的順序很重要,因爲座標的尺寸應該與座標值具有相同的元素編號。 IE瀏覽器。如果尺寸「z」是第二個元素,則crds [2]是尺寸「z」的座標值。

例如,假設我使用這些構造函數:

function AxCrd(dim,crd) { this.dim = dim, this.crd = crd } 
function Crd(dims,crds) { this.dims = dims, this.crds = crds } 

在我的實際用途,大部分的尺寸有九個值:4負,四個正和一個零。但爲了簡便起見,假設我有三個尺寸,使得:

var input = []; 
input.push(new AxCrd("x", -1)); 
input.push(new AxCrd("x", 1)); 
input.push(new AxCrd("y", -1)); 
input.push(new AxCrd("y", 1)); 
input.push(new AxCrd("z", -1)); 
input.push(new AxCrd("z", 1)); 
input.push(new AxCrd("d", -1)); 
input.push(new AxCrd("d", 1)); 

正如你可以看到,有三個維度和他們每個人只有兩個座標值。我試着寫,鑑於上面的輸入,將創建新的對象Crd中像這樣的功能:

var ret = []; 
ret.push(new Crd(["x","y","z","d"],[-1,-1,-1,-1])); 
ret.push(new Crd(["x","y","z","d"],[ 1,-1,-1,-1])); 
ret.push(new Crd(["x","y","z","d"],[-1, 1,-1,-1])); 
ret.push(new Crd(["x","y","z","d"],[ 1, 1,-1,-1])); 
ret.push(new Crd(["x","y","z","d"],[-1,-1, 1,-1])); 
ret.push(new Crd(["x","y","z","d"],[ 1,-1, 1,-1])); 
ret.push(new Crd(["x","y","z","d"],[-1, 1, 1,-1])); 
ret.push(new Crd(["x","y","z","d"],[ 1, 1, 1,-1])); 
ret.push(new Crd(["x","y","z","d"],[-1,-1,-1, 1])); 
ret.push(new Crd(["x","y","z","d"],[ 1,-1,-1, 1])); 
ret.push(new Crd(["x","y","z","d"],[-1, 1,-1, 1])); 
ret.push(new Crd(["x","y","z","d"],[ 1, 1,-1, 1])); 
ret.push(new Crd(["x","y","z","d"],[-1,-1, 1, 1])); 
ret.push(new Crd(["x","y","z","d"],[ 1,-1, 1, 1])); 
ret.push(new Crd(["x","y","z","d"],[-1, 1, 1, 1])); 
ret.push(new Crd(["x","y","z","d"],[ 1, 1, 1, 1])); 

如何做到這一點對於n維空間?

回答

1

如果我理解你的問題,你需要一個地圖所有尺寸名稱到他們的indeces(叫它dim_map應該是dim_map['x'] = 0; dim_map['y'] = 1;...)。 然後,當您進行轉換時,您使用的鍵爲dims,查找index = dim_map[AxCrd.dim]的索引並將該值分配給相應的元素(Crd.crds[index] = AxCrd.crd)。

我不完全確定這是你想要的,因爲你的例子看起來很混亂。我不確定爲什麼你爲每個AxCrd構造了兩個Crds,或者爲什麼其他一些值似乎發生了變化。

+0

在我創建的「遊戲」或人工智能中,每個座標都應該具有「道德價值」。您可能想將其視爲「分數」。也就是說,玩家通過移動或移動到某個座標獲得某個得分。我想預先計算這些分數,以便爲計算機編寫代碼以便找到最佳的移動方式。我打算將預先計算的分數添加爲Crd對象的屬性。 –

1

遞歸似乎是處理這類問題的正確方法。這是一個簡單的遞歸函數,返回結果點的數組。它還將維中的名稱存儲在作爲函數參數傳遞的數組中。

function rec(i, input, dimensions) 
{ 
    // find the name of the current dimension 
    var currentd = input[i].dim; 

    dimensions.push(currentd); 

    // find how many elements in the current dimension 
    var j = i; 
    while (j < input.length && input[j].dim == currentd) ++j; 

    // create a tail of results 
    var tail = []; 
    if (j < input.length) { 
     tail = rec(j, input, dimensions); 
    } 

    // create a result by appending tail to all possible coordinates in the current dimension 
    var result = []; 
    for (; i < j; i++) { 
     if (tail.length == 0) { 
      result.push([input[i].crd]); 
     } else { 
      for (var k = 0; k < tail.length; k++) { 
       result.push([input[i].crd].concat(tail[k])); 
      } 
     } 
    } 
    return result; 
} 

此功能不會創建Crd對象本身,而是你可以很容易地修改它做如此。用例:

var dimensions = []; 
var result = rec(0, input, dimensions); 
console.log(JSON.stringify(dimensions)); 
for (var i = 0; i < result.length; i++) { 
    console.log(JSON.stringify(result[i])); 
} 

輸出(假設input是在你的例子):

["x","y","z","d"] 
[-1,-1,-1,-1] 
[-1,-1,-1,1] 
[-1,-1,1,-1] 
[-1,-1,1,1] 
[-1,1,-1,-1] 
[-1,1,-1,1] 
[-1,1,1,-1] 
[-1,1,1,1] 
[1,-1,-1,-1] 
[1,-1,-1,1] 
[1,-1,1,-1] 
[1,-1,1,1] 
[1,1,-1,-1] 
[1,1,-1,1] 
[1,1,1,-1] 
[1,1,1,1] 
0

這看起來好像你正在尋找每個子陣列的項目,或Cartesian product的所有可能的組合。這可以遞歸地計算:

function product(array) { 
    if (array.length == 0) return [[]]; 

    var head = array[0]; 
    var tail = product(array.slice(1)); 
    var res = []; 

    for (var i = 0; i < head.length; i++) { 
     for (var j = 0; j < tail.length; j++) { 
      res.push([head[i]].concat(tail[j])); 
     } 
    } 

    return res; 
} 

答使用這樣的:假定傳遞的數組是數組的數組下

var input = [ 
    [-1, 1], // x 
    [-1, 1], // y 
    [-1, 1], // z 
    [-1, 1], // d 
]; 

var prod = product(input); 

for (var i = 0; i < prod.length; i++) { 
    console.log(i, prod[i]); 
} 

上述功能工作。沒有試圖檢測到這一點。

您可以將結果數組添加到列表中,而不是打印。我不確定爲什麼每次添加座標時都要創建一個新的座標系。你不應該只創建一次座標系並且傳遞一個參考嗎?我也是第二個索林,因爲你可能想要一個按字母查找的地圖。你的課堂設計似乎不必要的複雜。

0

我打算做似乎是由下列函數來基本實現:

function makeAllCoordinates(arr) { 
    if (arr.length === 0) { return []; } 
    else if (arr.length === 1) { return arr[0]; } 
    else { 
    var result = []; 
    var allCases = makeAllCoordinates(arr.slice(1)); 
    for (var c in allCases) { 
     for (var i = 0; i < arr[0].length; i++) { 
     result.push((arr[0][i] + allCases[c]).split(",")); }} 
    return result; }} 

結果是9×9×9×9×3×3 = 59049成員的陣列。這個數字是正確的。但是,每個數組只有一個成員,這是一個由六個重複的「[object Object]」組成的字符串。我需要它們是六個AxCrd對象的唯一數組,而不是這些字符串。數組的順序無關緊要。以這種方式修改這個函數很困難嗎?

在任何情況下,我希望這個回覆清除了我想要做的事情的模糊性。

+0

也許如果你考慮結果作爲數組,而不是字符串:'result.push([arr [0] [i]]。concat(allCases [c]));'?當你發佈這個答案時,其他兩個答案已經發布了或多或少相同的代碼。如果您只是想澄清事情,請編輯原始問題。 SO允許您提出自己的問題,但前提是它們是真正獨特的解決方案。 –