Предотвращение повторяющихся последовательностей в матрице в Matlab

У меня есть матрица 192 x 3, порядок (192 x 3):

order(:, 1) и order(:, 2) содержат повторяющиеся значения от 1 до 16, а order(:, 3) содержит повторяющиеся значения 1 и 2. Мне нужно перетасовать матрицу, не допуская повторения более чем три одинаковых значения в последнем столбце, поэтому order(:, 3) никогда не должен показывать более 3 повторений 1 или 2.

Это то, что у меня есть, которое отлично работало для меньшей версии матрицы, но, кажется, застревает с немного большей матрицей:

not_good = true;

while not_good

    not_good = false;

    order = Shuffle(order);

    % returns an array of 1s and 0s indexing the position of the values for 1 and 2
    R1 = order(:, 3) == 1;
    R2 = order(:, 3) == 2;

    % checks for repeats, returns 1 if repeats are present
    rep_test1 = any(diff([1; find(R1)])>3);
    rep_test2 = any(diff([1; find(R2)])>3);

    if rep_test1 > 0 || rep_test2 > 0
        not_good = true;
    end
end

Любые комментарии очень ценятся. Спасибо.


person Lau    schedule 21.09.2012    source источник
comment
1) В некоторых случаях это невозможно. Например, когда все order(:,3) равны. 2) Вы хотите, чтобы перетасовка была случайной? 3) Это домашнее задание?   -  person Oli    schedule 21.09.2012
comment
Спасибо за совет, не домашнее задание, а эксперимент.   -  person Lau    schedule 25.09.2012


Ответы (2)


Учитывая, что вы уже нашли договоренность, которая соответствует вашим условиям. Но должна быть возможность построить такое расположение.

Я бы сделал перетасовку с помощью выборки отклонения.

Псевдокод будет:

function shuffled = shuffle(orig)
for i=1:numShuffles
  [i1,i2] = randomIndices;
  tmp = shuffled with permuted lines i1 and i2 
  test if matrix is still valid
  if valid shuffled=tmp;
end
person bdecaf    schedule 21.09.2012
comment
Спасибо за информацию ре. браковочная выборка! - person Lau; 25.09.2012

Если у вас есть какой-либо низкоуровневый контроль над реализацией функции Shuffle, наиболее эффективно сделать ее реализацию для конкретной задачи. Например, сделайте версию, которая сразу отбрасывает неразрешимые проблемы и отклоняет любое новое дополнение к выходной матрице внутри цикла, если оно равно двум элементам над ним.

Но если предположить, что у вас нет такого уровня контроля, я должен согласиться с @Oli. В вашем коде нет внутреннего изъяна, ему просто не хватает проверок, чтобы увидеть, решаема ли проблема вообще или нет.

Хотя у него есть существенный недостаток. Например, если

order(:,3).' = [1 1 2 1 1 2 1 1 2 1 1 2 1 1 2 ...]

шансы получить (более) трех последовательных после Shuffle будут довольно большими. Это означает, что цикл должен будет выполняться большое количество раз, прежде чем он даст какой-либо результат. К сожалению, если проблема решаема, но просто «сложно решить», как в этом случае, вы мало что можете сделать, кроме как ждать.

person Rody Oldenhuis    schedule 21.09.2012