Рассчитать ближайшее евклидово расстояние с помощью JavaScript

У меня есть набор данных, который выглядит следующим образом (исходные данные: здесь):

var irisjson = [
    {"sepalLength": 5.1, "sepalWidth": 3.5, "petalLength": 1.4, "petalWidth": 0.2, "species": "setosa"},
    {"sepalLength": 4.9, "sepalWidth": 3.0, "petalLength": 1.4, "petalWidth": 0.2, "species": "setosa"},
    {"sepalLength": 4.7, "sepalWidth": 3.2, "petalLength": 1.3, "petalWidth": 0.2, "species": "setosa"}....]

Я хочу рассчитать евклидово расстояние и найти ближайшие точки. Функция, которую я написал, выглядит следующим образом:

function findClosest(irisjson){

    var result = [];
    //Calculate Euc. Dist
    for(var i=0; i < irisjson.length; i++){
        for(var j = 1; j < irisjson.length-1 ; j++){
            var a1, a2 , a3 , a4 ;

            a1 = irisjson[i].sepalLength -
                    irisjson[j].sepalLength;

            a2 = irisjson[i].sepalWidth -
                    irisjson[j].sepalWidth;

            a3 = Math.pow(a1, 2);
            a4 = Math.pow(a2, 2);

            result[i] = Math.sqrt(a3 + a4);


        }
        console.log(result[i]);
    }
}

Когда я вывожу результат на консоль, я вижу 1.1045361017187265 в первой строке. Однако, когда я вручную тестирую его, как показано ниже, я вижу результат 0.5385164807134502:

a1 = irisjson[0].sepalLength -
            irisjson[1].sepalLength;

    a2 = irisjson[0].sepalWidth -
            irisjson[1].sepalWidth;

    a3 = Math.pow(a1, 2);
    a4 = Math.pow(a2, 2);

    result = Math.sqrt(a3 + a4);
    console.log("res:", result);

Любые идеи о том, почему я получаю разные результаты?

Буду признателен за любую помощь, Спасибо!


person supaplex    schedule 03.07.2015    source источник
comment
Я получаю ожидаемые вами результаты — см.: jsfiddle.net/stvsg0we. Тем не менее, не перезаписываете ли вы (неправильно) предыдущие результаты в строке «результат [i] = Math.sqrt (a3 + a4);»?   -  person Joseph Redfern    schedule 03.07.2015
comment
Вы правы, @JosephRedfern выводит правильные результаты для трех строк кода JSON. Но у меня более длинный список, и он не печатает правильные результаты. Это может иметь какое-то отношение к переписыванию, о котором вы упомянули. Но я не мог понять. Можете ли вы попытаться объяснить больше? Большое спасибо!   -  person supaplex    schedule 03.07.2015
comment
Можете ли вы обновить свой вопрос, включив в него немного больше данных, чтобы проблемы было легче воспроизвести?   -  person Joseph Redfern    schedule 03.07.2015
comment
Я обновил вопрос @JosephRedfern. Вы можете найти данные здесь: raw.githubusercontent.com/vega/vega/master/examples/data/   -  person supaplex    schedule 03.07.2015
comment
Хорошо, теперь я вижу проблему - это из-за перезаписи. Вы хотите найти ближайшую пару точек?   -  person Joseph Redfern    schedule 03.07.2015
comment
Да, мне нужно найти ближайшую пару точек @JosephRedfern   -  person supaplex    schedule 03.07.2015


Ответы (1)


В настоящее время вы несколько раз перезаписываете результат [i] строкой

result[i] = Math.sqrt(a3 + a4);

Вам действительно нужно хранить расстояния между ВСЕМИ диафрагмами? Вы можете отслеживать текущий минимум (и индексы двух радужных оболочек) и обновлять его по мере необходимости. Избавьтесь от массива результатов и замените его объектом, который выглядит так:

minPair = {'irisA': i, 'irisB': j, distance: 0};

где i и j — индексы в списке ирисов.

Для каждой итерации цикла проверяйте, меньше ли расчетное расстояние, чем minPair.distance. Если это так, обновите minPaid.irisA, minPaid.irisB и minPair.distance на соответствующее значение.

После того, как вы закончите зацикливание, вы можете войти в minPair, чтобы увидеть, какие диафрагмы имеют минимальное расстояние.

person Joseph Redfern    schedule 03.07.2015
comment
Да, мне нужно сохранить расстояния между всеми радужками, так как я буду использовать эту информацию позже. - person supaplex; 03.07.2015
comment
В этом случае я бы сохранил массив results[], но также добавил объект minPair и обновил его, как описано. Вы можете изменить результаты, чтобы они были массивом массивов, где результаты[i][j] == расстояние между i и j. - person Joseph Redfern; 03.07.2015