搜索具有特定范围内属性值的对象的ArrayList

时间:2014-02-06 13:55:32

标签: java arraylist

所以,我正在扩展我的Java学习。

我想创建某种匹配制作系统,就像他们在游戏中一样。其他相关申请。

在这个系统的某些时候,我想在一个评级值的某个范围内搜索队列中的“玩家”,我想到了这样做的几种方法。

public Player findClosePlayerInQueue(int rating) {
    long startTime = System.nanoTime();
    while(true) {
        int range = 100;
        for(Player p: queuedPlayers) {
            if (p.getRating() > rating - range && p.getRating() < rating + range ) {
                System.out.printf("Searching took: %.3f", (startTime - System.nanoTime())/1e9 );
                return p;
            }
        }
        range += 100;
    }
}

这是另一种方法,给定一个必须满足的特定范围。

public Player findClosestPlayerInQueue(int rating, int range) {
    long startTime = System.nanoTime();
    while(true) {
        for(Player p: queuedPlayers) {
            if (p.getRating() > rating - range && p.getRating() < rating + range ) {
                System.out.printf("Searching took: %.3f", (startTime - System.nanoTime())/1e9 );
                return p;
            }
        }
    }
}

现在,鉴于玩家可以在任何时候加入队列,这些将以某种方式进行线程化。

最后,我的问题是,这是实现这些功能的最佳方式吗?我已经四处寻找,但在应用范围时找不到任何相关内容。

不相关的额外信息:我意识到严格来说这不是范围,因为我没有价值的一半,但这不是我想要在这里解决的问题。另外需要注意的是,queuedPlayers将按照它们在队列中的长度排序

3 个答案:

答案 0 :(得分:2)

你知道,如果你使用多个变量来匹配另一个玩家,你可能会发现搜索“最近”的其他玩家的想法很有趣。

例如,您使用“rating”变量进行比较。这是一个单一的变量比较。

但是,如果你有更多的变量来比较你的球员,比如实力,敏捷等等,并将它们全部同时进行比较呢?

如果您考虑进行多变量比较,您可以使用像KNN这样的东西找到一组与您“更接近”的玩家,然后您可以选择其中一个。

这里有一个完整的KNN java代码示例和解释

http://afewguyscoding.com/2010/05/nearest-neighbors-java/

答案 1 :(得分:2)

不,这不是寻找最佳匹配的好方法,原因有三:

  • 当您在找到播放器之前需要大量+= 100增量时,您的第一种方法需要太长时间
  • 即使您的第一个方法返回,也可能无法返回最佳匹配
  • 如果没有玩家属于特定范围,您的第二种方法可能永远不会返回。

您应该做的是测量与特定rating的“距离”。在这种情况下,距离只是Math.abs(p.getRating() - rating)。记住具有最佳距离的玩家,只通过队列一次,并始终返回最佳匹配:

public Player findClosePlayerInQueue(int rating) {
    long startTime = System.nanoTime();
    int bestDistance = Integer.MAX_VALUE;
    Player res = null;
    for(Player p: queuedPlayers) {
        int dist = Math.abs(p.getRating() - rating);
        if (dist < bestDistance ) {
            bestDistance = dist;
            res = p;
        }
    }
    System.out.printf("Searching took: %.3f", (startTime-System.nanoTime())/1e9);
    return res;
}

当您的评分最终扩展到包含其他内容时,您也可以更改距离度量,以便在N维度中进行操作。您可以使用欧几里德距离Manhattan Distance或您认为适当衡量所需“亲密度”的任何其他距离。

答案 2 :(得分:2)

如果您想提高效率,可以根据玩家的等级始终对队列进行排序。然后,您可以通过执行binary search来提高查找效率。

粗略地说,二进制搜索是这样的:

  1. 您从队列中间取一名玩家,并将其评分与所需的间隔进行比较。
  2. 如果玩家符合间隔时间,那么你就得到了解决方案。
  3. 如果玩家较弱,则将搜索范围缩小到队列的上半部分。
  4. 如果玩家更强,则将搜索范围缩小到下半部分。
  5. 重复直到找到播放器,或直到搜索到的块的大小减少到1(如果队列中不存在此类播放器)。如果这样的玩家存在,你可以在log(N)比较中找到他,N是队列中的玩家数量