Перевод отдельных фрагментов кода в оператор цикла - PullRequest
0 голосов
/ 24 ноября 2018

Я работаю над Matlab с файлом, составленным из единиц, запрошенных в разные дни (заказы продуктов).Файл, который можно найти по следующей ссылке: Файл

Имеет 4 столбца.Второй и четвертый показывают день и количество единиц соответственно.Этот файл имеет 3000 строк, и я хотел бы выполнить эту задачу для всех целых строк в файле.Основная задача кода, который я покажу, состоит в заполнении столбца 6 1, каждый раз, когда значение, вычисленное в столбце 5, ниже 300. В столбце 5 показано уменьшение объема единиц, которое изначально составляет 1000. Я покажу со следующим кодом:

clear
%Data
File='File.csv';
dataf=csvread(File, 1);
unbl=0;
dataf=[dataf zeros(size(dataf,1),1) zeros(size(dataf,1),1)];
%Loop by pieces
for i=1:size(dataf,1)
    if i==1
        dataf(i,5)=1000-dataf(i,4);
    else
        dataf(i,5)=dataf(i-1,5)-dataf(i,4);
    end
    if dataf(i,5)<300 && dataf(i-1,5)>=300
        dataf(i,6)=1;
    end
end

I1

В строке 29 значение меньше 300 для столбца 5, поэтому 1 в столбце 6. Номер дня встолбец 2 равен 3. Затем я должен добавить 4 к этому и найти строку, когда это произойдет первым.В этом случае первый 7. Этот код делает это и сохраняет значение столбца 5 в предыдущей строке в unlb:

index =find(dataf(:,6)==1);
index2 = find(dataf(:,2)==dataf(index,2)+4,1);
unbl = unbl+dataf(index2-1,5);

В этой строке у меня будет новый запас, затем я должен добавитьк фактическому значению столбца 5 количество 1200:

dataf(index2,5) = 1200+dataf(index2,5);

Я получил это:

I2

Следовательно, с этой точкиЯ должен повторить ту же задачу.Я использую этот длинный код:

for j=(index2+1):size(dataf,1)
    dataf(j,5)=dataf(j-1,5)-dataf(j,4);
    if dataf(j,5)<300 && dataf(j-1,5)>=300
        dataf(j,6)=1;
    end
end

index =find(dataf(:,6)==1,1,'last');
index2 = find(dataf(:,2)==dataf(index,2)+4,1);
unbl = unbl+dataf(index2-1,5);
dataf(index2,5) = 1200+dataf(index2,5);

for k=(index2+1):size(dataf,1)
    dataf(k,5)=dataf(k-1,5)-dataf(k,4);
    if dataf(k,5)<300 && dataf(k-1,5)>=300
        dataf(k,6)=1;
    end
end

index =find(dataf(:,6)==1,1,'last');
index2 = find(dataf(:,2)==dataf(index,2)+4,1);
unbl = unbl+dataf(index2-1,5);
dataf(index2,5) = 1200+dataf(index2,5);

for l=(index2+1):size(dataf,1)
    dataf(l,5)=dataf(l-1,5)-dataf(l,4);
    if dataf(l,5)<300 && dataf(l-1,5)>=300
        dataf(l,6)=1;
    end
end

index =find(dataf(:,6)==1,1,'last');
index2 = find(dataf(:,2)==dataf(index,2)+4,1);
unbl = unbl+dataf(index2-1,5);
dataf(index2,5) = 1200+dataf(index2,5);

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

%One loop (not working)
index=0;
index2=0;
unbl=0;
for i=1:size(dataf,1)
    if i==1
        dataf(i,5)=1000-dataf(i,4);
    else
        dataf(i,5)=dataf(i-1,5)-dataf(i,4);
    end
    if dataf(i,5)<300 && dataf(i-1,5)>=300
        dataf(i,6)=1;
        index =find(dataf(:,6)==1);
        index2 = find(dataf(:,2)==dataf(index,2)+4,1);
    end
    unbl = unbl+dataf(index2-1,5);
    dataf(index2,5) = 1200+dataf(index2,5);
    i=index2+1;
end

Я не знаю, как обновить индекс цикла, чтобы перемещаться по всем строкам и получать накопленное значение, сохраненное в unbl.Не могли бы вы помочь исправить эти фрагменты кода в одном операторе цикла, чтобы перемещаться по всем строкам и воспроизводить ранее упомянутую задачу.Большое спасибо.

1 Ответ

0 голосов
/ 25 ноября 2018

Вот фрагмент кода, который, я считаю, делает то, что вам нужно (пояснения в комментариях внутри):

stock = 1000;
new_stock = 1200;
unbl = 0;
% culculate the comulative substraction from the initial stock:
temp = cumsum([stock; -dataf(:,4)]);
dataf(:,5) = temp(2:end); % no need for the first element (1000)
% find when to set a new order:
low_stock = find(dataf(:,5)<300,1);
% start the loop
last_low = 0;
while low_stock~=last_low % if you found a new date with low stock
    last_low = low_stock; % use the new date
    dataf(last_low,6) = 1; % place 1 in the date with low stock
    % find the first line 4 days ahead:
    refill = last_low+find(dataf(last_low:end,2)==dataf(last_low,2)+4,1)-1;
    % add the amount on column 5 in the row above ind_b to 'unbl'
    unbl = unbl+dataf(refill-1,5);
    % add new stock to all rows below after stock arival
    dataf(refill:end,5) = dataf(refill:end,5)+new_stock;
    % find the next time to set a new order:
    low_stock = refill+find(dataf(refill+1:end,5)<300,1);    
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...