当前位置: 首页 > 知识库问答 >
问题:

有没有一种方法来生成项目列表的所有唯一排列

拓拔弘扬
2023-03-14

我有五个属性的列表,每个属性有五个不同的值。我想生成它们的笛卡尔乘积,并过滤所有独特的排列。

一些背景:

我需要它们作为我的输入值来解决逻辑难题。在那里我对照他们检查规则以找到正确的解决方案。

from itertools import product

# input
names = ['Dana', 'Ingo', 'Jessica', 'Sören', 'Valerie']
ages = [26, 27, 30, 33, 35]
tops = ['Blouse', 'Poloshirt', 'Pullover', 'Sweatshirt', 'T-Shirt']
colors = ['blue', 'yellow', 'green', 'red', 'black']
sizes = ['XS', 'S', 'M', 'L', 'XL']

all_attributes = [names, ages, tops, colors, sizes]

# cartesian product (superhtml" target="_blank">set)
inputs = list(product(*all_attributes))

# the following code you do that...

也许一个简化的例子就能说清楚。

数据:

[['Dana', 'Ingo'], [26, 27]]

数据的笛卡尔乘积:

[('Dana', 26), ('Dana', 27), ('Ingo', 26), ('Ingo', 27)]

我想要的是:

[[('Dana', 26), ('Ingo', 27)],
 [('Dana', 27), ('Ingo', 26)],
 [('Ingo', 26), ('Dana', 27)],
 [('Ingo', 27), ('Dana', 26)]]

我不想要的是:

[[('Dana', 26), ('Ingo', 26)], ...

我不希望同一个值多次出现。位置很重要,因此它应该具有置换性质,对于包含五个元素的列表,它应该具有置换性质。我猜输出大小将是巨大的,并且可能无法计算,因此最好指定一些固定的位置值。例如,我想将“Dana”设置为第一个元素名。

输出:

[[('Dana', 26), ('Ingo', 27),
 [('Dana', 27), ('Ingo', 26)]]

出于好奇,也许你可以告诉我,这些概念的具体数学名称是什么,我需要什么?

拼图:

有五个朋友(达娜、英戈、杰西卡、索伦、瓦莱丽)在购物中心的收银台排队等候。他们都有不同的年龄(26, 27, 30, 33, 35),想为自己购买不同的上衣(衬衫、Polo恤、套头衫、运动衫、t恤)。顶部有不同的颜色(蓝色,黄色,绿色,红色,黑色)和尺寸(XS,S,M,L,XL)。

  1. “达娜”最想买的是“XL”。在她身后(但不是正后方)是一个穿着“黑色”上衣的人

共有2个答案

长孙兴德
2023-03-14

对于你所拥有的逻辑谜题类型,使用排列的方法存在一个基本问题。问题甚至不在于它们太多,以至于你的求解器不太可能在合理的时间内完成。问题是,你没有一种自动化的方法来检查规则和问题:除非你有一种方法来验证它们,否则所有的可能性都摆在你面前是毫无意义的。

为了解决这些问题,我创建了一个名为“解谜者”的项目:

  • https://github.com/madphysicist/puzzle-solvers
  • https://pypi.org/project/puzzle-solvers/
  • https://puzzle-solvers.readthedocs.io/en/latest/

这是一个小项目,目前只包含一个感兴趣的类:puzzle\u解算器。消除解算器。此类实现了解决问题中提出的消除过程类型问题所需的大多数操作。所有的逻辑都有文档记录,本教程是对您的确切问题的演练。我将在这里解释基本知识,以便您了解我所做的工作,并可能对其进行改进。

步骤1是识别队列中的位置是一个属性,就像年龄、姓名等。这意味着顺序不再相关。

第二步是认识到这是一个伪装的图形问题。您有30个节点:五个个体的所有可能属性(其中六个)。图表开始时几乎是完整的。只有给定类型的属性之间的边丢失,所以您从375条而不是完整的435条边开始。

最终目标是在图中的五个连通分支中的每类属性之间有一条边。最终的边数因此5 * 15 = 75。

那么如何去除边缘呢?像“T恤衫不是红色”这样的简单规则非常简单:只需去除边缘即可。比如“排队的最后一个人是30岁。”也很简单,而且在去除边缘方面更有利可图。将删除年龄不到30岁和位置5之间的所有边,以及年龄不到5岁和位置30之间的所有边。我添加了两个半生不熟的工具包装,以检查大于和小于条件,并删除表示不可能的组合的边。

求解器最重要的方面是,任何时候边缘被移除,它都完全遵循该操作的所有逻辑含义。想象一下,你有“一件‘波洛衫’是‘红色’、‘黄色’或‘绿色’”,你已经到了一个难题的地步,这三种颜色都与30岁无关。这意味着无论是谁穿的polo恤都不可能是30岁。事实上,“波洛衬衫”不能有任何endpoint不被这三种颜色共享的边缘。如果你递归地遵循这些推论,你会得到一个完整的解决方案。

我为无耻地出售我的包裹感到抱歉,但作为理由,我写这封信只是为了回答这个问题。

卫飞鹏
2023-03-14

这样就可以了,但需要很长时间。我减小了列表大小,因为您请求的选项有2488320000个排列:

from itertools import permutations, product

names = ['Dana', 'Ingo']
ages = [26, 27]
tops = ['Hemd', 'Poloshirt']
colors = ['blau', 'gelb']
sizes = ['XS', 'S']

options = []

# Generate the Cartesian product of all permutations of the options.
for name,age,top,color,size in product(*map(permutations,[names,ages,tops,colors,sizes])):
    # Build the option list. zip() transposes the individual lists.
    option = list(zip(name,age,top,color,size))
    options.append(option)
    print(option)

输出:

[('Dana', 26, 'Hemd', 'blau', 'XS'), ('Ingo', 27, 'Poloshirt', 'gelb', 'S')]
[('Dana', 26, 'Hemd', 'blau', 'S'), ('Ingo', 27, 'Poloshirt', 'gelb', 'XS')]
[('Dana', 26, 'Hemd', 'gelb', 'XS'), ('Ingo', 27, 'Poloshirt', 'blau', 'S')]
[('Dana', 26, 'Hemd', 'gelb', 'S'), ('Ingo', 27, 'Poloshirt', 'blau', 'XS')]
[('Dana', 26, 'Poloshirt', 'blau', 'XS'), ('Ingo', 27, 'Hemd', 'gelb', 'S')]
[('Dana', 26, 'Poloshirt', 'blau', 'S'), ('Ingo', 27, 'Hemd', 'gelb', 'XS')]
[('Dana', 26, 'Poloshirt', 'gelb', 'XS'), ('Ingo', 27, 'Hemd', 'blau', 'S')]
[('Dana', 26, 'Poloshirt', 'gelb', 'S'), ('Ingo', 27, 'Hemd', 'blau', 'XS')]
[('Dana', 27, 'Hemd', 'blau', 'XS'), ('Ingo', 26, 'Poloshirt', 'gelb', 'S')]
[('Dana', 27, 'Hemd', 'blau', 'S'), ('Ingo', 26, 'Poloshirt', 'gelb', 'XS')]
[('Dana', 27, 'Hemd', 'gelb', 'XS'), ('Ingo', 26, 'Poloshirt', 'blau', 'S')]
[('Dana', 27, 'Hemd', 'gelb', 'S'), ('Ingo', 26, 'Poloshirt', 'blau', 'XS')]
[('Dana', 27, 'Poloshirt', 'blau', 'XS'), ('Ingo', 26, 'Hemd', 'gelb', 'S')]
[('Dana', 27, 'Poloshirt', 'blau', 'S'), ('Ingo', 26, 'Hemd', 'gelb', 'XS')]
[('Dana', 27, 'Poloshirt', 'gelb', 'XS'), ('Ingo', 26, 'Hemd', 'blau', 'S')]
[('Dana', 27, 'Poloshirt', 'gelb', 'S'), ('Ingo', 26, 'Hemd', 'blau', 'XS')]
[('Ingo', 26, 'Hemd', 'blau', 'XS'), ('Dana', 27, 'Poloshirt', 'gelb', 'S')]
[('Ingo', 26, 'Hemd', 'blau', 'S'), ('Dana', 27, 'Poloshirt', 'gelb', 'XS')]
[('Ingo', 26, 'Hemd', 'gelb', 'XS'), ('Dana', 27, 'Poloshirt', 'blau', 'S')]
[('Ingo', 26, 'Hemd', 'gelb', 'S'), ('Dana', 27, 'Poloshirt', 'blau', 'XS')]
[('Ingo', 26, 'Poloshirt', 'blau', 'XS'), ('Dana', 27, 'Hemd', 'gelb', 'S')]
[('Ingo', 26, 'Poloshirt', 'blau', 'S'), ('Dana', 27, 'Hemd', 'gelb', 'XS')]
[('Ingo', 26, 'Poloshirt', 'gelb', 'XS'), ('Dana', 27, 'Hemd', 'blau', 'S')]
[('Ingo', 26, 'Poloshirt', 'gelb', 'S'), ('Dana', 27, 'Hemd', 'blau', 'XS')]
[('Ingo', 27, 'Hemd', 'blau', 'XS'), ('Dana', 26, 'Poloshirt', 'gelb', 'S')]
[('Ingo', 27, 'Hemd', 'blau', 'S'), ('Dana', 26, 'Poloshirt', 'gelb', 'XS')]
[('Ingo', 27, 'Hemd', 'gelb', 'XS'), ('Dana', 26, 'Poloshirt', 'blau', 'S')]
[('Ingo', 27, 'Hemd', 'gelb', 'S'), ('Dana', 26, 'Poloshirt', 'blau', 'XS')]
[('Ingo', 27, 'Poloshirt', 'blau', 'XS'), ('Dana', 26, 'Hemd', 'gelb', 'S')]
[('Ingo', 27, 'Poloshirt', 'blau', 'S'), ('Dana', 26, 'Hemd', 'gelb', 'XS')]
[('Ingo', 27, 'Poloshirt', 'gelb', 'XS'), ('Dana', 26, 'Hemd', 'blau', 'S')]
[('Ingo', 27, 'Poloshirt', 'gelb', 'S'), ('Dana', 26, 'Hemd', 'blau', 'XS')]
 类似资料:
  • 我的意思是,这不是要知道列表是否排序(布尔值),而是像“排序”的比率,像统计学中的相关系数。 例如, > 如果列表中的项目按升序排列,则其比率为1.0

  • 问题内容: 我的网页上有一个“瘦”列表:例如,一个包含100个项目的列表,每个项目的长度为一个单词。为了减少滚动,我想在页面的两列甚至四列中显示此列表。我该如何使用CSS? 我希望该解决方案具有灵活性,这样,如果列表增加到200个项目,则无需进行很多手动调整即可容纳新列表。 问题答案: ul { -moz-column-count: 4; -moz-column-gap: 20px; -webki

  • 问题内容: 如何在Python中生成一个列表的所有排列,独立于该列表中元素的类型? 例如: 问题答案: 从Python 2.6(如果你使用的是Python 3)开始,你可以使用标准库工具:itertools.permutations。 如果你出于某种原因使用旧版Python(),或者只是想知道它的工作原理,那么这是一种不错的方法,取自 http://code.activestate.com/rec

  • 问题内容: 假设我们有一个字母“ abcdefghiklimnop”。如何以有效的方式递归地生成排列在FIVE组中的此字母重复的排列? 我几天来一直在为此苦苦挣扎。任何反馈将有所帮助。 本质上,这与以下操作相同:生成给定字符串的所有排列 但是,我只希望整个字符串的长度为5。我还无法弄清楚这一点。 因此,对于“ abcdefghiklimnop”的所有长度为5的所有子串,请查找子串的排列。例如,如果

  • 问题内容: 我有看起来像这样的代码: 它返回一个长度为32的字符串,但我认为它不是有效的UUID。如果它是一个真正的UUID,为什么它是一个UUID,什么是代码,修改的值的目的和。 有没有更好的方法来生成UUID? 问题答案: 这些行将字节6和8的值限制在特定范围内。返回range内的随机字节,这些字节不是UUID的所有有效值。据我所知,这应该对片中的所有值进行。 如果您使用的是Linux,则可以

  • 问题内容: 我想一次从redis列表中弹出所有列表项。 我不想在列表为空时调用或方法,因为它似乎多次无效地将请求发送到。 我也知道我可以使用方法获得所有列表,但不能弹出项目。 你能建议我吗? 我只想和清单中的项目一个请求即可。 问题答案: 正如Itamar Haber所说,请使用lrange和del。在管道模式下,它将作为单个命令完成。