Перемешать строки таблицы Фишера – Йейтса

Я намерен использовать перетасовку Фишера-Йейтса для перетасовки существующих строк данной таблицы, например:

<table>
    <tbody id="parent">
        <tr id="node1">
            <td>1</td>
            <td>A</td>
        </tr>
        <tr id="node2">
            <td>2</td>
            <td>B</td>
        </tr>
        <tr id="node3">
            <td>3</td>
            <td>C</td>
        </tr>
        <tr id="node4">
            <td>4</td>
            <td>D</td>
        </tr>
        <tr id="node5">
            <td>5</td>
            <td>E</td>
        </tr>
        <tr id="node6">
            <td>6</td>
            <td>F</td>
        </tr>
    </tbody>
</table>

С некоторой помощью JQuery у меня есть следующее:

var parent = $("#parent");

function shuffleRows(parent) {
    var rows = parent.children();
    for (var i = rows.length - 1; i > 0; i--) {
        var j = Math.floor(Math.random() * (i + 1));
        var temp = rows[i];
        rows.eq(i - 1).after(rows[j]);
        rows.eq(j - 1).after(temp);
    }
}

shuffleRows(parent);

Рабочий пример здесь: http://jsfiddle.net/98q9S/.

Однако, когда я проверяю вышеизложенное, я не могу не заметить, что строка A занимает первое место гораздо чаще, чем другие строки, а иногда два последовательных перетасовки дают точную последовательность строк.

Интересно, есть ли что-то не так в моей реализации, или это просто размер моей выборки слишком мал.


person MLister    schedule 17.10.2013    source источник
comment
как закодировано, вероятность замены последней строки составляет 1/6. шансы на обмен в первом ряду равны 5/6. было бы лучше захватить их все, перетасовать, а затем применить повторно, цикл не нужен.   -  person dandavis    schedule 17.10.2013


Ответы (1)


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

makeArrRandom = function(array) {

  var counter = array.length, temp, index;
  while (counter > 0) {
    index = Math.floor(Math.random() * counter);
    counter--;
    temp = array[counter];
    array[counter] = array[index];
    array[index] = temp;
  }
  return array;
};
person ezis    schedule 17.10.2013
comment
@eizs, спасибо. а чем ваш отличается от моего? Ваше решение в основном меняет цикл for на цикл while. - person MLister; 17.10.2013
comment
В моем есть одно дополнительное действие. Кроме того, каждая позиция перемешивается. - person ezis; 17.10.2013