【问题标题】:How to determine how many times will a statement inside a loop will be executed with conditional statements如何确定循环内的语句将使用条件语句执行多少次
【发布时间】:2011-10-08 00:11:28
【问题描述】:

有一个包含 12 个问题的测试。每个问题的值必须大于 4 分。所有问题必须加到 100。所有问题也必须有一个整数值。 所以可能的组合可能是 5,5,5,5,5,5,5,5,5,5,5,45

有一种方法理论上会给出这个结果:

// this method will return the possible number of tests
public static double PosibleNumberOfTests()
{
    int q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11, q12; // each question value

    double counter=0; // if there is a valid combination then counter will be increased by 1

    for (q12 = 5; q12 < 46; q12++)
    {
        for (q11 = 5; q11 < 46; q11++)
        {
            for (q10 = 5; q10 < 46; q10++)
            {
                for (q9 = 5; q9 < 46; q9++)
                {
                    for (q8 = 5; q8 < 46; q8++)
                    {
                        for (q7 = 5; q7 < 46; q7++)
                        {
                            for (q6 = 5; q6 < 46; q6++)
                            {
                                for (q5 = 5; q5 < 46; q5++)
                                {
                                    for (q4 = 5; q4 < 46; q4++)
                                    {
                                        for (q3 = 5; q3 < 46; q3++)
                                        {
                                            for (q2 = 5; q2 < 46; q2++)
                                            {
                                                for (q1 = 5; q1 < 46; q1++)
                                                {
                                                    if (q1 + q2 + q3 + q4 + q5 + q6 + q7 + q8 + q9 + q10 + q11 + q12 == 100)
                                                        counter++;  // here is what we need. How many times will this line be executed!
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

    }
    return counter;
}

请注意,我为小于 46 的值创建了每个循环,因为如果所有问题的值都必须大于 4,那么例如一个问题就不可能获得 50 分。

编辑

对不起,我认为我没有清楚地解释自己。我选择了 12 个问题作为随机猜测。这个例子可能是一个有 100 个问题的测试。我需要类似 dlev 在他的评论中提到的东西。我也知道我可以在循环中放置中断以使该方法更有效。如果总和大于 100 那么为什么继续循环只是从相应的循环中退出

【问题讨论】:

  • 拜托,看在上帝的份上,不要运行该代码。
  • 我知道,哈哈。所以我称之为理论方法
  • 你的问题是:我如何计算出有多少个排列加起来等于 100?
  • 我只想知道可能存在多少种不同的测试。请记住,每个问题必须至少值 5 分。所有问题必须加到 100。可能的组合是:5,5,5,5,5,5,5,5,5,5,5,45 或 5,5,5,5,5,5,5 ,5,5,5,6,44 或 5,5,5,5,10,10,10,10,10,10,10,10 等...
  • 这是整数分区的一种变体。标准问题是“对于给定的 N,我有多少种方法可以形成一组整数,使得它们的总和为 N?”您的问题只是添加了“集合的大小必须为 12,并且任何元素都不能小于 5。”有关一些想法,请参阅此维基百科链接,尤其是“中间函数”部分:en.wikipedia.org/wiki/Partition_%28number_theory%29(注意:如果您也关心问题的 顺序,那么您正在谈论 compositions 而不是 partitionsen.wikipedia.org/wiki/Composition_%28number_theory%29)

标签: c# iteration probability


【解决方案1】:

此代码将评估if 语句22,563,490,300,366,186,081 次。不用说,那是行不通的……

但只要稍作改动,就可以了。我并不是说蛮力是解决这个问题的方法,但它确实有效。

首先,为了让表达式更简单一点,如果每个问题的分数必须是非负数并且分数必须加起来为40,则观察他有同样的问题。

现在,第一个循环变为for (q12 = 0; q12 &lt;= 40; q12++)

在第二个循环中,我们不必测试040 之间的所有q11,因为q11 + q12 不能大于40

所以,第二个循环变成了for (q11 = 0; q11 + q12 &lt;= 40; q11++)

等等……

最后,最后一个for 循环是完全没有必要的,因为q1 只有一个可能的值。

所以,改变

for (q1 = 5; q1 < 46; q1++)
    if (q1 + q2 + q3 + q4 + q5 + q6 + q7 + q8 + q9 + q10 + q11 + q12 == 100)
        counter++;

if (q2 + q3 + q4 + q5 + q6 + q7 + q8 + q9 + q10 + q11 + q12 <= 40)
    counter++;

不快。不优雅。但它有效。

虽然这比最初的实现要快得多,但即使每秒找到1,000,000“好”组合,仍然需要大约 13 个小时...

让我们将问题更改为“每个问题必须至少值得 1 分,并且所有分数的总和必须为 52”。这相当于最初的问题。

我们有52 点要分发。每个星号代表一个点:

****************************************************

为此,我们可以使用分隔符分隔这些点。十一个分隔符会给我们12 星号组。

示例:****|*****|****|********|*|***|**|****|****|*********|***|*****

每个分隔符必须在两个相邻的星号之间。这些空间有51

由于分隔符不存在差异,因此解决方案也是“11 项目可以在51 点中分配多少种不同的、与顺序无关的方式。

给定一组51 元素中11-combinations 的数量是51! / ( 40! * 11! ),这给了我们47,626,016,970

这一切都是假设“顺序很重要”,即。即,如果问题 1 值 10 分,问题 2 值 20 分,或者反之亦然,则不同。

对于q 问题,每个问题的价值超过p 分,并且在测试中总共获得t 分,公式为:

(t - p * q - 1)! / ( (t - (p + 1) * q)! * (q - 1)! )

【讨论】:

  • 丹尼斯我不认为你理解这个问题,哈哈。或者也许我错过了什么......
  • 哦,我明白你的意思了。这是一个好点!是的,我还必须添加中断,这样如果循环超过 100,从方法中中断会更快。
  • 我希望能够告诉方法的输出而不必运行它。如果使用您的技术进行包含 100 个问题的测试肯定会使它变得更简单,但执行起来需要几个月的时间。我需要一个解决这类问题的公式......抱歉没有清楚地解释我自己
  • 是的,但我的数学有点不对劲。但也行不通。见编辑。
  • 是的,但我明白你的意思。我没有想到这一点。例如,如果总和大于 100,我想退出循环,但你的技术更容易实现,如果我打算执行该方法,则必须在那里
【解决方案2】:

每当您遇到计数问题时,最好先减去常数。在这种情况下,每个问题的最小值是 5,因此从每个值和总数中减去它。这为您提供了最多 40 个问题,每个问题最少为 0 个。然后在最后,当你提出实际的解决方案时,你可以再次添加常量。

现在看这个问题:Distribution of balls into 'bins with given capacities' using Dynamic Programming

你的问题是一样的,只是它更简单一点。这是相同的,因为您的问题对应于垃圾箱,而值对应于球。

你的更简单,因为在你的情况下,问题的容量没有限制。在上述问题的公认答案中,min(n, c[k]) 始终等于 n

【讨论】:

    【解决方案3】:

    老师的回答:(和你们感谢的一样!)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-11-04
      • 2017-03-23
      • 2021-03-03
      • 1970-01-01
      • 2018-05-27
      • 2015-03-20
      • 1970-01-01
      相关资源
      最近更新 更多