Java 使用随机函数选择两个相同距离值的对象

Java 使用随机函数选择两个相同距离值的对象,java,collections,distance,Java,Collections,Distance,我有一个ArrayListUnlovedOutlets包含对象Outlets,该对象具有属性经度和纬度 使用ArrayListUnrovedOutlets中Outlet对象的经度和纬度,我需要使用距离公式找到该列表中的最小距离:SQRT((X2-X1)^2)+(Y2-Y1)^2,其中(X1,Y1)是给定的。我使用Collections.min(list)查找最小距离 我的问题是,如果有两个或多个值具有相同的最小距离,我必须从中随机选择一个 代码: ArrayList距离=新建ArrayList(

我有一个ArrayList
UnlovedOutlets
包含对象
Outlets
,该对象具有属性
经度
纬度

使用ArrayList
UnrovedOutlets
Outlet
对象的
经度
纬度
,我需要使用距离公式找到该列表中的最小距离:SQRT((X2-X1)^2)+(Y2-Y1)^2,其中(X1,Y1)是给定的。我使用
Collections.min(list)
查找最小距离

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

代码:

ArrayList距离=新建ArrayList();
双最小距离=0.0;
对于(int i=0;i<0.size();i++){
距离。添加(Math.sqrt(
(unsolvedOutlets.get(i).getLatitude()-currSolved.getLatitude())*
(unsolvedOutlets.get(i).getLatitude()-currSolved.getLatitude())+
(未解决的outlets.get(i).getLongitude()-currSolved.getLongitude())*
(未解决的outlets.get(i).getLongitude()-currSolved.getLongitude());
距离。添加(0.0);//将此添加到测试
距离。添加(0.0);//将此添加到测试
smallestDistance=Collections.min(距离);
System.out.println(最小距离);
}          
控制台中的结果将打印出
0.0
,但不会停止。有没有办法知道是否有多个最小值相同的值。然后我将合并
Random
函数。这有意义吗?哈哈,但是如果有人有这样的逻辑,那真的很有帮助


谢谢大家!

注意:我相信fabian的解决方案比这更好,但我一直保留着它,以证明有许多不同的实现方法

我可能会:

  • 创建一个新类型,该类型包含与插座的距离以及插座的距离(或仅包含距离的平方),或出于相同目的使用通用的
    类型
  • 映射(使用
    Stream.Map
    )原始列表到这些对的列表
  • 按距离或距离的平方排序
  • 查看已排序的列表,直到找到与列表中第一个不同的距离
然后,您就知道有多少个以及哪些插座具有相同的距离

另一种选择是简单地洗牌原始集合,然后按距离对结果排序,然后获取第一个元素——这样即使多个元素具有相同的距离,您也将随机获取其中的一个


JB Nizet的“找到最小值,然后进行第二次扫描以找到所有具有该距离的对象”的选项也很好,而且可能更简单:)有很多选项…

注意:我相信fabian的解决方案优于此,但我一直保留着它,以证明有许多不同的实现方法

我可能会:

  • 创建一个新类型,该类型包含与插座的距离以及插座的距离(或仅包含距离的平方),或出于相同目的使用通用的
    类型
  • 映射(使用
    Stream.Map
    )原始列表到这些对的列表
  • 按距离或距离的平方排序
  • 查看已排序的列表,直到找到与列表中第一个不同的距离
然后,您就知道有多少个以及哪些插座具有相同的距离

另一种选择是简单地洗牌原始集合,然后按距离对结果排序,然后获取第一个元素——这样即使多个元素具有相同的距离,您也将随机获取其中的一个


JB Nizet的“找到最小值,然后执行第二次扫描以找到所有具有该距离的索引”选项也很好,而且可能更简单:)有很多选项…

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

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);
}
Random=。。。
...
List MinDistanceIndexes=新建ArrayList();
双最小距离=0.0;
对于(int i=0;i<0.size();i++){
double newDistance=Math.sqrt(
(unsolvedOutlets.get(i).getLatitude()-currSolved.getLatitude())*
(unsolvedOutlets.get(i).getLatitude()-currSolved.getLatitude())+
(未解决的outlets.get(i).getLongitude()-currSolved.getLongitude())*
(未解决的outlets.get(i).getLongitude()-currSolved.getLongitude());
距离。添加(新距离);
if(新距离<最短距离){
MinDistanceIndex.clear();
增加(i);
smallestDistance=新距离;
}else if(newDistance==smallestDistance){
增加(i);
}                             
}
如果(!unsolvedOutlets.isEmpty()){
int index=mindistanceindex.get(random.nextInt(mindistanceindex.size());
对象chosenOutlet=unsolvedouts.get(索引);
System.out.println(“选择的出口:“+chosenOutlet”);
}
正如Jon Skeet提到的,比较距离不需要平方根

此外,如果要在球体上使用距离,则公式是错误的:

根据你的公式,你将得到(0°N,180°E)到(0°N,0°E)与(90°N,180°E)到(90°N,0°E)相同的距离,但是你需要绕地球的一半才能从第一个移动到第二个,最后两个坐标都表示北极。

跟踪循环中最小距离的指数,循环后随机选择一个:

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);
}
Random=。。。
...
List MinDistanceIndexes=新建ArrayList();
双最小距离=0.0;
对于(int i=0;i<0.size();i++){
double newDistance=Math.sqrt(
(1)获取(i)。