Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 寻找可能的替代品清单_Algorithm_Search_Recursion_Tree - Fatal编程技术网

Algorithm 寻找可能的替代品清单

Algorithm 寻找可能的替代品清单,algorithm,search,recursion,tree,Algorithm,Search,Recursion,Tree,假设我们有一个二叉树,如下所示: 我正在寻找一种算法来找到A的所有等价性。我得到了一个数组,其中包含树中的元素。规则是,如果一个节点的所有子节点都存在于一个数组中,则相当于该节点存在于该数组中。 例如,如果我们在数组中有B和C,它相当于有一个A。所以在上面的数组中,F+G=C,C+B=A,所以[B,F,G]也相当于A。同样地[defg]也相当于A 我可以递归调用类似checkSubstitute(node)的东西: 这种逻辑有意义吗?另外,我如何使用上述算法存储所有等效数组 提前谢谢 您给出的方

假设我们有一个二叉树,如下所示:

我正在寻找一种算法来找到A的所有等价性。我得到了一个数组,其中包含树中的元素。规则是,如果一个节点的所有子节点都存在于一个数组中,则相当于该节点存在于该数组中。 例如,如果我们在数组中有B和C,它相当于有一个A。所以在上面的数组中,F+G=C,C+B=A,所以[B,F,G]也相当于A。同样地[defg]也相当于A

我可以递归调用类似checkSubstitute(node)的东西:

这种逻辑有意义吗?另外,我如何使用上述算法存储所有等效数组


提前谢谢

您给出的方法无法正常工作,因为您总是在for循环的第一次迭代中返回一个值。 假设您有一个数组[D]。然后checkSubstitute(B)返回True,而它应该返回False

与其使用for循环,只需对两个子项进行两次显式调用就更容易了。这假定每个节点都有零个子节点或两个子节点。如果一个节点可以有一个子节点,则需要进行一些额外的空检查

#returns true if Node n exists in NodeList seq, or if its equivalent exists in seq.
function exists(n, seq):
    if n in seq:
        return True
    if not n.hasChildren:
        return False
    return exists(n.leftChild, seq) and exists(n.rightChild, seq)
获得所有等价数组只需要一点组合运算

#gets all possible equivalents for the given node. This includes itself.
#An equivalent is a list of nodes, so this method returns a list of lists of nodes.
function getPossibleEquivalents(node):
    ret = new List()
    baseCase = new List()
    baseCase.append(node)
    ret.append(baseCase)
    if not node.hasChildren:
        return ret  
    for each leftEquivalent in getPossibleEquivalents(node.leftChild):
        for each rightEquivalent in getPossibleEquivalents(node.rightChild):
            ret.append(leftEquivalent + rightEquivalent)
    return ret
编辑: 通过为循环嵌套N,可以扩展具有0或N个子树的GetPossibleEquivalent:

for each child0Equivalent in getPossibleEquivalents(node.child[0]):
    for each child1Equivalent in getPossibleEquivalents(node.child[1]):
        for each child2Equivalent in getPossibleEquivalents(node.child[2]):
            for each child3Equivalent in getPossibleEquivalents(node.child[3]):
                for each child4Equivalent in getPossibleEquivalents(node.child[4]):
                    ret.append(child0Equivalent + child1Equivalent + child2Equivalent + child3Equivalent + child4Equivalent + child5Equivalent)
如果您想编写一个可以处理具有任意数量子级的树的函数,则需要对每个子级的每个可能等效项进行排序。有些语言已经为您实现了笛卡尔积。例如,在python中:

from itertools import product

def getPossibleEquivalents(node):
    ret = [node]
    if len(node.children) == 0: return ret
    for equivalentTuple in product(map(getPossibleEquivalents, node.children)):
        possibleEquivalent = reduce(lambda x,y: x+y, equivalentTuple)
        ret.append(possibleEquivalent)
    return ret

您给出的方法不能正常工作,因为您总是在for循环的第一次迭代期间返回一个值。 假设您有一个数组[D]。然后checkSubstitute(B)返回True,而它应该返回False

与其使用for循环,只需对两个子项进行两次显式调用就更容易了。这假定每个节点都有零个子节点或两个子节点。如果一个节点可以有一个子节点,则需要进行一些额外的空检查

#returns true if Node n exists in NodeList seq, or if its equivalent exists in seq.
function exists(n, seq):
    if n in seq:
        return True
    if not n.hasChildren:
        return False
    return exists(n.leftChild, seq) and exists(n.rightChild, seq)
获得所有等价数组只需要一点组合运算

#gets all possible equivalents for the given node. This includes itself.
#An equivalent is a list of nodes, so this method returns a list of lists of nodes.
function getPossibleEquivalents(node):
    ret = new List()
    baseCase = new List()
    baseCase.append(node)
    ret.append(baseCase)
    if not node.hasChildren:
        return ret  
    for each leftEquivalent in getPossibleEquivalents(node.leftChild):
        for each rightEquivalent in getPossibleEquivalents(node.rightChild):
            ret.append(leftEquivalent + rightEquivalent)
    return ret
编辑: 通过为循环嵌套N,可以扩展具有0或N个子树的GetPossibleEquivalent:

for each child0Equivalent in getPossibleEquivalents(node.child[0]):
    for each child1Equivalent in getPossibleEquivalents(node.child[1]):
        for each child2Equivalent in getPossibleEquivalents(node.child[2]):
            for each child3Equivalent in getPossibleEquivalents(node.child[3]):
                for each child4Equivalent in getPossibleEquivalents(node.child[4]):
                    ret.append(child0Equivalent + child1Equivalent + child2Equivalent + child3Equivalent + child4Equivalent + child5Equivalent)
如果您想编写一个可以处理具有任意数量子级的树的函数,则需要对每个子级的每个可能等效项进行排序。有些语言已经为您实现了笛卡尔积。例如,在python中:

from itertools import product

def getPossibleEquivalents(node):
    ret = [node]
    if len(node.children) == 0: return ret
    for equivalentTuple in product(map(getPossibleEquivalents, node.children)):
        possibleEquivalent = reduce(lambda x,y: x+y, equivalentTuple)
        ret.append(possibleEquivalent)
    return ret

这个逻辑可以很好地生成所有等价的表示,但需要一些重复,如果您愿意,可以检查并更正这些重复。(我将遵循一些python约定,在何处复制内容)

假设您需要[B,C]中所有可能的表示 对于此数组中的每个节点,可以将其替换为其子节点,也可以将其保持原样。递归的基本思想是:

find_equivalent(representation, node){
        // representation is a list which is a valid equivalent representation.
        child = list_of_children_of_node;
        Temp = representation[:]
        for each c in child: Temp.insert(child)


        find_equivalent(representation, next(node,representation))
        N = next(node,Temp)
        Temp.delete(node)
        Li.append(Temp)
        find_equivalent(Temp, N)
        // Here next function takes a list and a node and returns the next element from the list after node.

上面的Li是一个表示的全局数组,您需要为添加的每个表示调用find_equired函数。

此逻辑可以很好地生成所有等效表示,但需要一些重复,如果需要,您可以检查并更正。(我将遵循一些python约定,在何处复制内容)

假设您需要[B,C]中所有可能的表示 对于此数组中的每个节点,可以将其替换为其子节点,也可以将其保持原样。递归的基本思想是:

find_equivalent(representation, node){
        // representation is a list which is a valid equivalent representation.
        child = list_of_children_of_node;
        Temp = representation[:]
        for each c in child: Temp.insert(child)


        find_equivalent(representation, next(node,representation))
        N = next(node,Temp)
        Temp.delete(node)
        Li.append(Temp)
        find_equivalent(Temp, N)
        // Here next function takes a list and a node and returns the next element from the list after node.

上面的Li是表示的全局数组,您需要在添加表示时为每个表示调用函数find_equired。

关于查找所有等效数组的代码,如果我们现在扩展树,每个节点现在可以有多个子节点,该怎么办?简单但脆弱的答案是,对循环使用更多。更难但更可靠的答案是,用笛卡尔积替换那些for循环。嗨,凯文,非常感谢你的解释!不过,我不太理解最后一段代码,在递归中使用了“笛卡尔乘积”。它是如何工作的?还有什么方法可以用Java实现它吗?非常感谢。笛卡尔积可以被认为是在一行中模拟多个嵌套的
for
循环的一种方法。将其与倒数第二个代码段进行比较,您可以想象
equivalentTuple
等于
[child0Equivalent,child1Equivalent,…,child5Equivalent]
for
循环中的
reduce
方法是一种将这些子等价物组合成单个等价物的方法,然后我们可以将其附加到要返回的值集合中。至于在Java中实现笛卡尔积,在StackOverflow的其他部分已经讨论过,因此,我相信这是可能的:关于查找所有等效数组的代码,如果我们现在扩展树,并且每个节点现在可以有多个子节点,该怎么办?简单但脆弱的答案是,对循环使用更多。更难但更可靠的答案是,用笛卡尔积替换那些for循环。嗨,凯文,非常感谢你的解释!不过,我不太理解最后一段代码,在递归中使用了“笛卡尔乘积”。它是如何工作的?还有什么方法可以用Java实现它吗?非常感谢。笛卡尔积可以被认为是在一行中模拟多个嵌套的
for
循环的一种方法。将其与倒数第二个代码段进行比较,您可以想象
equivalentTuple
等于
[child0Equivalent,child1Equivalent,…,child5Equivalent]
for
循环中的
reduce
方法是一种将这些子等价物组合成单个等价物的方法,我们可以将这些子等价物附加到要返回的值集合中。至于在Java中实现笛卡尔积,在StackOverflow的其他地方已经讨论过,因此我确信这是可能的: