簡體   English   中英

有沒有辦法生成項目列表的所有唯一排列

[英]is there a way to generate all unique permutations of a list of items

我有一個包含五個屬性的列表,每個屬性有五個不同的值。 我想生成它們的笛卡爾積,並過濾所有獨特的排列。

一些背景:

我需要它們作為我的輸入值來解決邏輯謎題。 我在哪里檢查規則以找到正確的解決方案。

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 (superset)
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)]]

也許你可以出於好奇,告訴我,這些概念的具體數學名稱是什么,我需要哪些?


謎題:

五個朋友(Dana,Ingo,Jessica,Sören,Valerie)在購物中心的收銀台排隊等候。 他們都是不同年齡(26,27,30,33歲,35歲),並希望自己購買不同的上衣(襯衫,Pol衫,套衫,運動衫,T恤) 頂部有不同的顏色(藍色,黃色,綠色,紅色,黑色)和尺寸(XS,S,M,L,XL)

規則:

  1. 頂級'Dana'想買的是'XL'。 在她后面(但不是直接在后面)是一個有“黑色”頂部的人。
  2. '傑西卡'直接在一個想要購買'Poloshirt'的人面前等待。
  3. 排隊的第二個人想購買一個“黃色”頂部。
  4. 'T恤'不是'紅色'。
  5. 'Sören'想買一件'運動衫'。 直接在他面前等待的人比他身后的人年長。
  6. 'Ingo'需要頂級'L'。
  7. 排隊的最后一個人是30歲。
  8. 最年長的人將購買最小尺寸的頂部。
  9. 直接在'Valerie'后面等待的人想買一個比'S'大的'紅色'頂部。
  10. 最年輕的人想買一個“黃色”上衣。
  11. 傑西卡打算買一件“襯衫”。
  12. 排隊等候的第三個人想購買一個大小為'M'的頂級人物。
  13. 'Poloshirt'是'紅色'或'黃色'或'綠色'。

這樣做,但需要很長時間。 我縮小了列表大小,因為您要求的選項有24,883,200,000個排列:

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')]

對於你所擁有的邏輯謎題類型,使用排列的方法存在一個基本問題。 問題甚至不是因為有太多的解決方案不太可能在合理的時間內完成。 問題是你沒有自動檢查規則來解決問題:除非你有一個方法來驗證它們,否則你面前的所有可能性都是毫無意義的。

為了解決這些問題,我創建了一個名為Puzzle Solvers的項目:

這是一個小項目,目前包含一個感興趣的類: puzzle_solvers.elimination.Solver 此類實現了解決問題中提出的消除過程類型問題所需的大多數操作。 所有的邏輯都記錄在案 ,並且教程是你確切的問題的演練。 我將在這里解釋基礎知識,這樣你就可以理解我的所作所為,並且可能會改進它。

第1步是識別隊列中的位置是一個屬性,就像年齡,名稱等一樣。這意味着訂單不再相關。

第2步是認識到這是偽裝的圖形問題。 您有30個節點:五個人中每個人的所有可能屬性(其中六個)。 圖表幾乎完成。 只缺少給定類型屬性之間的邊緣,因此從375開始,而不是完整的435邊緣。

最終目標是在圖中的五個連通組件中的每個屬性類之間具有一條邊。 因此,最終邊緣數為5 * 15 = 75。

那么如何去除邊緣? 像“'T恤'不是'紅''這樣的簡單規則非常簡單:只需刪除那條邊。 像“隊列中的最后一個人已經30歲了”這樣的規則。 也很簡單,在邊緣去除方面更有利可圖。 去除年齡不是30和位置5之間的所有邊緣,以及不是5和30歲的位置之間的所有邊緣。我添加了幾個半烘焙的實用程序包裝來檢查大於和小於條件和刪除代表不可能組合的邊緣。

解算器最重要的方面是這樣一個事實,即每當一個邊被移除時,它就會完全貫徹該操作的所有邏輯含義。 想象一下,你有''Poloshirt'是'紅色'或'黃色'或'綠色'“並且你已經達到了謎題中的一個點,這三種顏色中沒有一個與30歲相關聯。這意味着無論誰是穿着poloshirt不能30歲。 事實上,'Poloshirt'不能有任何邊緣與這三種顏色不共享的端點。 如果您遞歸地執行這些推斷,您將獲得完整的解決方案。

對於我的包裹的無恥銷售,我感到很遺憾,但在理由上,我寫的只是為了回答這個問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM