您可以将每个排列映射到该排列所有重复项的规范代表,而不是比较所有排列对以检查其中是否存在重复项,并拒绝所有不规范的排列。
如果安排有长度米*n
,但你有N个
重复排列,其中米*n
相对较小,但N个
是巨大的,那么比较所有成对的排列将采取以下顺序牛*牛*米*牛
操作,而筛选出非规范安排只需要牛*米*牛
操作。
此外,由于表是循环的,您可以修复任意元素,并将其视为始终是第一个元素。这样,只需向置换生成算法传递一个元素,就可以立即避免生成大量重复项。
在这里,我生成所有座位更多交互工具.distinct_permutations,并过滤掉它们的旋转和反射的等价类中在字典上不是最小的座位。
定义最小值(seq):qes=序列[::-1]返回(范围(len(seq))中i的所有(seq<=qes[i:]+qes[:i])和所有(seq<=seq[i:]+seq[:i]表示范围内的i(len(seq)))从more_intertools导入distinct_permutations从字符串导入打印为字母def座位(n,m):“”“n组m人的所有可能座位,直至反射/旋转”“”池=“0”*(m-1)+字母[1:n]*mresult=(''.join(('0',*seating)),用于distinct_permutations(pool)中的座位)结果=[如果最小(座位),则结果中的座位数]返回结果l42=座位(4,2)打印(len(l42))# 171打印(l42)# ['00112233', '00112323', '00112332', '00113223', '00113232', '00113322', '00121233', '00121323', '00121332', '00122133', '00122313', '00122331', '00123123', '00123132', '00123213', '00123231', '00123312', '00123321', '00131223', '00131232', '00131322', '00132123', '00132132', '00132213', '00132231', '00132312', '00133122', '00133212', '00211233', '00211323', '00211332', '00212133', '00212313', '00213123', '00213132', '00213213', '00213312', '00221133', '00221313', '00223113', '00231123', '00231132', '00231213', '00232113', '00311223', '00312123', '00312213', '00321123', '01012233', '01012323', '01012332', '01013223', '01013232', '01013322', '01021233', '01021323', '01021332', '01022133', '01022313', '01023123', '01023132', '01023213', '01031223', '01032123', '01102233', '01102323', '01102332', '01103223', '01120233', '01120323', '01120332', '01122033', '01122303', '01123023', '01123032', '01123203', '01123302', '01130223', '01130232', '01130322', '01132023', '01132032', '01132203', '01132302', '01133022', '01133202', '01201233', '01201323', '01201332', '01202133', '01202313', '01202331', '01203123', '01203132', '01203213', '01203231', '01203312', '01203321', '01210233', '01210323', '01212033', '01212303', '01213023', '01213032', '01213203', '01213302', '01220133', '01220313', '01220331', '01221033', '01221303', '01223013', '01223031', '01223103', '01230123', '01230132', '01230213', '01230231', '01230312', '01230321', '01231023', '01231032', '01231203', '01231302', '01232013', '01232031', '01232103', '01233102', '01301322', '01302123', '01302132', '01302213', '01302231', '01302312', '01303122', '01303212', '01310223', '01310232', '01312023', '01312032', '01312203', '01312302', '01313022', '01313202', '01320132', '01320213', '01320231', '01320312', '01321203', '01321302', '01323102', '01330212', '01331022', '01331202', '02021133', '02021313', '02023113', '02031123', '02031213', '02112033', '02112303', '02113023', '02113032', '02113203', '02120313', '02121303', '02130213', '02130312', '02131203', '02203113', '02211303']l43=座位(4,3)打印(len(l43))# 15402打印(l43)# ['000111222333', '000111223233', '000111223323', '000111223332', '000111232233', '000111232323', '000111232332', '000111233223', '000111233232', '000111233322', ..., '022121130303', '022203031113', '022211130303']
为了记录在案,差异替代('00111222333')
生成92400个排列,其中我们保留15402个。