n个项目的k组成,带有“灰色代码”类似属性

发布于 2025-01-25 17:14:57 字数 1221 浏览 3 评论 0原文

我已经知道如何产生n个值的k组合,如下所述 >。问题是我需要一个额外的属性:我希望每对连续组合仅在一个位置上有所不同(或“ 灰色代码”类似属性)。在施工期间完成或在生成所有组合后使用特殊排序规则都没关系。

例如,具有k = 3,n = 5的原始实现会产生以下序列

 0 1 2
 0 1 3 <- good, previous line differs only in the last position (2->3)
 0 1 4
 0 2 3 <- bad, there are two changes (1->2) and (4->3)
 0 2 4
 0 3 4
 1 2 3
 1 2 4
 1 3 4
 2 3 4

,我想看到类似的东西(可以有多个满足“灰色代码”类似属性的解决方案)。

 0 1 2
 0 1 3 
 0 2 3
 0 2 4
 0 1 4
 0 3 4
 2 3 4
 1 3 4
 1 2 4
 1 2 3

似乎可以将所有数字保存在组合中(1 0 2不应该发生,只有0 1 2)。


更新

答案 @Stef显示了一个解决方案,其中包含以下数字的顺序。如果我们独立考虑不同列中的更改,则无法满足单个变更属性。

0, 1, 2
0, 2, 3
1, 2, 3
0, 1, 3 <- bad, change 1: (1->0), change 2: (2->1)
0, 3, 4
1, 3, 4
2, 3, 4
0, 2, 4
1, 2, 4
0, 1, 4

在组合中重新排序数字的明显建议(0 1 3 1 0 3 )无法满足上述分类要求。

目前尚不清楚是否存在满足此约束的解决方案的任何对(n,k),但到目前为止,我还没有发现何时无法进行。

I already know how to generate k combinations of n values as described here https://stackoverflow.com/a/28698654/15853075. The problem is that I need one additional property: I want each pair of successive combinations to differ only at one position (or have "Gray code"-like property). It doesn't matter if it is done during construction or uses a special sorting rule after all combinations are generated.

For example, the original implementation with k=3, n=5 produces the following sequence

 0 1 2
 0 1 3 <- good, previous line differs only in the last position (2->3)
 0 1 4
 0 2 3 <- bad, there are two changes (1->2) and (4->3)
 0 2 4
 0 3 4
 1 2 3
 1 2 4
 1 3 4
 2 3 4

Instead, I want to see something like this (there can be multiple solutions that satisfy "Gray code"-like property).

 0 1 2
 0 1 3 
 0 2 3
 0 2 4
 0 1 4
 0 3 4
 2 3 4
 1 3 4
 1 2 4
 1 2 3

It seems that it is possible to keep all numbers inside the combination sorted (1 0 2 should not occur, only 0 1 2 is allowed).


Update

The answer by @Stef shows a solution with the sequence of numbers below. It fails to satisfy the single change property if we consider changes in different columns independently.

0, 1, 2
0, 2, 3
1, 2, 3
0, 1, 3 <- bad, change 1: (1->0), change 2: (2->1)
0, 3, 4
1, 3, 4
2, 3, 4
0, 2, 4
1, 2, 4
0, 1, 4

The obvious suggestion to reorder the numbers in a combination (to replace 0 1 3 by 1 0 3) fails to satisfy the sortedness requirement mentioned above.

It is not clear if solution that satisfies this constraint exists for any pair (n, k), but so far I didn't find when it was not possible.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

傲性难收 2025-02-01 17:14:57

我找到了以下复发公式,以生成灰色代码的组合列表:

C(n,k) = C(n-1,k).0 + [C(n-1,k-1)]bar.1

来源: encyclopediaofmaths.org:灰色代码#combinations

带有符号的说明:

  • c(n,k)是灰色n元素的k组合列表代码顺序;
  • c(n-1,k).0只是c(n-1,k)
  • [l] bar表示“列表l in反向顺序“
  • l.1表示“列表L中的元组,n-1添加到每个元组中”,

并使用所有元组,并且使用Python Generrence公式将变为:

def combinations_graycode(n, k):
    yield from combinations_graycode(n-1, k)
    for comb in reversed(list(combinations_graycode(n-1, k-1))):
        yield comb + (n-1,)

添加base--递归的情况,这是整个Python代码:

def combinations_graycode(n, k):
    if k < 0:
        raise ValueError('k must be non-negative')
    elif k > n or n < 1:
        pass
    elif k == 0:
        yield ()
    elif k == n:
        yield tuple(range(n))
    else:
        yield from combinations_graycode(n-1, k)
        for comb in reversed(list(combinations_graycode(n-1, k-1))):
            yield comb + (n-1,)

print(list(combinations_graycode(5, 3)))
# [(0, 1, 2), (0, 2, 3), (1, 2, 3), (0, 1, 3), (0, 3, 4), (1, 3, 4), (2, 3, 4), (0, 2, 4), (1, 2, 4), (0, 1, 4)]

I found the following recurrence formula to generate the list of combinations in Gray-code order:

C(n,k) = C(n-1,k).0 + [C(n-1,k-1)]bar.1

Source: encyclopediaofmaths.org: Gray-code #Combinations

With notations explained:

  • C(n,k) is the list of k-combinations of n elements in Gray-code order;
  • C(n-1,k).0 is just C(n-1,k)
  • [L]bar means "list L in reverse order"
  • L.1 means "the tuples from list L, with n-1 added to each tuple"

With all that in mind, and using python generators, the recurrence formula becomes:

def combinations_graycode(n, k):
    yield from combinations_graycode(n-1, k)
    for comb in reversed(list(combinations_graycode(n-1, k-1))):
        yield comb + (n-1,)

Adding a base-case for the recursion, here is the whole python code:

def combinations_graycode(n, k):
    if k < 0:
        raise ValueError('k must be non-negative')
    elif k > n or n < 1:
        pass
    elif k == 0:
        yield ()
    elif k == n:
        yield tuple(range(n))
    else:
        yield from combinations_graycode(n-1, k)
        for comb in reversed(list(combinations_graycode(n-1, k-1))):
            yield comb + (n-1,)

print(list(combinations_graycode(5, 3)))
# [(0, 1, 2), (0, 2, 3), (1, 2, 3), (0, 1, 3), (0, 3, 4), (1, 3, 4), (2, 3, 4), (0, 2, 4), (1, 2, 4), (0, 1, 4)]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文