2015-02-26 3 views
-1

ok, поэтому у меня есть 2 вектора (A и B) с разной длиной (в этом примере можно сказать 100000 и 300000), и я хочу получить индексы, имеющие наибольшую разницу. Что-то вроде этоговычислить максимальное расстояние с большими векторами

distAB=bsxfun(@(v1,v2) abs(v1-v2),A,B)); 
[~,lin_indx]=max(distAB(:)); 
[x_indx,y_indx]=ind2sub(size(A),lin_indx) 

Проблема здесь в том, что мои векторы А и В являются слишком большими, и производя матрица «distAB» слишком дорого. Я хотел бы получить мин непосредственно с bsxfun.

+0

Просьба уточнить, хотите ли вы максимальное или минимальное расстояние. Ваш заголовок и код говорят min, ваш текст говорит max –

+0

Является ли 'size (A)' right? Не должно быть '[numel (A) numel (B)]'? – Divakar

+0

Итак, ваши размеры: 'size (A) == [100000,1]' и 'size (B) == [300000,1]', и вы хотите найти точки 'A (i)' и 'B (j) ', так что' abs (A (i) -B (j)) 'как можно меньше? – knedlsepp

ответ

2

Если вы хотите разворачивания расстояния, поиск может быть сведена к только две пары кандидатов : max(A), min(B)) или min(A), max(B)).

Так просто попробовать эти две пары:

[ma_val, ma_ind] = min(A); 
[Ma_val, Ma_ind] = max(A); 
[mb_val, mb_ind] = min(B); 
[Mb_val, Mb_ind] = max(B); 
diff1 = abs(Mb_val-ma_val); 
diff2 = abs(Ma_val-mb_val); 
if diff1 > diff2 
    result_ind_A = ma_ind; 
    result_ind_B = Mb_ind; 
    result_value = diff1; 
else 
    result_ind_A = Ma_ind; 
    result_ind_B = mb_ind; 
    result_value = diff2; 
end 

Если вы хотите минимизировать расстояние: сортировка конкатенации A и B, отслеживание какого элемент из A и который из B :

C = sortrows([A(:) zeros(numel(A),1); B(:) ones(numel(B),1)] ,1); 
%// C(k,2)==0 indicates element k comes from A; 1 indicates from B 

Теперь, используйте петлю for для перемещения всех элементов в C(:,1), которые исходят от B. Для каждого такого элемента найдите два элемента из A, которые расположены ближе всего выше и ниже слева в C. Это единственные кандидаты от A, чтобы быть ближе к этому элементу от A.

Для каждого элемента от B у вас есть два кандидата от A, что значительно снижает сложность проблемы.

+0

Хорошее наблюдение! – Divakar

+0

Но теперь я сомневаюсь, что OP хочет мин или макс ... –

+0

Пошел бы и на сортировку. – knedlsepp

1

Вы можете рассчитать distAB этот путь с помощью встроенного в @minus, которые могли бы быть более эффективным -

distAB = abs(bsxfun(@minus,A(:).',B(:))) 
+0

, который похож на то, что у меня есть, и не решит проблему, поскольку необходимо будет создать матрицу distAB. идея заключается в том, что я никогда не хочу генерировать 5x7 distAB, а затем вычислять минимум, но вместо этого вычислять минимум в одно и то же время.вместо 5, 7 представить себе матрицу 10000x100000 – ASantosRibeiro

+0

@ASantosRibeiro Если они такие большие, используйте петлю –

+0

@ASantosRibeiro Да, с этим огромным входом вы не можете думать о векторизованном подходе! – Divakar

1

Luis «Подход к сортировке, вероятно, будет самым быстрым. Но если у вас установлен набор инструментов статистики, вы можете использовать функцию knnsearch, которая обеспечивает простое, но эффективное решение. (Есть также некоторые подобные бесплатные версии этого файла на Файловом обмене. Ищите: kd tree nearest neighbor)

Одним из дополнительных преимуществ этого решения является то, что он также работает для данных 2D, 3D, ..., nD.

[Is, D] = knnsearch(A,B,'K',1); 
[~,j] = min(D); i = Is(j); 
[A(i), B(j)] 
+0

На днях мне нужно узнать, что такое KNN ... –

+2

В зависимости от размеров данных 'knnsearch' либо выполняет полный поиск по всем точкам (как в' min (pdist2 (... ') или строит дерево * kd *, которое в основном похоже на двоичное дерево, но условие, если что-то идет в левой ветви или правой ветке, чередуется с глубиной дерева и в основном циклически проходит через размеры (что в 1D делает это бинарное дерево). Поиск ближайших соседей * k к определенной точке легко (с точки зрения вычислительной сложности). – knedlsepp

Смежные вопросы