Python 优化选择-通过从行李列表中选择有限数量的行李来最大化设置

Python 优化选择-通过从行李列表中选择有限数量的行李来最大化设置,python,optimization,machine-learning,artificial-intelligence,set-cover,Python,Optimization,Machine Learning,Artificial Intelligence,Set Cover,我有一张行李单如果允许N个选择,我如何选择能最大化我的套餐的N个行李? e、 g 如果N=2,我想知道 choices[1, 2] 最大化我的集合 set = [B, A, E, Z, W] 我试图将其强制拟合为梯度下降格式,但我在创建成本函数时遇到了困难。这是正确/合理的方法吗 解决这个问题的最佳方法是什么? 备注: 假设选择列表足够大,无法计算所有可能的选择组合。 假设局部最优解是可接受的 缩小问题范围… 语言:Python 问题规模:约200万个选择;1-100袋大小 @sas

我有一张行李单
如果允许N个选择,我如何选择能最大化我的套餐的N个行李?
e、 g

如果N=2,我想知道

choices[1, 2]
最大化我的集合

set = [B, A, E, Z, W]

我试图将其强制拟合为梯度下降格式,但我在创建成本函数时遇到了困难。这是正确/合理的方法吗

解决这个问题的最佳方法是什么?


备注:
假设选择列表足够大,无法计算所有可能的选择组合。
假设局部最优解是可接受的



缩小问题范围…
语言:Python
问题规模:约200万个选择;1-100袋大小

@sascha-这套覆盖技巧非常有用

我走了一条写自己剧本的捷径,修改了其中一条:


印刷品。。。



我缺少的部分是。。。e、 g.如果我只能选择3,如何最大化集合覆盖率?

很容易实现混合整数规划方法(备选方案:sat解算器)。在这种情况下,也有很好的基于ADMM的启发式方法(如果非全局解决方案可行的话)。但在解决此问题之前,您应该提供有关问题大小、统计信息、编程语言限制、外部库限制等的更多信息。。。梯度下降感觉不自然,因为基于布尔/整数的简单公式不一定是可微的;这可能是个问题。你有没有看过类似的覆盖(或设置覆盖)问题?袋子里有多少独特的元素?aka有多少“唯一项”?很容易实现混合整数规划方法(备选方案:sat解算器)。在这种情况下,也有很好的基于ADMM的启发式方法(如果非全局解决方案可行的话)。但在解决此问题之前,您应该提供有关问题大小、统计信息、编程语言限制、外部库限制等的更多信息。。。梯度下降感觉不自然,因为基于布尔/整数的简单公式不一定是可微的;这可能是个问题。你有没有看过类似的覆盖(或设置覆盖)问题?袋子里有多少独特的元素?aka有多少“独特的项目”?
set = [B, A, E, Z, W]
from collections import defaultdict
import random
import string
random.seed(123)  # For reproducibility

size = 100
bag_size = 5
F = []
for i in range(size):
    bag = [string.ascii_uppercase[random.randint(0, 25)] for j in range(bag_size)]
    F.append(set(bag))

print('First 5 sets... of 100')
for item in F[0:5]:
    print(item)

set_freq = {}
for bag in F:
    for item in bag:
        set_freq[item] = set_freq.get(item, 0) + 1
print('Unique items:', len(set_freq))

f_copy = F.copy()  # Because F gets modified

# First prepare a list of all sets where each element appears
D = defaultdict(list)
for y,S in enumerate(F):
    for a in S:
        D[a].append(y)

L=defaultdict(set)        
# Now place sets into an array that tells us which sets have each size
for x,S in enumerate(F):
    L[len(S)].add(x)

E=[] # Keep track of selected sets
# Now loop over each set size
for sz in range(max(len(S) for S in F),0,-1):
    if sz in L:
        P = L[sz] # set of all sets with size = sz
        while len(P):
            x = P.pop()
            E.append(x)
            for a in F[x]:
                for y in D[a]:
                    if y!=x:
                        S2 = F[y]
                        L[len(S2)].remove(y)
                        S2.remove(a)
                        L[len(S2)].add(y)
print('Results...\n')
print('Indices:', E)
captured = {}
for index in E:
    for item in f_copy[index]:
        captured[item] = captured.get(item, 0) + 1
print('Unique items captured:', len(captured))
First 5 sets... of 100
{'B', 'Y', 'N', 'I', 'C'}
{'D', 'M', 'B', 'R', 'I'}
{'K', 'F', 'B', 'R'}
{'K', 'E', 'W', 'R'}
{'H', 'A', 'F', 'N', 'Y'}
Unique items: 26
Results...

Indices: [0, 10, 48, 32, 69, 7, 2, 5]
Unique items captured: 26