0

在我说别的之前 - 这个问题可能看起来很长,但实际上它只是核心中的一个问题,这种问题会重复出现。我正在尝试创建一个与概率有关的“解谜器”。这是一个模型,解决问题的人必须在没有计算机帮助的情况下完成,但我希望能够拥有一个脚本,我可以在其中更改不同条件下的变量。我们将这个测试用于潜在员工,我们必须想出答案。这很乏味,所以我希望有人可以帮助我尝试在 Python 中做到这一点?我仍在学习 Python,但因为我看到每个人都可以轻松地“操纵”它来为他们提供所需的东西,所以我希望学习如何做到这一点,所以我不必一遍又一遍地手动完成。

这是测试的一个例子 -

鉴于事实:

  1. 一排有5间房子,从左到右依次编号为1、2、3、4、5。
  2. 每栋房子都涂有不同的颜色:红色、橙色、黄色、绿色或蓝色。
  3. 每所房子由不同的人拥有:Ann、Bob、Carl、Dorothy 或 Ed。
  4. 每栋房子都有不同数量的窗户:一、二、三、四、五
  5. 每栋房屋建于不同的年份:1970 年、1980 年、1990 年、2000 年或 2010 年。
  6. 每个人都懂不同的语言:西班牙语、法语、拉丁语、德语、意大利语。

然后我们给他们约束:

  1. 鲍勃住在黄色的房子里。
  2. 安懂拉丁语。
  3. 橙色的房子有5扇窗户。
  4. 多萝西住在一个有两扇窗户的房子里。
  5. 橙色的房子就在温室的右边。
  6. 这位讲德语的人住在这座建于 2000 年的房子里。
  7. 红房子建于1970年。
  8. 中间的房子有3个窗户。
  9. 卡尔住在第一所房子里。
  10. 这座建于 1980 年的房子紧挨着这位意大利演讲者的房子。
  11. 这座建于 1970 年的房子毗邻这位说法语的人居住的房子。
  12. 建于 1990 年的房子有 1 个窗户。
  13. Ed住在一栋建于2010年的房子里。
  14. 卡尔住在蓝房子旁边。

潜在员工必须弄清楚:

对于编号为 1 到 5 的每栋房子,住在那里的人、房子是什么颜色、有多少窗户、什么时候建造的以及居住者说什么语言。这正是我想要放入 Python 的内容!

我试了一下,这是我的理由:

def permutations(x):
    outlist = []
    for a in x:
        for b in x:
            if b == a:
                continue
            for c in x:
                if c == b or c == a:
                    continue
                for d in x:
                    if d == a or d == b or d == c:
                        continue
                    for e in x:
                        if e == a or e==b or e==c or e==d:
                            continue
                        outlist.append([a,b,c,d,e])
    return outlist

循环中的“检查”是为了​​在重复条目时循环继续,因此除非早期循环有效,否则内部循环不必执行 - 节省时间!

给定一个包含五个元素的列表 x,此函数返回一个列表列表,每个列表都是原始五个元素的排列,其中没有一个元素等于另一个。因此,如果列表输入是 x = [1,2,3,4,5],则返回的输出是一个可能排列的列表:

Outlist = [[1,2,3,4,5],[1,2,3,5,4],[1,2,4,3,5],[1,2,4,5,3], ...]

这将有 5 个!= 120 个元素。

所以,我知道它在理论上是如何工作的,但是用 Python 写下来对我来说“翻译”非常重要。

我将名称变量 (Ann,Bob,Car​​l,Dorothy,Ed) 指定为这些排列之一(例如 [1,2,5,4,3]),这意味着 Ann 住在 1 号房子里,Bob 住在 2 号房子里, Carol 住在 5 号屋,Dorothy 住在 4 号屋,Ed 住在 3 号屋。

同样,我知道您可以将这些排列中的另一个(例如 [5,4,3,1,2])分配给颜色变量(红、橙、黄、绿、蓝),这意味着房子 5 是红色,房子 4橙色,3 号房屋为黄色,1 号房屋为绿色,2 号房屋为蓝色。

您可以为窗户数量(一、二、三、四、五)、房屋建造年份(七、八、九、零、十)和所用语言分配相同或另一种排列。

这就是我真正迷失的地方,因为我很难理解如何重复使用相同的数字——在这种情况下它们不会被覆盖吗?

不过,首先要做的是——如果我们首先检查这个任务的线索是否正确,会更好(更省时)。如果没有,参加考试的人可以去另一个作业!

编码方面,这就是我的想象,但我对 Python 的有限知识并没有真正帮助我编写“正确的代码”:

a) check if Bob lives in the yellow house, by Bob == Yellow 

(即分配给 Bob 的门牌号与分配给 Yellow 的门牌号相同。b)检查 1970 年建造的房子是否与说法语的人住的房子相邻,做绝对值计算 ->

abs(Seven – French) == 1

这意味着分配给七号和法文的门牌号仅相差 1。

此外,我知道还有额外的检查,并且所有这些检查都必须作为 True 传递,五个排列分配才能成为难题的解决方案。

然后我使用循环将排列分配给变量:

for a in outlist:
    (Ann,Bob,Carl,Dorothy,Ed) = a

它将给 Ann 赋值 a[0],Bob 赋值 a[1],Carol 赋值 a[2],Dorothy 赋值 a[3],Ed 赋值 a[4],因为我们循环遍历所有排列在 outlist 中,其中 outlist 是函数的输出,是排列列表的列表。

另一个问题 - 列出清单......显示有点困难。

我知道我必须为感兴趣的变量编写五个嵌套的赋值循环。为了验证分配是否满足线索,我考虑在完成部分分配后在每个循环中逐步检查线索的子集,因此除非线索子集得到满足,否则我不会枚举内部循环。同样,它使程序运行得更快、更有效。

这是第一个循环的尝试,它(例如)在名称上。我知道 Carl 必须住在 1 号房子里,如果这不是真的,其他循环不会被执行!在纸面上,你必须不断重复这个过程,直到 Carl == 1!

尝试编写代码:

for a in outlist:
(Ann,Bob,Carl,Dorothy,Ed) = a
if Carl != 1:
    continue
for b in outlist:
    (Red,Orange,Yellow,Green,Blue) = b
    if ...  

使用此代码,内部四个循环仅在 Carl == 1 时执行。我知道我必须继续,但变量的重叠在这里也是一个问题。

最后 - 有人建议我使用时间模块“计时功能”

time.time().  

我知道在 Mac(所以我的)中报告的当前时间是以微秒为单位的,这是根据那个写的。不知道如何获得正确的代码。

import time
start = time.time()
#CODE
end = time.time()
print('Running Time: {} msecs'.format((end - start)*0.001))

感谢您完成此任务!我发现它非常压倒性,不知道从哪里开始,但我肯定希望有这样的东西为我做我所有的排列!

4

1 回答 1

1

用于itertools.permutations()生成排列:

from itertools import permutations

for colors in permutations(range(5)):
    # colors is permuted combination of 5 integers between 0 and 4, inclusive.

这使用从 0 到 4 的数字,因为这对 Python 来说更自然,但原理是一样的;如果你愿意,你可以使用它range(1, 6)来生成整数 1 到 5 的排列,包括 1 到 5。

现在嵌套你的排列循环。外环用于颜色选择;每个数字代表该房子的颜色。测试约束,消除所有不适合的(任何橙色不靠近绿色的组合都不适合)。在约束适合的地方,为所有者循环排列,消除那些不适合的,为那些适合的循环窗口计数,等等。

使用一个函数来测试约束,允许缺少方面,以保持测试简单。

你会发现你可以很早就很快地消除大多数连击。

于 2013-04-27T08:17:12.447 回答