【问题标题】:Find second nearest value always return last nearest value查找第二个最接近的值总是返回最后一个最接近的值
【发布时间】:2019-12-12 19:14:32
【问题描述】:

我想从我的数据集中找到最接近的值。第一个值返回正确的数据,但第二个值返回最后一个最近的数据。例如,如果我有7, 11, 12, 15, 17, 20 并且我的参数值为 10,它应该返回第一个最接近的值 = 11 和第二个最接近的值 = 12。但是当我尝试时,第二个值不是 12 而是 20。第一个值将给出正确的返回但第二个最接近的值将始终显示最后一个最接近的值,而不是第二个最接近的值。

这是我的代码:

String closestPosition = null;

            ArrayList<Router> wifis = db.getFriendlyWifis(building);

            double min_distance = positionData.uDistance(positionsData.get(0), wifis);
            closestPosition = positionsData.get(0).getName();
            String res = "";
            res += closestPosition + "\n" + min_distance;
            res += "\n" + positionsData.get(0).toString();
            int j=0;
            for (int i = 1; i < positionsData.size(); i++) {
                double distance = positionData.uDistance(positionsData.get(i), wifis);
                res += "\n" + positionsData.get(i).getName() + "\n" + distance;
                res += "\n" + positionsData.get(i).toString();
                if (distance < min_distance) {
                    min_distance = distance;
                    closestPosition = positionsData.get(i).getName();
                    j=i;
                }

            }
            if (min_distance == PositionData.MAX_DISTANCE){
                closestPosition="OUT OF RANGE";
                Toast.makeText(this,"You are out of range of the selected building",Toast.LENGTH_LONG).show();

            }
            result.setText("Nearest point :  "+ closestPosition);
            res += "\nCurrent:\n" + positionData.toString();
            Log.v("Result",res);
            //////////////////////////////////////////////////

            min_distance = positionData.uDistance(positionsData.get(0), wifis);
            String closestPosition2 = null;

            closestPosition2 = positionsData.get(0).getName();
            res = "";
            res += closestPosition2 + "\n" + min_distance;
            res += "\n" + positionsData.get(0).toString();
            for (int i = 1; i < positionsData.size(); i=i+2) { if(j!=i){
                    double distance = positionData.uDistance(positionsData.get(i), wifis);
                    res += "\n" + positionsData.get(i).getName() + "\n" + distance;
                    res += "\n" + positionsData.get(i).toString();
                    closestPosition2 = positionsData.get(i).getName();//////////////////////////
                    if(closestPosition2.equals(closestPosition))
                        continue;
                    if (distance < min_distance) {
                        min_distance = distance;
                        closestPosition2 = positionsData.get(i).getName();

                    }
                }
            }

            if (min_distance == PositionData.MAX_DISTANCE){
                closestPosition2="OUT OF RANGE";
                Toast.makeText(this,"You are out of range of the selected building",Toast.LENGTH_LONG).show();

            }
            result2.setText("Nearest point :  "+ closestPosition2);

这是输出:

V/closest1:: f
V/closest2:: e

这是日志:

 d
    36.0
    d(4.0,4.0)
    UGM-Secure : -63.0
    eduroam : -63.0
    UGM-Hotspot : -42.0

    a
    64.0
    a(1.0,1.0)
    UGM-Hotspot : -40.0

    f
    17.0
    f(6.0,6.0)
    UGM-Secure : -65.0
    eduroam : -66.0
    UGM-Hotspot : -46.0

    b
    25.0
    b(2.0,2.0)
    UGM-Secure : -60.0
    eduroam : -59.0
    UGM-Hotspot : -48.0

    c
    89.0
    c(3.0,3.0)
    UGM-Secure : -60.0
    eduroam : -59.0
    UGM-Hotspot : -40.0

    e
    94.0
    e(5.0,5.0)
    UGM-Secure : -65.0
    eduroam : -66.0
    UGM-Hotspot : -39.0

如果第一个最接近的值是 f 值 17,那么第二个最接近的值是 b 还是 d 对吗?但是为什么它返回具有最远值的 e 呢?实际上,我也在寻找第三个最接近的值,如果还有办法找到第三个最接近的值,那就太好了。

编辑:这是我的 PositionData 类

public class PositionData implements Serializable {
    public static final int MAX_DISTANCE=99999999;
    private String name;
    double x;
    double y;
    public static final int MINIMUM_COMMON_ROUTERS=1;
    public HashMap<String, Double> values;
    public HashMap<String,String> routers;



    public PositionData(String name, double x, double y) {
        // TODO Auto-generated constructor stub
        this.name=name;
        this.x=x;
        this.y=y;
        values = new HashMap<String, Double>();
        routers = new HashMap<String, String>();

    }



    public void addValue(Router router, double strength){

        values.put(router.getBSSID(), strength);
        routers.put(router.getBSSID(),router.getSSID());

    }
    public String getName() {
        return name;
    }

    public Double getX() {
        return x;
    }

    public Double getY() {
        return y;
    }

    public String toString() {
        String result="";
        result+=name+"("+x+","+y+")"+"\n";
        for(Map.Entry<String, Double> e: this.values.entrySet())
            result+=routers.get(e.getKey())+" : "+e.getValue().toString()+"\n";

        return result;

    }
    public HashMap<String, Double> getValues() {
        return values;
    }
    public double uDistance(PositionData arg,ArrayList<Router> friendlyWifis){
        double sum=0;
        double count=0;
        for(Map.Entry<String, Double> e: this.values.entrySet()){
            Double v;
            //Log.v("Key : ",arg.values.get(e.getKey()).toString());
            if(isFriendlyWifi(friendlyWifis,e.getKey()) && arg.values.containsKey(e.getKey()))
            {
                v=arg.values.get(e.getKey());
                sum+=Math.pow((v-e.getValue()),2);
                count++;
            }
        }
        if(count<MINIMUM_COMMON_ROUTERS){
            sum=MAX_DISTANCE;
        }

        return sum;
    }

    private boolean isFriendlyWifi(ArrayList<Router> wifis, String bssid){
        for(int i=0;i<wifis.size();i++){
            if(wifis.get(i).getBSSID().equals(bssid))
                return true;

        }
        return false;

    }

}

【问题讨论】:

    标签: java android if-statement coordinates closest


    【解决方案1】:

    试试下面的代码:

        private final static int POSITIONS_ARRAY_SIZE = 3; //Global constant in the Activity.
    
    
        String closestPosition = null;
        String closestPosition2 = null;
        String closestPosition3 = null;
        ArrayList<Router> wifis = db.getFriendlyWifis(building);
        boolean flagPositionInserted;
    
        ArrayList<Integer> min_distance_positions = new ArrayList<>();
        //Get the first value (position = 0).
        double min_distance = positionData.uDistance(positionsData.get(0), wifis);
        min_distance_positions.add(0);
        String res = "";
        res += closestPosition + "\n" + min_distance;
        res += "\n" + positionsData.get(0).toString();
    
        //Iterate through the datalist (positionsData).
        for (int i = 1; i < positionsData.size(); i++) {
            double distance = positionData.uDistance(positionsData.get(i), wifis);
            res += "\n" + positionsData.get(i).getName() + "\n" + distance;
            res += "\n" + positionsData.get(i).toString();
    
            flagPositionInserted = false;
            //Iterate through the sorted list (min_distance_positions).
            for (int j = 0; j < min_distance_positions.size(); j++){
                if (distance < positionData.uDistance(positionsData.get(min_distance_positions.get(j)), wifis)) {
                    min_distance_positions.add(j, i);
                    flagPositionInserted = true;
                    break;
                }
            }
            if (!flagPositionInserted) {
                if (min_distance_positions.size() < POSITIONS_ARRAY_SIZE) {
                    min_distance_positions.add(i);
                }
            }
        }
    
        //min_distance_positions.size() should be less or equal to 3(POSITIONS_ARRAY_SIZE).
        //min_distance_positions.get(0) is the closestPosition.
        //min_distance_positions.get(1) is the 2nd closestPosition.
        //min_distance_positions.get(2) is the 3rd closestPosition.
        String msg = "";
        for (int i = 0; i < min_distance_positions.size(); i++){
            msg += min_distance_positions.get(i) + ", ";
        }
        Log.v("Result", "Position ArrayList Content: " + msg);
    
        closestPosition = positionsData.get(min_distance_positions.get(0)).getName();
        if (positionData.uDistance(positionsData.get(min_distance_positions.get(0)), wifis) >= PositionData.MAX_DISTANCE){
            closestPosition="OUT OF RANGE";
            Toast.makeText(this,"You are out of range of the selected building",Toast.LENGTH_LONG).show();
        }
        result.setText("Nearest point :  "+ closestPosition);
        res += "\nCurrent:\n" + positionData.toString();
        Log.v("Result", res);
    
        closestPosition2 = positionsData.get(min_distance_positions.get(1)).getName();
        if (positionData.uDistance(positionsData.get(min_distance_positions.get(1)), wifis) >= PositionData.MAX_DISTANCE){
            closestPosition2="OUT OF RANGE";
            Toast.makeText(this,"You are out of range of the selected building",Toast.LENGTH_LONG).show();
        }
        result2.setText("Nearest point :  "+ closestPosition2);
        closestPosition3 = positionsData.get(min_distance_positions.get(2)).getName();
        if (positionData.uDistance(positionsData.get(min_distance_positions.get(2)), wifis) >= PositionData.MAX_DISTANCE){
            closestPosition3="OUT OF RANGE";
            Toast.makeText(this,"You are out of range of the selected building",Toast.LENGTH_LONG).show();
        }
        result3.setText("Nearest point :  "+ closestPosition3);
    

    代码是使用INSERTION SORT根据距离对点进行排序,并将点位置存储在另一个ArrayList(min_distance_positions)中。根据您的样本数据,原始顺序为:d(位置 0)、a(位置 1)、f(位置 2)、b(位置 3)、c(位置 4)、e(位置 5)。排序顺序为:2(f)、3(b)、0(d)、1(a)、4(c)、5(e)。 if (min_distance_positions.size() &lt; POSITIONS_ARRAY_SIZE)是控制输出ArrayList(min_distance_positions)大小,所以现在msg只有:2,3,0,。如果省略此代码,则 msg 为:2, 3, 0, 1, 4, 5,

    希望有帮助!

    【讨论】:

    • 我在运行中收到此消息SQLiteConnectionPool: A SQLiteConnection object for database was leaked! Please fix your application to end transactions in progress properly and to close the database when it is no longer needed.
    • 所以我们用min_distance_positions.remove(POSITIONS_ARRAY_SIZE) 删除第一个最接近的值,然后我们可以寻找第二个最接近的值?或者那个代码是 3 个最接近的值?
    • 对不起,我不明白,我应该为//min_distance_positions.size() should be less or equal to 3(POSITIONS_ARRAY_SIZE). //min_distance_positions.get(0) is the 1st closestPosition. //min_distance_positions.get(1) is the 2nd closestPosition. //min_distance_positions.size2) is the 3rd closestPosition.写代码吗?
    • 所以我需要重写它,并将 j 更改为 1 和 2 以获得第二和第三最近的点?以及为什么使用//min_distance_positions.size(2) 获得第三个最接近位置,而第一个和第二个使用//min_distance_positions.get(1/2)
    • 更新了代码以显示如何显示 result2 和 result3,并添加了更多 cmets :-)
    【解决方案2】:

    这将为您提供最接近的值

    int[] numbers = new int[10];
    numbers[0] = 100;
    numbers[1] = -34200;
    numbers[2] = 3040;
    numbers[3] = 400433;
    numbers[4] = 500;
    numbers[5] = -100;
    numbers[6] = -200;
    numbers[7] = 532;
    numbers[8] = 6584;
    numbers[9] = -945;
    
    int myNumber = 50;
    int distance = Math.abs(numbers[0] - myNumber);
    int idx = 0;
    for(int c = 1; c < numbers.length; c++){
        int cdistance = Math.abs(numbers[c] - myNumber);
        if(cdistance < distance){
            idx = c;
            distance = cdistance;
        }
    }
    int nearestNumber = numbers[idx];
    

    【讨论】:

    • 我已经得到了最接近的值。我的问题是关于第二接近的值和第三接近的值。
    • 此链接可能对Nearest valueclosest value in a sorted List 有帮助,请检查
    • 未排序。参数的值在输出中的点名称下
    【解决方案3】:
      import java.util.Arrays;
        public class Main {
            public static void main(String[] args) {
                System.out.println("Hello World");
                int[] numbers = new int[10];
                numbers[0] = 100;
                numbers[1] = -34200;
                numbers[2] = 3040;
                numbers[3] = 400433;
                numbers[4] = 500;
                numbers[5] = -100;
                numbers[6] = -100;
                numbers[7] = 532;
                numbers[8] = 6584;
                numbers[9] = -945;
                // my number 
                int myNumber = 150;
                Arrays.sort(numbers);
    
    // for first nearest value
                int num = valnearest(numbers, myNumber);
                int firstnearestNumber = numbers[num];
                System.out.println("firstnearestNumber--->" + firstnearestNumber);
    
     // for Second nearest value
                numbers = removeTheElement(numbers, num);
    
                int newnum = valnearest(numbers, myNumber);
                int secondnearestNumber = numbers[newnum];
                System.out.println("secondnearestNumber--->" + secondnearestNumber);
    
            }
    
            public static int valnearest(int[] numbers, int myNumber) {
                int idx = 0;
                int lastdistance = -1;
                for (int c = 0; c < numbers.length; c++) {
                    int distance = Math.abs(numbers[c] - myNumber);
    
                    if (lastdistance != -1) {
                        if (distance < lastdistance) {
                            idx = c;
                        }
                    }
                    lastdistance = distance;
    
                }
    
                return idx;
            }
    
            public static int[] removeTheElement(int[] arr,
                                                 int index) {
    
                // If the array is empty 
                // or the index is not in array range 
                // return the original array 
                if (arr == null
                        || index < 0
                        || index >= arr.length) {
    
                    return arr;
                }
    
                // Create another array of size one less 
                int[] anotherArray = new int[arr.length - 1];
    
                // Copy the elements except the index 
                // from original array to the other array 
                for (int i = 0, k = 0; i < arr.length; i++) {
    
                    // if the index is 
                    // the removal element index 
                    if (i == index) {
                        continue;
                    }
    
                    // if the index is not 
                    // the removal element index 
                    anotherArray[k++] = arr[i];
                }
    
                // return the resultant array 
                return anotherArray;
            }
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-02-16
      • 2013-03-01
      • 2022-11-10
      • 2016-07-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多