简体   繁体   中英

C# Recursion Logic

I am attempting to write a function in which the number of nested loops is dependent upon an integer (numStroke) passed into it. For example, when numStrokes is 1, the code executed should be:

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;
}

When numStrokes is 3, it should be:

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;
}

Linked is the extra example of when numStrokes is 6, just in case what I'm trying to do isn't already clear:

http://hastebin.com/hemolikodo.avrasm

So far, I have come up with the following attempt to implement numStrokes amount of nested loops, but it does not work (if for no other reason, because the function tries to create another copy of int i when it calls itself recursively). I'm not sure if this code is even the right approach. I'm not even certain that I should be trying to do this recursively. I considered just using a giant if statement that executes code based on the value of numStrokes, but a more general implementation seemed preferable.

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;
}

Can anyone explain how to implement this properly?

Edit: The problem is that I don't know how many nested loops I need until run time.

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 loops from 0 to 5 inclusive means you have total Math.Pow(6, numStrokes) elements. You use your inner loops indexes to increment/decrement some cololrs array. Those indexes can be easily calculated from element number. For numStroke == 3 example k can be calculated as innerForIndex % 6 , j as (innerForIndex / 6) % 6 , i as ((innerForIndex / 6) / 6) % 6 .

This is the closest I think I can get you to a solution for this.

First up this is the checkProfitability method:

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;
}

The recursion is now in the computePayoffs method:

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]--;
        }
    }
}
for (int i = 0; i <= 5 * numstrokes; i++)
{
    // Populate possiblePayoffs[]
    if(i % 5 == 0)
    {
        //start of next loop
    }
}

Why not do this?

The question is not clear. But I think recursion will help you to solve these type of cases. What i could understand is you need to do some looping numstocks*6(The below code will loop this much time. If this is the case The code will be structured as(Didn't test it. May need some minor modifications)

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
}

More over beware of stackoverflow Exception also

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM