Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Алгоритм жеребьёвки (https://javascript.ru/forum/misc/37331-algoritm-zherebjovki.html)

DJZT 16.04.2013 01:14

Алгоритм жеребьёвки
 
Задача написать генератор жеребьёвки для турниров. То есть надо сопоставить первые пары.
Алгоритм таков, что генерируем число от 1 до 16 и проверяем его в массиве arr. Если не найдено - запишем в исключающий массив arr и в массив первых команд в паре mas1.
Аналогично и для вторых команд пары. и так прохожу 16 раз, пока не заполнятся все массивы mas1 mas2.

В исключающий массив arr пишет всё подряд без разбора, хоть оно даже там и есть уже.

Код:

<div class = "zad">
        <h1>Задача 7</h1>
        <p>Реализовать программу "Генератор жеребьёвки"</p>
        <form name = "inf">
                <input type = "text" value = "16" name = "k_kom">
                <input type = "button" value = "Сгенерировать"
onClick = "generation()">
        </form>
        <script type="text/javascript">
       
function generation(){
		//debugger;
		var arr = [100, 101];
		var mas1 = [];
		var mas2 = [];
		var ch1 = 0;
		var ch2 = 0;
		var min = 1;
		var max = inf.k_kom.value;
		for(var k = 0;k<=16;k++){
		M1:{
			ch1 = Math.round((Math.random() * (max - min) + min));
			for(var i in arr){
				if(arr[i] == ch1){
					break M1;
				}else{
					arr.push(ch1);
					mas1.push(ch1);
				}
			}
		}
		M2:{
			ch2 = Math.round((Math.random() * (max - min) + min));
			for(var i in arr){
				if(arr[i] == ch2){
					break M2;
				}else{
					arr.push(ch2);
					mas2.push(ch2);
				}
			}

		}
	}
	print(mas1);
	print(mas2);
}
	generation();

        </script>
</div>


rgl 16.04.2013 18:02

И в чем вопрос?
Надо отладить скрипт и исправить ошибки? Или же подсказать лучшее решение?
Ну для начала скажу, что выбрать случайное число в диапазоне min - max нужно не так. Ваш алгоритм плохой, т.к. вероятность выпадения min или max в два раза меньше, чем других чисел. Вот, взгляните:
var min = 1, max = 10, r, i, rCount = Array(max-min+1);

for( i = 0; i < rCount.length; ++i )
  rCount[i] = 0;

for( i = 0; i < 100000; ++i ) { // считаем количество выпадений
  r = Math.round((Math.random() * (max - min) + min));
  ++rCount[ r - min ];
}

for( i = 0; i < rCount.length; ++i ) // считаем вероятности
  rCount[i] /= 100000;

alert( rCount );

А вот если вместо
Math.round((Math.random() * (max - min) + min)) ;
написать
Math.floor( Math.random() * (max-min+1) + min ) ;
то шансы уровняются.

rgl 16.04.2013 18:19

Вот вам алгоритм:
var min = 1, max = 16, r, i, tmp, mas = Array(max-min+1);

for( i = 0; i < mas.length; ++i ) // заполняем массив номерами команд
  mas[i] = i+min;

for( i = 0; i < mas.length; ++i ) { // тасуем
  r = Math.floor( Math.random() * (max-min+1) );
  tmp = mas[i];
  mas[i] = mas[r];
  mas[r] = tmp;
}
// Внимание, нет никакой защиты на случай, если количество команд нечетное.

for( i = mas.length - 2; i >= 0; i -= 2 ) // группируем попарно
  mas.splice( i, 2, [ mas[i], mas[i+1] ] );

alert( mas.join( "\n" ) );

dima*** 16.04.2013 20:56

DJZT-а тебе для чего?
Просто,есть файл в excel,где есть календари на любое количество команд.Просто,вписываешь название команд и календарь готов.Или тебе другое нужно?

рони 16.04.2013 21:59

Вариант...
var max = 16, arr = [];
max++;
while (--max) {
  var i = arr.length;
  var num = Math.floor(Math.random() * (++i));
  arr.splice(num, 0, max);
}
alert(arr.join(",").match(/\d+,\d+/g).join("\n"))

rgl 17.04.2013 00:11

рони,
!!!!!!!!!!!!!!!!!!!!!!!!!!!
Хотя......

rgl 17.04.2013 00:31

Цитата:

Сообщение от rgl (Сообщение 246591)
рони,
Хотя......

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

rgl 17.04.2013 01:08

Цитата:

Сообщение от рони (Сообщение 246559)
Вариант...
var max = 16, arr = [];
max++;
while (--max) {
  var i = arr.length;
  var num = Math.floor(Math.random() * i);
  arr.splice(num, 0, max);
}
alert(arr.join(",").match(/\d+,\d+/g).join("\n"))

var max = 16, arr = [];
max++;
while (--max) {
  var i = arr.length;
  var num = Math.floor(Math.random() * (i+/*!!!!!!!!*/1));
  arr.splice(num, 0, max);
}
alert(arr.join(",").match(/\d+,\d+/g).join("\n"))


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