чередующиеся и смещающиеся участки массива - PullRequest
0 голосов
/ 13 июня 2019

У меня есть массив тревог (может быть массив любого размера, но он не будет 1 xm) , и я хочу вращать / сдвигать каждый квадратный цикл независимо от размера массива.

Как я могу чередовать вращение / сдвиг каждого квадратного цикла независимо от размера массива.

Обратите внимание: я не пытаюсь вычислить значения в массиве, но сдвигаю значения.

Мой мыслительный процесс состоял в том, чтобы получить значения каждого "квадрата"loop "и поместите их в одну строку и выполните круговое смещение, затем поместите их обратно в другой массив.

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

розовый подсвеченный раздел, слева от стрелок - это начальная позиция массива и его "петли" и зеленый выделенный участок, справа от стрелок - это тип вращения / сдвига значений, которые я пытаюсь создать. Массив может иметь более 3 «циклов», это только пример.

Код ниже:

I=[1:5;6:10;11:15;16:20;21:25;26:30]

[rw,col] = size(I);

outer_1=[I(1,:),I(2:end-1,end).',I(end,end:-1:1),I(end-1:-1:2,1).'] %get values in one row (so I can shift values)
outer_1_shift=circshift(outer_1,[0 1]) %shift values 
new_array=zeros(rw,col);

Shift Process

Ps: я использую Octave 4.2.2 Ubuntu 18.04

Ответы [ 2 ]

1 голос
/ 13 июня 2019

Редактировать: функция кругового смещения была изменена для Octave 5.0, последнее редактирование сделало ее совместимой с предыдущими версиями

1;

function r = rndtrip (n, m, v)
  rv = @(x) x - 2 * (v - 1);
  r = [v * ones(1,rv(m)-1) v:n-v+1 (n-v+1)*ones(1,rv(m)-2)];
  if (rv(m) > 1)
    r = [r n-v+1:-1:v+1];
  endif
endfunction

function idx = ring (n, m , v)

  if (2*(v-1) > min (n, m))
    r = [];
  else
    r = rndtrip (n, m, v);
    c = circshift (rndtrip (m, n, v)(:), - n + 2 * v - 1).';
    idx = sub2ind ([n m], r, c);
  endif

endfunction

# your I
I = reshape (1:30, 5, 6).';

# positive is clockwise, negative ccw
r = [1 -1 1];

for k = 1:numel(r)

  idx = ring (rows(I), columns(I), k);
  I(idx) = I(circshift(idx(:), r(k)));

endfor

I

дает

I =

    6    1    2    3    4
   11    8    9   14    5
   16    7   18   19   10
   21   12   13   24   15
   26   17   22   23   20
   27   28   29   30   25

запустить ее в режиме tio

1 голос
/ 13 июня 2019

Итак, у меня была та же идея, что и в комментарии Энди . Тем не менее, так как я уже готовил некоторый код, вот мое предложение:

% Input.
I = reshape(1:30, 5, 6).'
[m, n] = size(I);

% Determine number of loops.
nLoops = min(ceil([m, n] / 2));

% Iterate loops.
for iLoop = 1:nLoops

  % Determine number of repetitions per row / column.
  row = n - 2 * (iLoop - 1);
  col = m - 2 * (iLoop - 1);

  % Initialize indices.
  idx = [];

  % Add top row indices.
  idx = [idx, [repelem(iLoop, row).']; iLoop:(n-(iLoop-1))];

  % Add right column indices.
  idx = [idx, [[iLoop+1:(m-(iLoop-1))]; repelem(n-(iLoop-1), col-1).']];

  if (iLoop != m-(iLoop-1))

    % Add bottom row indices.
    idx = [idx, [repelem(m-(iLoop-1), row-1).'; (n-(iLoop-1)-1:-1:iLoop)]]

  end

  if (iLoop != n-(iLoop-1))

    % Add left column indices.
    idx = [idx, [[(m-(iLoop-1))-1:-1:iLoop+1]; repelem(iLoop, col-2).']]

  end

  % Convert subscript indices to linear indices.
  idx = sub2ind(size(I), idx(1, :), idx(2, :));

  % Determine direction for circular shift operation.
  if (mod(iLoop, 2) == 1)
    direction = [0 1];
  else
    direction = [0 -1];
  end

  % Replace values in I.
  I(idx) = circshift(I(idx), direction);

end

% Output.
I

К сожалению, я не мог придумать более разумного способа генерирования индексов, поскольку вам нужно поддерживать правильный порядок и избегать двойных индексов. Как видите, я получаю индексы индекса по отношению к I, поскольку это можно сделать довольно просто, используя размеры матрицы и количество циклов. Тем не менее, для операции circshift и последующей замены значений в I линейные индексы более удобны, поэтому операция sub2ind.

Вход и выход выглядят так:

I =
    1    2    3    4    5
    6    7    8    9   10
   11   12   13   14   15
   16   17   18   19   20
   21   22   23   24   25
   26   27   28   29   30

I =
    6    1    2    3    4
   11    8    9   14    5
   16    7   18   19   10
   21   12   13   24   15
   26   17   22   23   20
   27   28   29   30   25

Я был прав, что «направление сдвига» меняется с каждым циклом?

Надеюсь, это поможет!

Внимание: я еще не проверял общность. Поэтому, пожалуйста, сообщайте о любых ошибках, с которыми вы можете столкнуться.

...