读了很长时间,第一次找不到我正在研究的东西的答案。在
我有一个93个字符串的列表,每个6个字符长。从这93个字符串中,我想确定一组20个字符串,它们都符合相对于集合中其他字符串的特定标准。同时itertools.组合会给我所有可能的组合,不是所有的条件都值得检查。在
例如,如果[list[0]、list[1]等失败,因为list[0]和list[1]不能在一起,那么其他18个字符串是什么都不重要,集合每次都会失败,这是浪费大量的检查。在
目前我有20个嵌套for循环,但似乎必须有一个更好/更快的方法来实现它
for n1 in bclist:
building = [n1]
n2bclist = [bc for bc in bclist if bc not in building]
for n2 in n2bclist: #this is the start of what gets repeated 19 times
building.append(n2)
if test_function(building): #does set fail? (counter intuitive, True when fail, False when pass)
building.remove(n2)
continue
n3bclist = [bc for bc in bclist if bc not in building]
#insert the additional 19 for loops, with n3 in n3, n4 in n4, etc
building.remove(n2)
在第20个for循环中有print语句,如果有一组20甚至存在,就会向我发出警报。for语句至少允许我在单次加法失败时提前跳过集合,但当较大的组合失败时没有内存:
例如,[list[0], list[1]]
失败,所以跳到通过的[list[0], [list[2]]
。下一个是[list[0], list[2], list[1]]
,它将失败,因为0和1再次在一起,所以它将移动到{
[list[0], list[3], list[2]]
[list[2], list[0], list[3]]
[list[2], list[3], list[0]]
[list[3], list[0], list[2]]
[list[3], list[2], list[0]]
所有这些组合的结果都将与之前的组合相同。基本上我交易的是itertools.组合测试我知道的所有集合的组合都失败了,因为早期的值失败了,for循环把值的顺序当作一个因素,而我不关心它们的顺序。这两种方法都大大增加了代码完成所需的时间。在
任何关于如何除掉魔鬼的想法都将不胜感激。在
您可以利用问题的两个方面:
test_function(L)
是True
,那么{test_function
也将是{您还可以通过处理索引0-92而不是
list[0]
-list[92]
-我们只关心test_function
列表的内容是什么。在下面的代码首先找到可行的对,然后是4对、8对和16对。最后,它会找到16和4的所有可行组合,从而得到20的列表。但是有超过10万套的8套,所以还是太慢了,我放弃了。也许你可以按照同样的思路做一些事情,但是用
itertools
来加速,但可能还不够。在我找到了一个更好的解决方案。首先,确定范围(0-92)内符合
^{pr2}$test_function
的所有值对,并保持这些对的顺序。假设第一对的第一个值必须是解的第一个值,最后一个对的第二个值必须是解的最后一个值(但是请检查。。。这个假设对test_function
成立吗?如果这不是一个安全的假设,那么您需要对start和finish的所有可能值重复find_paths
)。然后找到从第一个值到最后一个值的路径,它的长度为20个值,并且符合test_function
。在这将从
l
中选择基数n
的子集,这样test(subset) == False
。在它尽量避免不必要的工作。但是,鉴于有1e20方法可以从93个元素中选择20个元素,您可能需要重新考虑您的总体方法。在
使用当前方法,但也要跟踪索引,以便在内部循环中可以跳过已检查的元素:
相关问题 更多 >
编程相关推荐