2014-06-10 80 views
1

我正在嘗試編寫一個函數,其中嵌套循環的數量取決於傳遞給它的整數(numStroke)。例如,當numStrokes爲1時,執行的代碼應該是:C#遞歸邏輯

double checkProfitability(GameState state, int numStrokes) 
{ 
    double[] possiblePayoffs = new double[50000]; 
    int pPIndex = 0; 
    double sumOfPayoffs = 0; 
    double averagePayoff = 0; 

    for (int i = 0; i <= 5; i++) 
    { 
     // Populate possiblePayoffs[] 
    } 

    for (int ii = 0; ii < pPIndex; ii++) 
    { 
     sumOfPayoffs += possiblePayoffs[i]; 
    } 

    averagePayoff = sumOfPayoffs/pPIndex; 

    return averagePayoff; 
} 

當numStrokes是3時,它應該是:

double checkProfitability(GameState state, int numStrokes) 
{ 
    double[] possiblePayoffs = new double[50000]; 
    int pPIndex = 0; 
    double sumOfPayoffs = 0; 
    double averagePayoff = 0; 

    for (int i = 0; i <= 5; i++) 
    { 
     state.colors[i]++; 

     for (int j = 0; j <= 5; j++) 
     { 
      state.colors[j]++; 

      for (int k = 0; k <= 5; k++) 
      { 
       // Populate possiblePayoffs[] 
      } 

      state.colors[j]--; 
     } 

     state.colors[i]--; 
    } 

    for (int ii = 0; ii < pPIndex; ii++) 
    { 
     sumOfPayoffs += possiblePayoffs[i]; 
    } 

    averagePayoff = sumOfPayoffs/pPIndex; 

    return averagePayoff; 
} 

鏈接是當numStrokes是6的額外實例中,只是在我想要做的情況下,是不是已經很清楚:

http://hastebin.com/hemolikodo.avrasm

到目前爲止,我想出了以下嘗試實現numStrokes amou nt嵌套循環,但它不起作用(如果沒有其他原因,因爲該函數試圖在遞歸調用自身時創建另一個int i副本)。我不確定這個代碼是否是正確的方法。我甚至不確定我應該試圖遞歸地做這件事。我認爲只是使用巨大的if語句來執行基於numStrokes的值的代碼,但更通用的實現似乎更可取。

double checkProfitability(GameState state, int numStrokes, int i) 
{ 
    double[] possiblePayoffs = new double[50000]; 
    int pPIndex = 0; 
    double sumOfPayoffs = 0; 
    double averagePayoff = 0; 

    if (numStrokes == 0) 
    { 
     // Populate possiblePayoffs[] 
    } 
    else 
    { 
     for (int i = 0; i <= 5 && numStrokes >= 1; i++) 
     { 
      checkProfitability(state, --numStrokes, i); 
     } 
    } 

    for (int ii = 0; ii < pPIndex; ii++) 
    { 
     sumOfPayoffs += possiblePayoffs[ii]; 
    } 

    averagePayoff = sumOfPayoffs/pPIndex; 
    richTextBox1.Text = averagePayoff.ToString(); 

    return averagePayoff; 
} 

任何人都可以解釋如何正確實施這個嗎?

編輯:問題是,我不知道我需要多少嵌套循環,直到運行時。

+1

不應該甚至編譯自定義具有相同名稱的兩個變量。 –

+0

您正在修改'state.colors',但是甚至沒有在使用未修改的'pIndex'和'possiblePayoffs'的「return」值中使用它。 – crashmstr

+0

@crashmstr state.colors []用於將值分配給possiblePayoffs。我用註釋替換了算法// Populate possiblePayoffs [],因爲代碼很長。 – user10478

回答

0
for (int i = 0; i < Math.Pow(6, numStrokes); i++) 
{ 
    int innerForIndex = i; 
    for (int j = 0; j < numStrokes; j++) 
    { 
     colors[innerForIndex % 6]++; 
     innerForIndex /= 6; 
    } 

    //populate your possiblePayoffs[] 

    innerForIndex = i; 
    for (int j = 0; j < numStrokes; j++) 
    { 
     colors[innerForIndex % 6]--; 
     innerForIndex /= 6; 
    } 

} 

numStrokes for循環,從0到5包容性意味着你總Math.Pow(6, numStrokes)元素。你用你的內部循環索引遞增/遞減一些cololrs陣列。這些指標可以很容易地從元素數中計算出來,對於numStroke == 3,例子k可以計算爲innerForIndex % 6,j爲(innerForIndex/6) % 6,i爲((innerForIndex/6)/6) % 6

0
for (int i = 0; i <= 5 * numstrokes; i++) 
{ 
    // Populate possiblePayoffs[] 
    if(i % 5 == 0) 
    { 
     //start of next loop 
    } 
} 

爲什麼不這樣做?

+0

//填充possiblePayoffs []不應該發生,直到最內層的嵌套循環。問題是我不知道在運行時需要多少嵌套循環,而不是每個循環的迭代次數是可變的。 – user10478

0

問題不明確。但我認爲遞歸將幫助你解決這類案件。我可以理解的是你需要做一些循環numstocks * 6(下面的代碼將循環這麼多時間,如果是這樣的話代碼將被構造爲(沒有測試它,可能需要一些小的修改)

double checkProfitability(GameState state, int numStrokes) 
{ 
if(numStrokes!=0) 
{ 
    for (int i = 0; i <= 5; i++) 
    { 
     checkProfitability(state,numStrokes-1); 
    } 
} 
//your code //calls this code numStrokes*6 times 
} 

更多在提防計算器異常也

+0

我想我實際上需要循環6^numStrokes次,而不是6 * numStrokes,但是,你的代碼是在正確的軌道上。我不明白的是,如果沒有讓我進入功能,這是如何工作的。例如,如果numStrokes = 2,我需要執行:for(int i = 0; i <= 5; i ++){state.colors [i] ++; for(int j = 0; j <= 5; j ++){state.colors [j] ++; //做其他的事情; state.colors [j] - ;} state.colors [i] - ;}。我無法看到如何遞增和遞減state.colors [i]和state.colors [j]而無需傳入迭代數字。 – user10478

1

這是最接近我想我可以讓你解決這個問題。

首先登場的是這種方法checkProfitability

double checkProfitability(GameState state, int numStrokes) 
{ 
    var possiblePayoffs = new double[50000]; 
    computePayoffs(state, possiblePayoffs, Enumerable.Empty<int>(), numStrokes); 
    var averagePayoff = possiblePayoffs.Select(x => (double)x).Average(); 
    richTextBox1.Text = averagePayoff.ToString(); 
    return averagePayoff; 
} 

遞歸現在處於computePayoffs方法:

void computePayoffs(GameState state, int[] possiblePayoffs, 
    IEnumerable<int> values, int numStrokes) 
{ 
    if (numStrokes == 0) 
    { 
     // Populate possiblePayoffs[] 
    } 
    else 
    { 
     for (int i = 0; i <= 5; i++) 
     { 
      state.colors[i]++; 
      computePayoffs(
        state, 
        possiblePayoffs, 
        values.Concat(new [] { i }), 
        numStrokes - 1); 
      state.colors[i]--; 
     } 
    } 
}