生成Python中不包括循环旋转的所有排列

时间:2014-03-05 00:33:10

标签: python-3.x

我需要为货币套利创建一个(实践)程序,在一系列汇率下检测有利可图的“回路”。因此,USD-> JPY,JPY-> USD,USD-> EUR可能会有不同的值,依此类推。然而,为了检测盈利能力,我首先需要列举所有可能的循环 - USD-> JPY-> EUR-> USD是一个例子,但是USD-> EUR-> JPY-> USD是使用相同货币的一个明显例子,因为它可能达到不同的汇率。

如果我忽略循环的最后一部分,它始终与原点相同,那么似乎每种货币在“最佳”循环中最多只能存在一次,就好像存在一种货币一样不止一次它实际上是两个不同的循环(其中至少有一个仍然有利可图)。

同样,我可以忽略只是已经测试过的循环的翻译的循环:USD-> JPY-> ASD与JPY-> ASD-> USD相同。

所以,鉴于像 [USD,JPY,EUR,ASD] 这样的输入,我需要一些可以返回的内容:

(USD,JPY,EUR,ASD)
(USD,JPY,ASD,EUR)
(USD,EUR,ASD,JPY)
(USD,EUR,JPY,ASD)
(USD,ASD,EUR,JPY)
(USD,ASD,JPY,EUR)

1 个答案:

答案 0 :(得分:0)

此解决方案使用Python 3.3中引入的语法yield。就像内置的itertools.permutations()一样,这个:

  • 是一个发电机,不需要存储任何东西
  • 如果传递长度为0
  • ,将产生一个空元组
  • 假设置换对象中的每个项目本身都是唯一的

from itertools import permutations
def unique_cyclic_permutations(thing, length):
    if length == 0:
        yield (); return
    for x in permutations(thing[1:], length - 1):
        yield (thing[0],) + x
    if length < len(thing):
        yield from unique_cyclic_permutations(thing[1:], length)

算法的工作原理是选择一个支点,在开头修复它,然后置换其余的对象。在非全长排列的情况下,还将存在一些根本不包括枢轴对象的排列。在这种情况下,生成器递归调用自身,同时排除原始数据透视。