簡體   English   中英

檢查2D數組中每個鄰居的最快方法

[英]Fastest way to check each neighbor in 2D array

我正在研究隨機地牢生成器,只是為了娛樂/作為學習一些新事物的輔助項目。 我編寫了一個函數,該函數為任何給定的單元返回整數哈希值,該函數可為您提供有關該游戲對象應為哪種類型的信息。 例如,如果它是牆,則要面向哪個方向,是否是拐角,等等。這是該功能當前的外觀。

    private int CellHashValue(int xIndex, int yIndex, char centerTile)
    {
        int hashValue = 0;
        if (dungeon2DArray[xIndex - 1, yIndex + 1] == centerTile)
        {
            hashValue += 1;
        }
        if (dungeon2DArray[xIndex, yIndex + 1] == centerTile)
        {
            hashValue += 2;
        }
        if (dungeon2DArray[xIndex + 1, yIndex + 1] == centerTile)
        {
            hashValue += 4;
        }
        if (dungeon2DArray[xIndex - 1, yIndex] == centerTile)
        {
            hashValue += 8;
        }
        if (dungeon2DArray[xIndex + 1, yIndex] == centerTile)
        {
            hashValue += 16;
        }
        if (dungeon2DArray[xIndex - 1, yIndex - 1] == centerTile)
        {
            hashValue += 32;
        }
        if (dungeon2DArray[xIndex, yIndex - 1] == centerTile)
        {
            hashValue += 64;
        }
        if (dungeon2DArray[xIndex + 1, yIndex - 1] == centerTile)
        {
            hashValue += 128;
        }
        return hashValue;
    }

我的問題是,有沒有一種我可能沒有想到的更有效,更快捷的方法來進行這些檢查? 地牢數組的大小范圍從100x100到1000x1000,盡管並未在每個單元格上調用該函數。 我有一個單獨的List,其中包含房間,並且在迭代實例化對象的每個方向上都有開始索引和結束索引。

由於您使用數組構建映射,因此由於直接訪問,訪問時間是恆定的。 因此,檢查每個數組索引的過程很快。

有一些小事情可以加快此功能。

  1. 在相應的if語句中返回hashValue。 這將刪除幾行代碼。
  2. 通過刪除hashValue變量並返回一個硬編碼的值,將從過程中刪除變量初始化。 這比看起來更重要。 創建和刪除對象需要花費大量時間 ,而在規模化時則需要花費大量時間
  3. 可以使xIndexyIndex成為對象的全局對象。 小心執行此想法。 由於在檢查特定條件時xIndex和yIndex不變,因此可以在對象內將它們全局化。 這減少了傳入的參數的數量。由於Java不通過引用傳遞,因此將創建大小相等的對象並將其傳遞到函數中。 一個簡單的int不會對速度產生很大的影響,但是如果您的對象包含許多變量,則需要更多的時間來構建另一個相等值的對象。
  4. 每個檢查都可以移至單獨的功能。 這主要有助於提高可讀性和以后進行調試。 有一些速度優勢,但它們取決於項目。 通過觀察對象如何初始化/操作,通常可以強制某些條件為真。 當不需要檢查邏輯並且無需檢查就可以得出結論時,則需要的時間更少。

只是一些想法。 如果您有時間研究,第二點和第三點將使用low latency/high frequency概念。 另外,請注意,其中一些概念不被視為最佳實踐。

您要做的實際上是應用一種卷積形式。 在沒有更多有關如何調用方法或如何使用返回的哈希值的上下文的情況下,您正在執行的操作似乎接近最有效的3x3網格迭代方法。 假設您的dungeon2dArray是char [] []並且是全局的,那么我認為這會更加清楚和簡潔(您必須根據迭代順序來調整如何解釋結果之和)。

private int CellHashValue(int x, int y) {
    int hashSum = 0;   // Hash sum to return
    int hashValue = 1; // Increases as power of 2 (1,2,4,8,...128)
    char centerTile = dungeon2DArray[x, y]; // Cache center tile

    for (int r = -1; r <= 1; r++) {
        for (int c = -1; c <= 1; c++) {
            if (r == 0 && c == 0) continue; // Skip center tile
            if (dungeon2DArray[x + c, y + r] == centerTile) {
                hashSum += hashValue;
            }
            hashValue *= 2; // Next power of two
            //could also bit shift here instead 
            // hashValue <<= 1
        }
    }
    return hashSum;
}

注意:此方法不進行任何邊界檢查,因此,如果x或y索引沿邊,則索引將失敗。

每個數組訪問為O(1),並且在整個地牢數組中進行迭代的時間為O(n ^ 2),因此獲得更高效率的唯一方法是組合每個單元格方法調用,但這仍然是一個常數,因此效率實際上並沒有提高,但是取決於計算方式可能會稍微提高性能。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM