【发布时间】:2018-06-16 10:45:28
【问题描述】:
我正在尝试开发一种方法来查找以下列表中特定序列的有序等级。
a = list(sorted(itertools.combinations(range(0,5),3)))
b = list(sorted(itertools.permutations(range(0,5),3)))
a 表示combinatorial number system 的元素列表,因此排名公式非常简单。
我需要的是 2 个函数 magic_rank_1 和 magic_rank_2,它们具有以下定义
def magic_rank_1(perm_item,permutation_list_object):
## permutation_list_object is actually b
return list_object.index(perm_item)
def magic_rank_2(perm_item,permutation_list_object,combination_list_object):
## permutation_list_object is actually b and combination_list_object is actually a
return combination_list_object.index(tuple(sorted(perm_item)))
所以基本上magic_rank_2((0,1,2),b,a) = magic_rank_2((2,0,1),b,a)
听起来很简单……但我有一些限制。
- 我无法使用 indexof 函数,因为我无法为每个项目搜索 >100000000 个项目
- 我需要 magic_rank_1 和 magic_rank_2 是纯数学的,而不使用任何排序函数或比较函数或搜索函数。我将拥有的所有信息是需要识别其等级的元组和我的字母表的最后一个字母(在本例中为 5)
- 当 k = len(a) 时,magic rank 2 不必是 0 到 k-1 之间的数字,只要它是 0 到 2 之间的唯一数字即可^(ceiling((max_alphabet/2)+1))
我知道magic_rank_1 可以通过类似于this 的东西来计算,但有区别,输入字母表的每个字母都被使用,在我的情况下它是一个子集
最后是的,这应该是散列函数的替代品,目前正在使用散列函数,但我没有利用 magic_rank_2((0,1,2),b,a) = magic_rank_2((2,0,1),b,a) 的事实。如果可以的话,它将显着减少我的存储空间需求,因为我的序列长度实际上是 5 ,所以如果我可以计算一个 magic_rank_2 的方法,我会将我的存储需求减少到当前需求的 1%
更新 - 对于magic_rank_2,元组的元素之间应该没有比较操作,即没有排序、最小值、最大值等
这只会使算法的效率低于常规散列
【问题讨论】:
-
indexof函数最好在散列中实现,就像你说的那样,如果你能负担得起预先存储和索引列表以提高性能。否则,由于itertools.combinations和itertools.permutations都是生成器,这意味着每次调用它们时都必须花时间迭代整个列表,而且速度很慢。您在 magic_rank_2 中的输入只需排序一次。如果需要多次调用magic_rank_2,可以将循环包裹在Cython函数中。 -
至于数学(?)方法,可以看
itertools的源码,了解生成器迭代中元素的预期顺序。然后您可以尝试根据预期顺序计算 perm_item 的确切索引。我不会那样做,因为没有人知道这是否不是一个 NP 难题并且需要博士学位。论文。 -
我不会称其为 NP 难题,最终的实现是针对 c 的,无论如何我使用排序树进行排序(即 log(n))但因为我的话是 7-10数字 longs 这意味着用于排序的 13-22 比较操作被证明是一个瓶颈,我还需要利用受控冲突,因为 rank(x,y,z) = rank(y,z,x)
-
@Mai 1)Python 用于概念验证和原型设计,因此 python 中的有效算法适用于 C 2) 我没有说树排序我说排序树有很大的不同 3)我在这里要求一种更有效的做事方式。与其为你的答案拼命投票,不如不回答如果你忍不住希望没有下次
-
很抱歉我不能。祝你好运。
标签: python permutation lexicographic