如果两个相同的距离值,则使用随机函数选择对象

时间:2016-09-19 06:13:26

标签: java collections distance

我有一个包含对象unsolvedOutlets的ArrayList Outlet,其中包含longitudelatitude属性。

使用ArrayList longitude中的latitudeOutletunsolvedOutlets个对象,我需要使用距离公式找到该列表中的最小距离:SQRT((( X2-X1)^ 2)+(Y2-Y1)^ 2),其中给出(X1,Y1)。我使用Collections.min(list)找到最小的距离。

我的问题是,如果有两个或多个具有相同最小距离的值,我必须从中随机选择一个。

代码:

ArrayList<Double> distances = new ArrayList<Double>();
Double smallestDistance = 0.0;
for (int i = 0; i < unsolvedOutlets.size(); i++) {
    distances.add(Math.sqrt(
        (unsolvedOutlets.get(i).getLatitude() - currSolved.getLatitude())*
        (unsolvedOutlets.get(i).getLatitude() - currSolved.getLatitude())+
        (unsolvedOutlets.get(i).getLongitude() - currSolved.getLongitude())*
        (unsolvedOutlets.get(i).getLongitude() - currSolved.getLongitude())));
    distances.add(0.0); //added this to test 
    distances.add(0.0); //added this to test 
    smallestDistance = Collections.min(distances);   
    System.out.println(smallestDistance);                                     
}          

控制台中的结果会打印出0.0,但它不会停止。有没有办法知道是否有多个值相同的最小值。然后我将合并Random函数。这有意义吗?大声笑,但如果有人会有这个逻辑,这将是非常有帮助的!

谢谢!

2 个答案:

答案 0 :(得分:4)

跟踪循环中最小距离的索引,并在循环后随机选择一个:

Random random = ...
...
List<Integer> minDistanceIndices = new ArrayList<>();

double smallestDistance = 0.0;
for (int i = 0; i < unsolvedOutlets.size(); i++) {
    double newDistance = Math.sqrt(
        (unsolvedOutlets.get(i).getLatitude() - currSolved.getLatitude())*
        (unsolvedOutlets.get(i).getLatitude() - currSolved.getLatitude())+
        (unsolvedOutlets.get(i).getLongitude() - currSolved.getLongitude())*
        (unsolvedOutlets.get(i).getLongitude() - currSolved.getLongitude()));
    distances.add(newDistance);
    if (newDistance < smallestDistance) {
         minDistanceIndices.clear();
         minDistanceIndices.add(i);
         smallestDistance = newDistance;
    } else if (newDistance == smallestDistance) {
         minDistanceIndices.add(i);
    }                             
}

if (!unsolvedOutlets.isEmpty()) {
     int index = minDistanceIndices.get(random.nextInt(minDistanceIndices.size()));
     Object chosenOutlet = unsolvedOutlets.get(index);
     System.out.println("chosen outlet: "+ chosenOutlet);
}

正如Jon Skeet所说,你不需要用平方根来比较距离。

此外,如果你想在球体上使用距离,你的公式是错误的:
使用您的公式,(0°N,180°E)到(0°N,0°E)的距离与(90°N,180°E)到(90°N,0°E)的距离相同),但是当你需要绕着地球一半行进从第一个到第二个行进时,最后两个坐标都表示北极。

答案 1 :(得分:2)

注意:我相信fabian的解决方案优于此,但我保留了它以证明有很多不同的方法来实现这个...

我可能会:

  • 创建一个新类型,其中包含距离插座和插座(或距离的正方形)的距离,或者使用通用Pair类型用于相同目的
  • 将原始列表映射(使用Stream.map)到这些对的列表
  • 按距离或距离的方式排序
  • 查看已排序的列表,直到找到与列表中的第一个距离不同的距离

然后你知道有多少 - 和哪个 - 出口有相同的距离。

另一种选择是简单地改变原始集合,然后按距离对结果进行排序,然后取第一个元素 - 即使其中多个具有相同的距离,你也可以这将是随机的一个。

JB Nizet选择&#34;找到最小值,然后执行第二次扫描以查找具有该距离的所有人#34;也会很好 - 而且可能更简单:)很多选择...