Python 选择适当的算法来创建和计算元素共享对的置换

Python 选择适当的算法来创建和计算元素共享对的置换,python,algorithm,time-complexity,permutation,graph-algorithm,Python,Algorithm,Time Complexity,Permutation,Graph Algorithm,我感兴趣的是,执行以下任务时,哪种算法的时间复杂度最低: 给定元组列表,例如[(a,B),(B,C),(C,D),(de),(a,D),(E,a),(a,C)], 查找诸如[A、B、C、D、E、A]或[A、D、C、B、A]等序列,这些序列以相同的字母开头和结尾,并且通过连接共享元组中至少一个元素的对而形成。注:(A,B)被认为与(B,A)相同,就像(A,C)与(C,A)相同,因此它可以用于创建两对(C,B,A,C)或(A,B,C,A) 重要的约束条件是对长度进行限制。例如,确保序列的总长度不超过

我感兴趣的是,执行以下任务时,哪种算法的时间复杂度最低:

给定元组列表,例如[(a,B),(B,C),(C,D),(de),(a,D),(E,a),(a,C)], 查找诸如[A、B、C、D、E、A]或[A、D、C、B、A]等序列,这些序列以相同的字母开头和结尾,并且通过连接共享元组中至少一个元素的对而形成。注:(A,B)被认为与(B,A)相同,就像(A,C)与(C,A)相同,因此它可以用于创建两对(C,B,A,C)或(A,B,C,A

重要的约束条件是对长度进行限制。例如,确保序列的总长度不超过7个元素

我试图通过将树一次扩展一个元素来解决这个问题,直到达到最大长度7,但是我很好奇是否有更好的方法来解决这个问题。非常感谢您,期待听到您的好主意

时间复杂性 用于解决此问题的任何算法的(最坏情况)时间复杂度的下界为O(n),其中n是图的边数(即元组):

  • 如果需要查找从A到A的所有循环,则不能排除查找某条边,因为它可能是此类循环的一部分
  • 如果您需要查找从A到A的任何循环,您可能会遇到这样的情况,即只有一个这样的循环,在最坏的情况下,您可能会发现您访问的最后一条边就是结束该循环的边
所以在任何一种情况下,你都需要至少看一次每一条边

算法 本质上有两种策略:广度优先或深度优先搜索。两者的时间复杂度都是O(n)

您似乎尝试过的算法是广度优先搜索。当您需要找到最短的周期时,它是更好的选择,因为这样您可以在找到周期(a-to-a)后立即退出算法

深度优先搜索也是一个可行的选择,当然是在循环长度有限制的情况下。在这种情况下,空间复杂度为O(m),其中m是循环的最大长度。根据图(其大小、平均分支因子)的不同,这可能比广度优先搜索所需的O(n)空间便宜得多

此外,广度优先搜索需要不断切换状态,而递归和回溯期间发生的转换(深度优先搜索的特征)通常更容易处理

准备工作 无论使用哪种策略,请确保首先为图形创建有效的数据结构


由成对数组组成的简单数据结构(如您的问题所示)不够好。为了获得最佳的时间复杂度,您需要构建一个邻接列表(或类似的东西),这样您就可以在恒定的时间内找到节点的邻居(通过一个元组可以到达)。

那么当您有(a,B)时,(a,B,a)是一个解决方案吗?或者一个元组只能使用一次有限制吗?非常感谢你,Trincot!在这种情况下,你有什么建议?假设(A,B)的成本为0.8,(B,C)的成本为0.6,(B,D)的成本为0.7,(C,A)和(D,A)的成本相等。我们的目标是找到最低成本,即0.8+0.6+等成本<0.8+0.7+等成本。这里重要的是,我们并没有停止寻找“A到A”,而是在序列的“最大长度”上,比如6。在所有长度为6的序列中,我们需要找到成本最低的序列。非常感谢。通常用于此类场景。在这种情况下,当路径长度大于6时,您不会扩展路径,并且在查找长度较短的目标节点时,您也不会停止。但是,当您找到长度为6的路径时,您将确保以最小的成本获得该路径。另见。