Вы можете использовать комбинации (из itertools) для создания подмножеств A и для каждого из них определить общие элементы B, найденные через L, которые вы можете индексировать как словарь. Это даст вам пары подмножеств с непустым продуктом. Используя функцию max (), вы можете найти пару с наибольшим продуктом.
from collections import defaultdict
from itertools import combinations
def findProdSets(A,B,L):
d = defaultdict(set)
for a,b in L: d[a].add(b)
for size in range(1,len(A)+1):
for subsetA in combinations(A,size):
subsetB = set.intersection(*(d[a] for a in subsetA))
if len(subsetB)>0:
yield subsetA,tuple(subsetB)
A = [1,2,3,4,5]
B = ["a","b","c","d","e","f"]
L = [(1,"a"),(1,"f"),(2,"d"),(3,"a"),(3,"f"),(4,"b"),(5,"f")]
subSetA,subSetB = max(findProdSets(A,B,L),key=lambda c:len(c[0])*len(c[1]))
print(subSetA,subSetB)
(1, 3) ('a', 'f')
Чтобы оптимизировать это, вы можете изменить функцию findProdSets так, чтобы она возвращала пару наборов с наибольшим товар. Это позволило бы ему выйти рано, начиная с самого большого размера и останавливаясь, тогда size x len(A)
меньше или равно наибольшему найденному продукту