我有一些要合并的等于项。 我尝试用一个例子更好地解释:
我有一些人,每个人都有一个ID。 情况就是这样的5个人的名单
['A','A','B','B','C']
我需要将每个人都放在一个房间里。每个具有相同代码的人都必须位于同一房间。 例如,房间数是3:第一个房间有2个桌子,第二个房间有3个桌子,最后一个又有2个桌子。
所以最终我希望看到这样的组合列表:
[['A','A'],['B','B',None],['C',None]]
[['A','A'],['C',None,None],['B','B']]
[['A','A'],['B','B','C'],[None,None]]
[['B','B'],['A','A',None],['C',None]]
[['B','B'],['C',None,None],['A','A']]
[['B','B'],['A','A','C'],[None,None]]
[['C',None],['A','A',None],['B','B']]
[['C',None],['B','B',None],['A','A']]
“无”表示空桌子。
我不希望有最终的解决方案,我希望能对遵循的逻辑过程有所帮助,因为我对此感到非常疯狂。
非常感谢您。
答案 0 :(得分:0)
peoples = ['A','A','B','B','C', "None", "None"]
import itertools
for x in itertools.permutations(peoples):
rooma = x[:2]
if rooma[0] == rooma[1] or "None" in rooma[:2]:
roomb = x[2:5]
if len(roomb) != len(set(roomb)):
roomc = x[5:]
if roomc[0] == roomc[1] or "None" in roomc[:2]:
print([rooma,roomb,roomc])
如果有的话,这可以使您获得95%
答案 1 :(得分:0)
我创建了一个示例来解决您的问题:
import itertools
combs = ['AA','BB','C','X', 'X'] # i grouped AA becouse they are grouped and "X" = None
mylist = sorted(list(itertools.permutations(combs))) #create all possible permutations
#split the groups
tuppleSet = set()
for line in mylist:
t = ()
for string in line:
string.split("\\")
t = t + tuple(string)
tuppleSet.add(t)
newlist = sorted(tuppleSet)
for line in newlist:
if line[0] == "C" or line[0] == "X" and line[1] == "A" or line[1] == "B": #restricton with table size
continue
elif line[6] == "X" or line[6] == "C" and line[4] == "A" or line[4] == "B": #restricton with table size
continue
print(line)
Output:
('A', 'A', 'B', 'B', 'X', 'X', 'C')
('A', 'A', 'C', 'X', 'X', 'B', 'B')
('A', 'A', 'X', 'C', 'X', 'B', 'B')
('A', 'A', 'X', 'X', 'C', 'B', 'B')
('X', 'C', 'A', 'A', 'X', 'B', 'B')
('X', 'C', 'B', 'B', 'X', 'A', 'A')
('X', 'C', 'X', 'A', 'A', 'B', 'B')
('X', 'X', 'A', 'A', 'C', 'B', 'B')
('X', 'X', 'B', 'B', 'C', 'A', 'A')
('X', 'X', 'C', 'A', 'A', 'B', 'B')
我强烈建议更深入地研究Itertools,因为我不太深...
答案 2 :(得分:0)
from itertools import combinations,permutations,repeat,groupby,zip_longest
Peop = [["A001_B","A001_B"],["A004_A","A004_A"],["A003_A","A003_A","A003_A","A003_A","A003_A","A003_A"],["A002_A","A002_A","A002_A","A002_A"],["A001_C","A001_C"],["A001_A","A001_A","A001_A"],["A002_B","A002_B"]];
RPla = [4,10,2,4,8]
Comb = []
for r in RPla:
out,out1,l1,s1 = [],[],[],[]
for s in Peop:
l = len(s)
if l > r:
continue
elif l == r:
out.append(s)
else:
s1.append(s) # ======== new purged Peop
l1.append(l) # ======== len same people Peop
indL,tempC,diff = [],[],[]
for z in range(2,len(l1)-1):
for k,y in zip(combinations(range(len(l1)),z),combinations(l1,z)):
indL.append(k)
tempC.append(y)
if sum(y) > r:
continue # <<<<<==== WILL DO SOMETHING ======================
elif sum(y) == r:
tempL1 = []
for h in k:
tempL1.append(s1[h])
tempL1 = [item for sublist in tempL1 for item in sublist] #flatten
out.append(tempL1)
else:
diff = r - sum(y)
tempL1 = []
for h in k:
tempL1.append(s1[h])
tempL1 = [item for sublist in tempL1 for item in sublist] #flatten
tempL1.extend(repeat("Empty Desk",diff))
out.append(tempL1)
s1.append(repeat("Empty Desk",r))
tempL2 = [list(row) for row in zip_longest(*s1, fillvalue='Empty Desk')]
tempL3 = [list(row) for row in zip_longest(*tempL2, fillvalue='')]
#tempL3 = tempL3[:len(s1)-1]
out.extend(tempL3)
Comb.append(out)
print(Comb)
我想向您展示我的正在进行的工作(上面)。
这样,对于每个房间,我都会找到所有可能的优化组合。问题在于,现在我必须不重复地组合房间之间的组合。 我没有找到办法,所以我也想改变主意。
与上一个示例相比,您可以看到人们可以改变,而且房间位置也可以。
这是使用Python 3的测试,尽管我使用的是Python 2
谢谢!
答案 3 :(得分:0)
这是基于Fabian方法的更快解决方案:
import itertools, sys
# combs = ['AA','BB','C','X', 'X'] # i grouped AA becouse they are grouped and "X" = None
# rooms = [2, 3, 2]
combs = ['AA', 'BBB', 'C', 'X', 'X', 'X', 'X']
rooms = [2, 3, 2, 3]
mylist = sorted(list(itertools.permutations(combs))) #create all possible permutations
unique_assignments = []
# test if two assignemtns are equivalent
def equivalent_assignments(assignment1, assignment2):
for i in range(0, len(assignment1)):
if tuple(assignment1[i]) not in itertools.permutations(assignment2[i]):
return False
return True
# for every permutation
for line in mylist:
fits = True
rooms_ind = 0
comb_ind = 0
room = rooms[rooms_ind]
comb = line[comb_ind]
room_assignments = []
room_assignment = []
# see if this permutation will fit
while True:
if room < len(comb):
break
elif room == len(comb):
comb_ind += 1
rooms_ind += 1
room_assignment.append(comb)
room_assignments.append(room_assignment)
room_assignment = []
try:
room = rooms[rooms_ind]
comb = line[comb_ind]
except:
break
else: # room > len(comb)
room_assignment.append(comb)
room -= len(comb)
comb_ind += 1
try:
comb = line[comb_ind]
except:
break
# if we have leftover people, they don't fit
if comb_ind < len(line) - 1:
fits = False
# check for same assignments
if fits:
same_assignments = [x for x in unique_assignments if equivalent_assignments(x, room_assignments)]
if len(same_assignments) == 0:
unique_assignments.append(room_assignments)
# print results
for line in unique_assignments:
print line
输出:
[['AA'], ['BBB'], ['C', 'X'], ['X', 'X', 'X']]
[['AA'], ['BBB'], ['X', 'X'], ['C', 'X', 'X']]
[['AA'], ['C', 'X', 'X'], ['X', 'X'], ['BBB']]
[['AA'], ['X', 'X', 'X'], ['C', 'X'], ['BBB']]
[['C', 'X'], ['AA', 'X'], ['X', 'X'], ['BBB']]
[['C', 'X'], ['BBB'], ['AA'], ['X', 'X', 'X']]
[['C', 'X'], ['BBB'], ['X', 'X'], ['AA', 'X']]
[['C', 'X'], ['X', 'X', 'X'], ['AA'], ['BBB']]
[['X', 'X'], ['AA', 'C'], ['X', 'X'], ['BBB']]
[['X', 'X'], ['AA', 'X'], ['C', 'X'], ['BBB']]
[['X', 'X'], ['BBB'], ['AA'], ['C', 'X', 'X']]
[['X', 'X'], ['BBB'], ['C', 'X'], ['AA', 'X']]
[['X', 'X'], ['BBB'], ['X', 'X'], ['AA', 'C']]
[['X', 'X'], ['C', 'X', 'X'], ['AA'], ['BBB']]
我以前效率低得多的解决方案:
import itertools, sys
people = ['A', 'A', 'B', 'B', 'C']
rooms = [2, 3, 2]
# people = ['A', 'A', 'B', 'B', 'B', 'C']
# rooms = [2, 3, 2, 3]
# people = ['A', 'A', 'B', 'B', 'C', 'C', 'C', 'C', 'C'] # takes absurdly long
# rooms = [2, 3, 2, 5]
total_room_space = sum(rooms)
print("total_room_space: " + str(total_room_space))
people_padded = people
for i in range(0, (total_room_space - len(people))):
people_padded.append('None')
print('people_padded: ' + str(people_padded))
unique_assignments = []
for perm in itertools.permutations(people_padded):
perm_index = 0
room_assignments = []
for room_size in rooms:
room_assignment = []
for i in range(0, room_size):
room_assignment.append(perm[perm_index])
perm_index += 1
room_assignments.append(tuple(room_assignment))
skipflag = False
# check for multiple rooms
for room_assignment in room_assignments:
rest = [x for x in room_assignments if x is not room_assignment]
for room_asgn in rest:
for code in room_assignment:
if code != 'None':
if code in room_asgn:
skipflag = True
# skip if needed
if skipflag:
continue
if room_assignments not in unique_assignments:
unique_assignments.append(room_assignments)
# return true if two room assignments are the same
def same_assignment(assignment1, assignment2):
for i in range(0, len(assignment1)):
if assignment1[i] not in itertools.permutations(assignment2[i]):
return False
return True
# clean up same combinations in unique_assignments
indeces = range(0, len(unique_assignments))
delete_indeces = []
while indeces:
curr_index = indeces.pop(0)
equivalent_assignments = [x for x in indeces if same_assignment(unique_assignments[x], unique_assignments[curr_index])]
for ind in equivalent_assignments:
delete_indeces.append(ind)
indeces = [x for x in indeces if x not in equivalent_assignments]
for index in reversed(sorted(delete_indeces)):
del unique_assignments[index]
# print results
print("\n\nResults:")
for assignment in unique_assignments:
print assignment