【问题标题】:Algorithm for finding nearest animal on board寻找船上最近动物的算法
【发布时间】:2023-03-10 14:11:01
【问题描述】:

所以我正在写一个兔子和狼的模拟 - 一开始有一定数量的狼和兔子,兔子逃离狼,狼追逐兔子,当他们在同一个街区相遇时兔子被杀死并模拟当没有兔子离开时结束。我写了大部分代码,但是我不知道如何使兔子逃离狼,狼追逐兔子。我必须首先编写一个算法来找到最近的动物,然后计算出最佳移动(这很容易)。

动物可以在 1 个线程循环中向上、向下和交叉,例如,如果有 2 只狼离开 2 次移动,那么我必须随机化我逃离的那只(狼和追逐兔子也是如此) .

我的第一种方法是我以某种方式(可能是递归的?)从给定的动物开始搜索数组,然后像这样围绕它转圈:

所以第一次迭代它没有找到狼,第二次它找到了 2,所以它保存了它们的两个坐标,结束它的工作并将它传递给随机选择的函数。现在,我认为这将是最好的主意,但我不知道如何实现它:(我尝试了几个小时但我放弃了,因为我没有到达任何地方。

第二种方法,非常幼稚,是找到棋盘上所有的狼,然后为每一个计算到达兔子所需的移动量,然后只保存数量最少的那些。我可以编码,但我认为对于更大的电路板来说效率很低。

【问题讨论】:

  • 不要低估计算机的速度。对于您正在做的事情,除非网格绝对巨大,否则这些方法中的任何一种都可以正常工作。
  • 巨大的@TimB 意味着......数百万。
  • 如果您的数据集很小(例如小于 1000),为了实现简单,我会采用蛮力方法,否则我会采用 O(n*logn) 方法en.wikipedia.org/wiki/Closest_pair_of_points_problem
  • 好的,谢谢,我会写蛮力的,看看它是如何工作的。谢谢

标签: java arrays algorithm 2d


【解决方案1】:

兔子应该看着所有的狼活得更久。如果他只是从最近的人那里逃跑——那可能是个大错误。

在这种情况下,如果狼更喜欢“向上”而不是“右”,或者“右”而不是“下”(顺时针优先),他会活得很长。另外,如果只有几只非随机的狼,兔子可能会长生不老)

我可以建议的最简单的逻辑是检查船上的所有狼并选择最接近的 5 个,按曼哈顿距离 (dx+dy) 对它们进行排序,然后将其设为 D1、D2、D3、D4、D5。

所以,让“D - 进入某个牢房有多危险”。计算

D = D1*A + D2*B + D3*C + D4*D + D5*E

A > B > C > D > E

对于与当前兔子细胞相邻的所有 4 个细胞。并选择具有最小值的单元格(您需要通过实验找到A,B,C,D,E)。我认为您也可以为 D1、D2、D3、D4、D5 设置一些上限。比如D4或D5的狼真的很远——他应该不会受到任何影响,所以让D4 = D5 = 0。

当然,这种情况下这个逻辑会失效

但我认为我们根本没有什么可以做的)所以这不是我们试图优化的情况

【讨论】:

  • 这真的很酷,我肯定会尝试实现这一点,但是有了这个我搜索所有狼的蛮力方法完全不在窗口,因为要么我必须搜索整个板5次,或者用所有狼的坐标(以及从狼到这只特定野兔的距离)按距离对数组进行排序,我不知道该怎么做。
  • @user3369008 你不需要对数组进行排序来找到最小值,不是吗?您不需要对数组进行排序以找到两个最小值,不是吗?)只需保留一些小数组(大小 = 5)并尝试将每只狼都添加到其中。如果他的距离比其他人都大 - 不要添加他。但是,例如,如果他比第三班更接近 - 3,4 班(输掉 5 班)并将他插入 3 位。最后你会得到 5 只最近的狼。
  • 你能看看这个吗? gist.github.com/deviancee/5eccd2531f4fc6c805dd wolvesCoords 是二维数组,包含所有狼的坐标。动物是 int[5][3] ,而 animal[i][2] 被初始化为最大 int 值。它适用于最近的狼,但它会落在后面,因为动物 [1] 和动物 [2] 可以有不同的距离但坐标相同:/ NVM 我发现我的错误:D
  • 好的,我实现了这个,但我认为它不能独立工作。在这种情况下,兔子最致命的事情是角落,我看不到一个简单的方法来处理它,它们只是太喜欢它们了:D 我试图将中间框的距离添加到危险值,但它不起作用
  • @user3369008 在角落里创建虚拟狼比。也可能是弱狼,所以兔子会尽量避免遇到他,但不要害怕在附近)
【解决方案2】:

这是Closest pair of points problem

这是一个实现:http://algs4.cs.princeton.edu/99hull/ClosestPair.java.html

您的对象只能垂直或水平移动,因此您需要将距离替换为 x+y。

【讨论】:

    【解决方案3】:

    如果棋盘上的物体数量比棋盘本身少得多(例如,棋盘可以达到 1000x1000 但最多有 10,000 只狼),一个实用的方法是分别存储每个物体的坐标.然后,您可以检查狼的列表,而不必每次都在板上找到它们。

    为了保持这两种表示,需要双向引用:每个板单元都有一个指向其中包含的对象的指针(如果可以有多个指针,则为指针列表),每个对象都包含其坐标细胞。还有一个包含(指向)所有现有对象的单独列表(或数组),或者可能是狼和兔子的两个单独列表,具体取决于您需要经常迭代的内容。

    【讨论】:

      猜你喜欢
      • 2011-03-20
      • 2011-02-07
      • 1970-01-01
      • 2010-10-24
      • 2011-02-02
      • 1970-01-01
      • 1970-01-01
      • 2013-07-27
      • 1970-01-01
      相关资源
      最近更新 更多