在使用动态规划的Python程序中未获得预期的输出。

huangapple go评论76阅读模式
英文:

Not getting the output as expected in a Python program that uses dynamic programming

问题

我写了一个使用动态规划的程序:

def count_partitions(n, k):
    if n < k:
        return 0
    elif n == k == 3:
        return 1
    else:
        # 使用基本情况初始化表格
        table = [[0] * (k+1) for _ in range(n+1)]
        table[3][3] = 1

        # 使用递推关系填充表格
        for i in range(4, n+1):
            for j in range(3, k+1):
                table[i][j] = (j-2) * table[i-1][j] + (j-1) * table[i-1][j-1]

        return table[n][k]

问题是针对以下情景:

一个学生关心中心将学生分成组,监督他们自学。然而,来自同一家庭的三胞胎总是互相交谈,中心工作人员不希望将他们中的任何两个放在同一组中。假设有n名学生,包括三胞胎,学生关心中心如何将这些学生分成k组?允许一个组中只有一个学生,但不允许有空组。组的顺序不重要,因此如果通过重新排列组的顺序可以将一个分组转换为另一个分组,则被视为相同的方式。

G(n, k) = G(n-1, k-1) + k × G(n-1, k)

我正在编写的程序可以通过提供“n”和“k”的值来解决分区问题的特定实例。

“count_partitions”函数用于计算将“n”个不同的项分成“k”个非空集的方式数量。给定程序中的“count_partitions”函数还包含了当“n”和“k”都等于3时的特定情况。在这种情况下,函数返回值1,表示将3个不同的项分成3个非空集的方式只有一种。

我的代码运行了,但我没有得到预期的结果。我希望这些输出:

# 输出1,应输出3
count_partitions(4, 3)
# 输出1,应输出9
count_partitions(5, 3)
# 输出21,应输出37
count_partitions(6, 4)

希望这对你有所帮助。如果你有其他问题,请随时提出。

英文:

I've written this program that uses dynamic programming:

def count_partitions(n, k):
    if n &lt; k:
        return 0
    elif n == k == 3:
        return 1
    else:
        # Initialize table with base cases
        table = [[0] * (k+1) for _ in range(n+1)]
        table[3][3] = 1

        # Fill in table using recurrence relation
        for i in range(4, n+1):
            for j in range(3, k+1):
                table[i][j] = (j-2) * table[i-1][j] + (j-1) * table[i-1][j-1]

        return table[n][k]

The problem is for the following senario:

A student care center partitions students into groups and supervises them for self-study. However, there is a triumph of triplets from the same family who always talk to one another, center staff will not want to place any two of them in the same group. Suppose there are n students including the triplets, how many ways can the student care center partition these n students into k groups? It is allowed to have only one student in a group, but not allowed to have an empty group. The order of the groups does not matter, so it is considered as the same way if one grouping can be
converted to another by rearranging the sequence of the group.
G(n, k) = G(n-1, k-1) + k × G(n-1, k)

I'm making this program that can be used to solve a specific instance of the partitioning problem by providing the values of "n" and "k" as input.

The "count_partitions" function is used to calculate the number of ways to partition "n" distinct items into "k" non-empty sets.
The "count_partitions" function in the given program also contains a specific case for when both "n" and "k" are equal to 3. In this case, the function returns the value 1, indicating that there is only one way to partition 3 distinct items into 3 non-empty sets.

My code runs, but I don't get the expected results. I would expect these outputs:

# Outputs 1, should output 3
count_partitions(4, 3)
# Outputs 1, should output 9
count_partitions(5, 3)
# Outputs 21, should output 37
count_partitions(6, 4)

答案1

得分: 0

由于您未提供问题的描述,我们无法帮助您找到正确的解决方案,但我们可以帮助您开始理解您当前的程序行为方式。

最简单的情况是输入 n=4, k=3,它的输出是 1。这是因为您初始化表格如下所示:

    table = [[0] * (k+1) for _ in range(n+1)]
    table[3][3] = 1

因此,执行后,您的表格将成为一个 5x4 的矩阵,除了位置 [3,3] 外都是 0:

# k=0 1 2 3
  [ 0 0 0 0 ] # n=0
  [ 0 0 0 0 ] #   1
  [ 0 0 0 0 ] #   2
  [ 0 0 0 1 ] #   3
  [ 0 0 0 0 ] #   4

然后,您的循环从 i=4(在 n 轴上)和 j=3(在 k 轴上)开始。它也在 i=4, j=3 停止。

for i in range(4, n+1):
    for j in range(3, k+1):

然后,您计算一个单个值(因为循环仅运行一次):

# i=4, j=3
# table[3][3] = 1
# 所有其他 table[x][y] = 0

table[i][j] = (j-2) * table[i-1][j] + (j-1) * table[i-1][j-1]

# 这化简为
table[4][3] = 1 * 1 + 2 * 0 = 1

然后,您返回 table[n][k],再次使用 n=4, k=3,因此这将返回在循环中设置的 1。

您需要做的是查看这个示例正在发生什么,并解释实际应该发生的情况。也许在解释中,您会找到问题。


根据您的编辑,您正尝试实现以下递归关系:

G(n, k) = G(n-1, k-1) + k * G(n-1, k)

而您的代码如下:

table[i][j] = (j-2) * table[i-1][j] + (j-1) * table[i-1][j-1]

所以,首先,您已经了解到变量名的重要性。很难看出这些表达式是否相符。让我们首先将目标递归(从 G 到 T,从 n 到 i,从 k 到 j)重新命名,并将代码从 table 重新命名为 t:

T(i, j) = T(i-1, j-1) + j * T(i-1, j)
t[i][j] = (j-2) * t[i-1][j] + (j-1) * t[i-1][j-1]

现在顺序也不同。让我们重新排列术语并将它们对齐:

T(i, j) = j * T(i-1, j) + T(i-1, j-1)
t[i][j] = (j-2) * t[i-1][j] + (j-1) * t[i-1][j-1]

现在您是否明白问题所在了吗?您编写的递归与您尝试创建的递归不一致。

英文:

Since you haven't provided a description of the problem, we can't help you find the right solution, but we can get you started on understanding why your current program behaves the way it does.

The simplest one is the inputs n=4, k=3, which outputs 1. This is because you initialize the table like this:

    table = [[0] * (k+1) for _ in range(n+1)]
    table[3][3] = 1

So your table, after this executes will be a 5x4 matrix of 0s, except for position [3,3], which is 1:

# k=0 1 2 3
  [ 0 0 0 0 ] # n=0
  [ 0 0 0 0 ] #   1
  [ 0 0 0 0 ] #   2
  [ 0 0 0 1 ] #   3
  [ 0 0 0 0 ] #   4

Then your loops start at i=4 (in the n-axis) and j=3 (in the k-axis). It also stops at i=4, j=3 as well.

for i in range(4, n+1):
    for j in range(3, k+1):

Then you compute a single value (since the loops only run once):

# i=4, j=3
# table[3][3] = 1
# all other table[x][y] = 0

table[i][j] = (j-2) * table[i-1][j] + (j-1) * table[i-1][j-1]

# This reduces to
table[4][3] = 1 * 1 + 2 * 0 = 1

Then you return table[n][k], again with n=4, k=3, so this returns 1, which was set in the loop.

What you need to do is look at what's happening for this example and explain what's supposed to happen instead. Maybe in explaining it, you will find the problem.


Based on your edit, you are trying to implement this recurrence:

G(n, k) = G(n-1, k-1) + k &#215; G(n-1, k)

What you have is

table[i][j] = (j-2) * table[i-1][j] + (j-1) * table[i-1][j-1]

So, to start, you've learned why variable names are important. It's hard to see whether these expressions line up. Let's start by renaming your target recurrence (from G to T, n to i, k to j), and renaming your code from table to t:

T(i, j) = T(i-1, j-1) + j &#215; T(i-1, j)
t[i][j] = (j-2) * t[i-1][j] + (j-1) * t[i-1][j-1]

Now the order is different, too. Let's re-arrange terms and line them up:

T(i, j) = j     &#215; T(i-1, j)   +           T(i-1, j-1)
t[i][j] = (j-2) * t[i-1][j]   +   (j-1) * t[i-1][j-1]

Do you see now what the problem is? The recurrence you've coded isn't the recurrence you're trying to make.

huangapple
  • 本文由 发表于 2023年3月3日 19:45:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/75626681.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定