簡體   English   中英

關於實現標簽設置/校正/動態規划的問題

[英]Question about implementing label setting/correction/dynamic programming

對於那些熟悉這個算法的人。 我的問題是,您如何編碼使用動態編程獲得有效子集的部分? 我理解邏輯,但就是無法將其放入代碼中,因為標簽維度通常很高,您如何在不編寫 10 或 100 個嵌套“for”循環的情況下實現它?

對於那些不熟悉這個算法的人。 我的問題是,如何找到具有非顯性元組的最大子集。 我們說元組 A 支配元組 B,如果元組 A 中的所有元素都小於元組 B 中的元素,則B[0] < A[0] & B[1] < A[1] & B[2] < A[2] & ... . 像 B 這樣的元組應該從集合中刪除。

例如,考慮下面的元組集

(1, 7, 1, 5, 2), (6, 2, 3, 3, 2), (5, 5, 6, 9, 8), (2, 4, 9, 9, 7), (4) , 1, 2, 8, 7), (3, 0, 2, 0, 2), (5, 1, 1, 1, 3), ...

(3, 0, 2, 0, 2) 支配 (6, 2, 3, 3, 2), (5, 5, 6, 9, 8), (4, 1, 2, 8, 7)

您如何在不編寫 5 個嵌套 for 循環的情況下進行編程? 如果我用遞歸來寫,那么會有很多重復的計算,但是如果我使用迭代,那么我需要一個 5 維數組來保存結果。

如果我理解正確,您擔心的是您將擁有一個n維數組A ,您需要在其中執行以下操作:

  • 您需要以這樣一種方式迭代數組元素,即您不會訪問A [ i 0 ][ i 1 ][…][ i n −1 ] 直到您沿着每個維度( A [ i 0 -1][ i 1 ][…][ i n -1 ], A [ i 0 ][ i 1 -1][…][ i n -1 ], …, 和A [ i 0 ][ i 1 ][…][ i n -1 -1])。
  • 當訪問A [ i 0 ][ i 1 ][…][ i n −1 ] 時,你需要沿着每個維度檢查它的前身。

並且您擔心這樣做的唯一方法是為i 0i 1 、... 和i n −1中的每一個設置單獨的變量,並為每個變量設置一個 for 循環。

(在我看來,您的部分擔憂似乎有些過分——您提到了“10 或 100 多個嵌套的‘for’循環”,但無論如何您都無法存儲 2100元素,這比地球上所有計算機中的所有數據還多——但是即使是五個嵌套的 for 循環也是混亂且容易出錯的,當然,您會被綁定到特定數量的維度。因此,不想這樣做是合理的。)

您可以通過將“邏輯” n維數組表示為具有適當數量元素的“底層”維數組來解決此問題,使用整數數組作為“邏輯”索引,並編寫邏輯以在該數組之間進行映射和一個“基礎”索引,它是一個整數。

例如,如果您的“邏輯”數組A是 10×10×10×10×10,那么您可以創建一個長度為 10 5 的“底層”數組A ,以及“邏輯”位置 [3,4, 5,6,7] - 意思是A [3][4][5][6][7] - 是A[34_567] 這是一個從前者轉換為后者的 Java 方法:

public int getUnderlyingIndex(
    final int[] index,
    final int[] dimensions
) {
    int result = 0;
    for (int dim = 0; dim < dimensions.length; ++dim) {
        result = result * dimensions[dim] + index[dim];
    }
    return result;
}

出於迭代目的,您需要一個函數來“增加”索引——例如,給定 [1,2,3,9,9] 它會將其更改為 [1,2,4,0,0]——並讓您知道你是否已經通過了數組的末尾。 下面是 Java 中的樣子:

public boolean incrementIndexArray(
    final int[] index,
    final int[] dimensions
) {
    int dim = index.length - 1;
    while (true) {
        index[dim]++;
        if (index[dim] < dimensions[dim]) {
            return true; // iteration can continue
        }
        index[dim] = 0;
        --dim;
        if (dim < 0) {
            return false; // done iterating
        }
    }
}

為了檢查元素的前身,您可以編寫單個 for 循環。 下面是 Java 中的樣子:

for (int dim = 0; dim < dimensions.length; ++dim) {
    if (index[dim] == 0) {
        // no predecessor along this dimension
        continue;
    }
    index[dim]--;
    final int predecessor =
        underlyingArray[getUnderlyingIndex(index)];
    index[dim]++;
    // ... do what you want with it ...
}

暫無
暫無

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

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