【发布时间】:2023-02-04 09:10:40
【问题描述】:
我曾经遇到过 python 的问题,我必须检查集合中的至少一个项目是否与集合列表中的所有单个集合相交。
所以例如我有三个集合:
A = [
{"a", "b", "c"},
{"c", "d", "e"},
{"a", "l", "k"}
]
和一个独特的字符集合 U:
U = {"a", "b", "c", "d", "e", "l", "k"}
我现在想找到 U 的最短组合,其中至少一个字符出现在 A 的所有集合中。
例如组合 ["a", "c"] 将是一个解决方案。 ["a", "d"], ["a", "e"] 也可以,我想把它们都找出来,以便以后找到一个最佳的(每个字符都有一些特征)。
我在 python 中写这个的方式如下:
for i in range(1,5):
combs = itertools.combinations(U, i)
for c in combs:
if all(set(c) & l for l in A):
# -> solution found
因为它可能有一个很大的 A 和 U 列表,可能的组合数量可能会变成天文数字,所以我尝试用 Rust 实现它,但是我的 Rust 实现与 Python 一样“慢”。
// the input is a bit weird, but this step doesnt take much time i times
let A: Vec<HashSet<String>> = A.into_iter().map(|x| HashSet::from_iter(x)).collect();
let mut possible = vec![];
for n_combs in 1..=4 {
for i in U.iter().combinations(n_combs) {
let outp = A.iter().fold(0, |acc, x| {
for j in i.iter() {
if x.contains(*j) {
return acc + 1;
}
}
acc
});
if outp == A.len() {
//solution
}
}
我将这两个示例都运行到迭代部分并且速度相同。所以问题是我如何检查交叉点。 感谢您对改进这一点的任何帮助,谢谢
【问题讨论】:
-
对于 Rust 实现,您在编译时是否使用了
--release标志? -
是的,我使用了 --release .. 没有它必须比 python 版本慢
-
我认为组合的使用会在这里扼杀它,但我需要更多地考虑如何摆脱搜索所有这些序列
-
即使组合不是正确的方法,我仍然很好奇与 Rust 相比,Python 的检查速度如此之快。我认为我所做的远非最佳
-
我怀疑您通过进行一组额外的迭代大大增加了时间复杂度,但我的生锈并不好