创建 12 项二阶序列号生成器

Creating 12-item second order sequence number generator

提问人:notacoder 提问时间:11/16/2023 最后编辑:notacoder 更新时间:11/16/2023 访问量:56

问:

我对编码很陌生,所以如果这是一个明显的问题,我深表歉意。我正在尝试创建一些代码,这些代码将创建符合某些约束的 12 项长数字序列:

  1. 每个数字重复相同的次数
  2. 没有单个数字重复(不能有 1-1)
  3. 没有数字对重复(不能有 1-2 后跟 1-2)

我曾尝试解决 2017 年提出的二阶条件问题(python 中的二阶序列),但我无法让它工作。这是我一直在编辑的代码:

from random import choice

def second_order_random(k,SOC):
    n0 = choice(range(1,k+1))
    yield n0
    n1 = choice(range(1,k+1))
    yield n1
    while True:
        (n0,n1) = (n1,choice(SOC[(n0,n1)]))
        yield n1

# dictionary defining valid sequences
SOC = {
    (1, 2):(3, 4),
    (1, 2):(4, 3),
    (1, 3):(2, 4),
    (1, 3):(4, 2),
    (1, 4):(2, 3),
    (1, 4):(3, 2),
    (2, 1):(3, 4),
    (2, 1):(4, 3),
    (2, 3):(1, 4),
    (2, 3):(4, 1),
    (2, 4):(1, 3),
    (2, 4):(3, 1),
    (3, 1):(2, 4),
    (3, 1):(4, 2),
    (3, 2):(1, 4),
    (3, 2):(4, 1),
    (3, 4):(1, 2),
    (3, 4):(2, 1),
    (4, 1):(2, 3),
    (4, 1):(3, 2),
    (4, 2):(1, 3),
    (4, 2):(3, 1),
    (4, 3):(1, 2),
    (4, 3):(2, 1)
}
for n in second_order_random(4, SOC):
    print(n)

如果我尝试将“k”替换为任何值(我尝试了 4 次尝试并遵循示例),我会得到“SyntaxError:语法无效”输出,否则它什么都不做。我不确定我做错了什么。

python pycharm 序列

评论

0赞 Barmar 11/16/2023
你在哪里替换了?你不能在函数参数列表中替换它,参数始终是变量。k
0赞 Barmar 11/16/2023
展示您如何使用该函数。它应该是这样的for n in second_order_random(4, SOC):
0赞 CrazyChucky 11/16/2023
你的第一个问题是你已经定义了你的函数,但你还没有调用它。(你可能会也可能不会有进一步的问题,但在你打电话之前什么都不会发生。
0赞 notacoder 11/16/2023
在原始示例中,它使用了 iteratools,但我的 PI 告诉我不要使用该工具箱。我想也许问题出在函数的定义上。我的调用函数为:for n in second_order_random(4, SOC): print(n)
0赞 notacoder 11/16/2023
这些数字现在正在生成,但无限生成。在不使用 iteratools 的情况下生成 12 个项目后,有没有一种好方法可以停止循环?

答:

0赞 gog 11/16/2023 #1

你没有说你想使用多少个数字,但对于 12,最小值显然是 3。这里有一个简单的回溯算法,它为“下一个”号码创建一个候选列表,排除那些违反要求的人,并尝试填写列表的其余部分。如果失败,它会回溯并选择下一个可能的候选者:

import random

def fill(src, dst=None):
    # print(src, ' >> ', dst)

    if not src:
        return dst

    dst = dst or []

    free = set(src)
    if len(dst) > 0:
        free.discard(dst[-1])
    if len(dst) > 2 and dst[-1] == dst[-3]:
        free.discard(dst[-2])

    while free:
        n = random.choice(list(free))
        free.remove(n)
        src2 = list(src)
        src2.remove(n)
        dst2 = fill(src2, dst + [n])
        if dst2:
            return dst2
    

##

src = [1, 2, 3] * 4
res = fill(src)
print(res)

# for example, [2, 3, 1, 2, 1, 3, 1, 2, 3, 1, 2, 3]

评论

0赞 notacoder 11/16/2023
谢谢,真的很有帮助!我能够编辑它,因此它也运行了 [1, 2, 3, 4]。如果我希望每个序列都以特定的一对开头(例如“1,2...”),是否可以添加这种约束?
0赞 gog 11/16/2023
当然,您可以从 (=剩余元素) 和 (=结果序列) 的任意组合开始。srcdst
0赞 gog 11/16/2023
例如fill([3,4,1,2,3,4,1,2,3,4], [1,2])