Вы можете использовать рекурсивный генератор вместе с functools.lru_cache
, чтобы вычислить минимальное количество магазинов, необходимое для покупки определенного набора предметов:
from functools import lru_cache
@lru_cache()
def find_best_path(need: frozenset):
return min(visit_shops(need), key=len)
def visit_shops(need):
for k, items in shops.items():
buy = items & need
if buy == need:
yield (k,) # there's a single best option: just visit that shop
break
elif buy:
yield (k,) + find_best_path(need - buy)
Тестирование на вашем пример:
shops = {
'A': {2, 3},
'B': {1, 2},
'C': {4},
}
need = frozenset({1, 4})
print(find_best_path(need)) # ('B', 'C')
Тестирование на другом примере с несколькими параметрами:
shops = {
'A': {1, 2, 3},
'B': {4},
'C': {5},
'D': {1, 3, 5},
'E': {2, 4},
}
need = frozenset({1, 2, 3, 4, 5})
print(find_best_path(need)) # ('D', 'E')