Javascript-форум (https://javascript.ru/forum/)
-   Ваши сайты и скрипты (https://javascript.ru/forum/project/)
-   -   Случайная пересортировка массива (https://javascript.ru/forum/project/27758-sluchajjnaya-peresortirovka-massiva.html)

9xakep 23.04.2012 23:16

Случайная пересортировка массива
 
Понадобилось сделать этакую штуку, решил сюда выложить:
var m = [1, 2, 3, 4, 5, 6]
  var done = m.slice()
  

  function resort(arr1) {
   var did = []

    sort1()

    function sort1() {
      var i = 0;
      do {

        var r1 = Math.random() * m.length | 0
        var r2 = Math.random() * m.length | 0
        var m1 = arr1[r1]
        var m2 = arr1[r2]
        arr1[r1] = m2
        arr1[r2] = m1
        did.push(r1)
        did.push(r2)
        i += 2

      } while (i != 6)
    }
  }


  function doCheck(arr3, arr4) {
    var repeat = 0;
    var max_repeat = Math.floor(arr4.length * 0.75)
    for (i = 0; i < arr3.length; i++) {
      for (k = 0; k < arr4.length; k++) {
        if (arr3[i] == arr4[k]) {
          ++repeat
          break;
        } else continue;
      }
    }
    if (repeat >= max_repeat) {
      resort(arr3)
    }
  }
  resort(m) // пересортировываем нужный массив
  doCheck(m, done) /* для параноиков проверяем, не получился ли массив похожим с исходным, для этого вначале нужно создать массив аналогичный исходному:var done = m.slice() */
  alert(m) // результат
  alert(done) // исходный массив

Скрипт конечно не доработан для общего пользования :) Но в будущем можно будет сделать как методы Array :victory:

B~Vladi 23.04.2012 23:35

Мсье знает толк в извращениях?
alert([1,2,3,4,5,6,7,8,9,0].sort(function () {
  return Math.round(Math.random()) * 0.5;
}));

devote 23.04.2012 23:38

Цитата:

Сообщение от B~Vladi
Мсье знает толк в извращениях?

дауж я тоже сижу и смотрю в его код и думаю, что же там такого нового и отличающего от стандартного метода сортировки :)

9xakep 24.04.2012 00:04

если бы я еще знал этот способ, до написания скрипта =/ Да ну вас, у вас способ скучный :D
=============
Цитата:

Мсье знает толк в извращениях?
где-то я это уже слышал, только в каком посту не помню

B~Vladi 24.04.2012 00:16

Цитата:

Сообщение от 9xakep
где-то я это уже слышал

Частенько проскакивает в интернетах :)

Kolyaj 24.04.2012 01:03

B~Vladi,
не надо так перемешивать http://alljs.ru/articles/array/sort#shuffle

Gvozd 24.04.2012 01:32

Цитата:

Сообщение от B~Vladi
Мсье знает толк в извращениях?

А мне ваше решение кажется извращением, ведь на выходе получается далеко не случайный массив ;)

А вот и код для тестирования результата на случайность, и заодно мой вариант функции сортировки

var test_count = 100000;
var test_result;
var array = [1, 2, 3];

test(resort1);
console.log('=========');
test(resort2);
console.log('=========');
test(resort3);

function test(func) {
	test_result = {};
	for(var i = 0; i < test_count; i++) {
		var arr = array.slice();
		func(arr);
		if(test_result[arr] == undefined) {
			test_result[arr] = 0;
		}
		test_result[arr]++;
	}
	var test_list = [];
	for(var i in test_result) {
		test_list.push([i,test_result[i]]);
	}
	min = max = test_result[i];
	test_list.sort(function(a,b) {
		min = Math.min(min, a[1], b[1]);
		max = Math.max(max, a[1], b[1]);
		return a[0] < b[0] ? -1 : 1;
	});
	for(var i =0; i< test_list.length; i++) {
		console.log(test_list[i][0] + ': ' + test_list[i][1]);
	}
	console.log([min, max]);
}

function resort1(arr1) {
    var did = []
    sort1()
    function sort1() {
		var i = 0;
		do {
			var r1 = Math.random() * arr1.length | 0
			var r2 = Math.random() * arr1.length | 0
			var m1 = arr1[r1]
			var m2 = arr1[r2]
			arr1[r1] = m2
			arr1[r2] = m1
			did.push(r1)
			did.push(r2)
			i += 2
		} while (i != 6)
	}
}
function resort2(arr1) {
	arr1.sort(function () {
	  return Math.round(Math.random()) * 0.5;
	});
}
function resort3(arr) {
	var new_arr = [0,0];
	for(var i = 0, s = arr.length; i < s; i++) {
		new_arr.push(arr.splice(Math.floor(Math.random()*(s-i)), 1)[0]);
	}
	arr.splice.apply(arr, new_arr)
}

И примеры полученных результатов(для краткости только min/max)
Цитата:

[14707, 18513]
[12399, 25029]
[16548, 16731]
наиболее равномерное распределение у моего варианта.
И к тому же достаточно очевидно, что распределение будет статистически равномерным(при условии статистической равномерности Math.Random)

А вот для второго кода из топика вполне очевидно, что он может дать равномерное распределение только для массива из двух элементов.
Для большего количества - распределение будет неравномерным, и при этом будет зависеть от браузера(от реализации сортировки в нем), потому что сравниваться будет далеко не все элементы со всеми, и в случае с быстрой сортировкой количество перестановок будет стремится к минимально возможному

Gvozd 24.04.2012 01:34

Kolyaj,
ну, вот.
Только отвлечешься чуть наваять тестирующую систему, да свой вариант случайной сортировки, а на эту тему уже статью написал :D

B~Vladi 24.04.2012 01:51

Цитата:

Сообщение от Gvozd
А мне ваше решение кажется извращением, ведь на выходе получается далеко не случайный массив

Это уже на совести реализаций, как они получают "случайное" число. Зато по коду всё понятно.
Мне известно, что процессор в принципе не может генерировать случайные числа. Только сегодня читал статью про Battle Sity - можно применить подобное решение с несколькими величинами.

9xakep 24.04.2012 07:46

Gvozd,
Что делает функция test?
B~Vladi,
Цитата:

Частенько проскакивает в интернетах :)
Вспомнил от трикадина слышал такое)


Часовой пояс GMT +3, время: 19:52.