Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.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_Optimization - Fatal编程技术网

Algorithm 在尽可能少的步骤中找到运动目标的算法

Algorithm 在尽可能少的步骤中找到运动目标的算法,algorithm,search,optimization,Algorithm,Search,Optimization,我正试图解决以下问题: 一排有6个杯子(比如编号1到6)。其中一个杯子下面有一个球(我不知道是哪一个)。我可以举起一个杯子,看看球是否在那里。如果是,我赢了。如果不是,球将从其当前位置移动到一个杯上,直接向左或向右移动(因此从杯4移动到杯3或杯5。从杯6移动到杯5)。球必须移动,不能停留在原地 问题是:如果你使用最佳策略,经过多少次“杯托”后,你会知道球的位置 目前,我已经想出了一个策略,最坏的情况是6部电梯。请注意,不需要进行最后的举重,“证明”球的位置。我的问题是:是否有一种算法具有更好的“

我正试图解决以下问题:

一排有6个杯子(比如编号1到6)。其中一个杯子下面有一个球(我不知道是哪一个)。我可以举起一个杯子,看看球是否在那里。如果是,我赢了。如果不是,球将从其当前位置移动到一个杯上,直接向左或向右移动(因此从杯4移动到杯3或杯5。从杯6移动到杯5)。球必须移动,不能停留在原地

问题是:如果你使用最佳策略,经过多少次“杯托”后,你会知道球的位置

目前,我已经想出了一个策略,最坏的情况是6部电梯。请注意,不需要进行最后的举重,“证明”球的位置。我的问题是:是否有一种算法具有更好的“最坏情况”?如果不是,我如何证明这是最好的算法

我目前的战略。我们假设球在一开始是在一个均匀的杯子下(2,4或6)。我的最坏情况的一步一步如下

提起1:提起2号杯子。球不在那里。根据我们的假设,球将移动到一个奇数杯,但它不可能移动到第1杯(因为它必须起源于第2杯,但它不在那里)

提起2:提起3号杯子。球不在那里。我不可能在1岁以下(见上图),也不可能在3岁以下,假设是在一个奇怪的杯子下。这意味着它现在位于杯5下,因此必须移动到杯4或杯6

举起3号:举起4号杯子,球不在那里。这意味着它必须移动到第6个杯子,所以下一步它必须移动到第5个杯子

举起4:举起5号杯子,球不在那里。这是唯一剩下的可能性,所以我们错误地猜测它是在一个均匀的杯子下开始的。因此,它现在处于某个偶数杯之下,下一步将移动到一个奇数杯。我们现在的工作流程是相同的,但情况正好相反

提起5号杯子:再次提起5号杯子。球不在那里。根据新的假设,球现在将移动到第2或第4杯(同样,它不能移动到第6杯,因为它不在5杯以下)


提起6号杯子:提起4号杯子。它不在那里,所以它必须在2号杯子下面(它在一个均匀的杯子下面,而不是在6号或4号杯子下面)。因此,我们知道杯子在哪里(即使我们没有执行第2号杯子的最终提升)。

您的算法有缺陷。如果球在奇数位置开始,经过偶数次移动后,它将在奇数位置结束。您的算法假设它在六次移动后处于平衡位置。那是行不通的。此外,你的举重顺序并不能确定球在哪里

例如,假设球从杯1下开始。按照您的电梯顺序,以下是可能的

  • 提起杯2。球移到第二杯
  • 提起杯3。球移动到杯1
  • 提起杯4。球移到第二杯
  • 提起杯5。球移动到杯1
  • 提起杯5(再次)。球移到第二杯
  • 提起杯4。球移动到杯1
  • 步骤6后,球可以从杯2移动到杯1或杯3。所以你不知道它在哪里。

    我认为它接近你提出的问题。但是,它包含5个盒子,而不是6个。无论如何,你仍然可以检查他们提出的解决方案,并将他们的策略与你的策略进行比较


    希望有帮助。

    如果你想用一个程序解决这个问题,请构造一个图,其中顶点是球可能所在的位置集,边是杯托,结果不会露出球。然后,一个解决方案是从您想要的任何起始状态到具有2个可能的杯托的任何状态的最短路径。(在a结束的终止条件有点混乱,因为规则允许它在球移动之前“知道”球在哪里)

    这段代码相当粗糙,但使用DFS来查找最短路径,然后漂亮地打印解决方案。它证实了在最坏的情况下,需要6次提杯才能找到球,事实上,找到的解决方案与你所做的完全相同

    输出为:

    $ python cups.py
    the ball can be under cups: 1,2,3,4,5,6
    lift cup 2
    the ball can be under cups: 2,3,4,5,6
    lift cup 3
    the ball can be under cups: 1,3,4,5,6
    lift cup 4
    the ball can be under cups: 2,4,5,6
    lift cup 5
    the ball can be under cups: 1,3,5
    lift cup 5
    the ball can be under cups: 2,4
    lift cup 2
    
    代码是:

    import collections
    
    N = 6
    MASK = (1<<N)-1
    
    def bitcount(n):
        if n == 0: return 0
        return 1 + bitcount(n & (n-1))
    
    def shifts(c):
        return ((c << 1) | (c >> 1)) & MASK
    
    def adjacent(c):
        if bitcount(c) == 2:
            yield min(i for i in xrange(N) if (c>>i)&1), 0
            return
        for i in xrange(N):
            if (c>>i)&1:
                yield i, shifts(c & ~(1<<i))
    
    def bfs(edges, start):
        prev = {start: None}
        q = collections.deque([start])
        while q:
            x = q.popleft()
            for y in edges[x]:
                if y in prev: continue
                prev[y] = x
                q.append(y)
        return prev
    
    def path(x, prev):
        if x is None: return []
        return path(prev[x], prev) + [x]
    
    edges = dict((v, [n for _, n in adjacent(v)]) for v in xrange(2**N))
    best_path = path(0, bfs(edges, MASK))
    
    for pi, p in enumerate(best_path[:-1]):
        print 'the ball can be under cups: %s' % ','.join(str(i+1) for i in xrange(N) if (p>>i)&1)
        print 'lift cup %d' % list(c+1 for c, n in adjacent(best_path[pi]) if n == best_path[pi+1])[0]
    
    导入集合
    N=6
    掩码=(1>i)&1),0
    返回
    对于x范围内的i(N):
    如果(c>>i)&1:
    产量i,位移(c&~(1i)和1)
    打印“提升杯%d%”列表(c+1代表c,n在相邻(最佳路径[pi]),如果n==最佳路径[pi+1])[0]
    
    我们假设球在开始时在一个均匀的杯子下(所以是2、4或6)
    为什么?作为限制搜索空间的初始方法:如果假设是正确的,那么我们只需要三次提起就可以找到它。这是找到一种最坏情况为6次提升的方法所需要的——如果你不需要假设我洗耳恭听的话;)这是一个非常奇怪的假设。似乎这无助于构建通用解决方案。很久以前,我在五个地方解决了类似的问题(猫/鼠标是更可靠的模型:)。假设2*n-4个镜头是最好的可能结果,您可以编写一些代码来运行所有组合,以找到最佳的提升顺序。只有6*2^6种可能的球的移动顺序和6^6种可能的6步6杯的举杯顺序——完成所有这些动作只需要几秒钟。如果你在寻找理论证据,你可能是在错误的位置。我的建议是要么要么要么(看起来更像数学而不是计算机科学,但我不确定这个问题是否会涉及到这两个方面的话题)。从我如何表述我的问题来看,可能还不够清楚,但在我举起杯子的那一刻,球还没有移动。所以你是对的,在第6步之后,球将移动到1或3。但是,在步骤6中,它必须位于杯2下(在最坏的情况下)。所以在这一点上,在它移动到第一杯之前,我知道它在第二杯下面(尽管我没有提起它)@radial:谢谢你的澄清。