Более быстрый способ уменьшить некоторые элементы в векторе в Matlab

#performance #algorithm #matlab #vector

#Производительность #алгоритм #matlab #вектор

Вопрос:

Я ищу более быстрый способ уменьшить значение определенных чисел в векторе в Matlab, например, у меня есть этот вектор:

Вектор а=[1 21 35 44 45 67 77 83 93 100]

Затем я должен удалить элементы 35,45,77, так что:

Удалить вектор b=[3,5,7] Удалить элементы c=[35,45,77]

После удаления элементов, они должны быть:

Вектор=[1 21 43 65 80 90 97]

Обратите внимание, что помимо удаления элемента, все последующие элементы уменьшают свои значения на 1, у меня есть этот код в Matlab:

 a(:,b) = [];
b = fliplr(b);
for i=1:size(a,2)
    for j=1:size(c,2)
        if(a(1,i)>=c(1,j))
            a(1,i) = a(1,i) -1;
        end
    end
end
 

Но слишком медленно, m0 = 2,8 * 10 ^-3 секунды, есть более быстрый алгоритм? Я считаю, что с помощью matrix операции могли бы быть более быстрыми и элегантными.

Комментарии:

1. Ваш код не выдает результат [1 21 43 65 80 90 97] , какое поведение предполагается?

2. Извините, я исправил код, это дает мне [1 21 43 65 80 90 97], но я хочу улучшить время

Ответ №1:

У @Geoff хороший общий подход, но корректировка может быть выполнена O(n) не O(n*k) :

 adjustment = zeros(size(a));
adjustment(b(:)) = 1;

a = a - cumsum(adjustment);
a(b(:)) = [];
 

Комментарии:

1. Спасибо, я проверил код, время составило 7,426*10^-5 секунд

Ответ №2:

Я думаю , что перед удалением элементов a , индексы которых указаны в b , код мог бы сначала выполнить все уменьшение

 % copy a
c = a;

% iterate over each index in b
for k=1:length(b)
    % for all elements in c that follow the index in b (so b(k) 1…end)
    % subtract one
    c(b(k) 1:end) = c(b(k) 1:end) - 1;
end

% now remove the elements that correspond to the indices in b
c(b) = [];
 

Попробуйте выше и посмотрите, что получится!

Комментарии:

1. Спасибо, я проверил код, время составило 1.2648 * 10 ^ -4 секунды

Ответ №3:

Большое спасибо Джеффу и Бену за ваш ответ, я доказал оба ответа таким образом:

 tic
a=[1 21 35 44 45 67 77 83 93 100];
b=[3 5 7];
%Code by Geoff
c = a;
for k=1:length(b)
    % for all elements in c that follow the index in b (so b(k) 1…end)
    % subtract one
    c(b(k) 1:end) = c(b(k) 1:end) - 1;
end
c(b) = [];
m1 = toc;
 

и

 tic
a=[1 21 35 44 45 67 77 83 93 100];
b=[3 5 7];
%Code by Ben
adjustment = zeros(size(a));
adjustment(b(:)) = 1;
a = a - cumsum(adjustment);
a(b(:)) = [];
m2 = toc;
 

Результаты на моей машине были m1 = 1,2648 * 10 ^ -4 секунды и m2 = 7,426 * 10 ^ -5 секунд, второй код быстрее, мой первый код дает m0 = 2,8 * 10 ^ -3 секунды.