Maxmaxmахimus,
Та вообще зависимость факториальная - но имхо нун рыть в сторону рядов - что-то мне напоминает Ко всему прочему - мон найти вариации делителей всех чисел до 100, этого должно хватать для боль мень равномерной статистики и оценки при непопадании на простые числа(ну и их комбинации |
Прошу прошения, если данный варинат уже был, распределяю добавки к минимальному значению.
Последнее число, в принципе, и не может быть случайным по самой формулировке задачи (оно закономерно является разницей расчленяемого числа и суммы предыдущих полученных чисел). <script> window.onload = function () { function f(num, part, min) { if (num / part < min) { alert('не реально'); return; } var rest = num - min * part; var mas = []; var elem = 0; for (var i = 1; i < part; i++) { elem = Math.round(rest * Math.random()); mas.push(min + elem); rest -= elem; } mas.push(min + rest); alert(mas); } f(130, 3, 20) } </script> |
Есть мысля рекурсивно дробить число на две рандомные половики пока не получится нужное количество частей, но тестить сейчас лень.)
|
bes,
Вроде родил идентичное Вашему: <style type="text/css">input{margin:4px;}</style> <script type="text/javascript" src="http://yandex.st/jquery/1.4.4/jquery.min.js"></script> <input id=Number type="text" value="100" > Число <br /> <input id=Nparts type="text" value="4" > Кол-во разбиваемых частей<br /> <input id="Min-a" type="text" value="1" > Минимальное значение каждой части<br /> <input id="Out-2" type="text" size="35" value=""> Выходной массив разбивки <br /> <input type="button" value="Разбить" onClick="TstNum()"> <script type="text/javascript"> function TstNum(){ var a = parseInt($('#Number').val()); var b = parseInt($('#Min-a').val()); var N = parseInt($('#Nparts').val()); //alert(a+'||'+b+'||'+N) var Arr = []; var Summ = 0; for(var i=0; i<N; i++){ Arr[i] = Math.random(); Summ+=Arr[i]; } var DELTA_FromParts = (a - b*N); var Ost = a; for(var i=0; i<N-1; i++){ Arr[i] = b + parseInt((DELTA_FromParts*Arr[i])/Summ) Ost-= Arr[i]; } Arr[N-1] = Ost; //alert(Arr); b=Arr.join();c=eval(Arr.join('+')); $("#Out-2").val(b+'='+c); } </script> |
<div id="div"> <input value="130"> Число <br> <input value="3"> Количество частей <br> <input value="20"> Минимальное значение части<br> <input type="button" value="Разбить"> </div> <script> window.onload = function () { function f(num, part, min) { if (num / part < min) { alert('не реально'); return; } var rest = num - min * part; var mas = []; var elem = 0; for (var i = 1; i < part; i++) { elem = Math.round(rest * Math.random()); mas.push(min + elem); rest -= elem; } mas.push(min + rest); alert(mas); } function check (elem) { if (isNaN(elem) == false && elem.value != '') { return true; } else { return false; } } var div = document.getElementById('div'); div.children[6].onclick = function () { var num = parseInt(div.children[0].value); var part = parseInt(div.children[2].value); var min = parseInt(div.children[4].value); if (check(num) && check(part) && check(min)) { f (num, part, min); } else { alert('в полях есть не число') } } } </script> PS: добавил поля для ввода |
Увидел разницу
bes, берёт рандом от остатка за вычетом предыдущего рандома, - что не айс - поскольку увеличивает вероятность больших размеров для первых элементов деления и уменьшает для конечных. я же беру рандом для всех частей, с последующим нормированием каждого на общую сумму рандомов - что обеспечивает независимость каждой части |
Deff, у меня распределение настолько случайно, насколько случайна сама Math.random() :) (+ только в том, что это делается за part (количество частей) шагов без лишних проверок)
Цитата:
|
Цитата:
Оки - вызови функцию 100 раз и запиши среднее арифметическое для 1-й;2-й; и 3-й доли - они будут убывать! Параметры разделения и начальных условий - не меняем |
Deff, 100 раз не тестил (не до этого :) ), если не нормально, ок, верю, оставляю только первую фразу
Цитата:
|
Цитата:
|
bes,
Тест ( Выбрал 0 минимум и более 4 частей - для максимального разброса <div id="div"> <input value="999"> Число <br> <input value="9"> Количество частей <br> <input value="0"> Минимальное значение части<br> <input type="button" value="Разбить"> </div> <script> window.onload = function () { function f(num, part, min) { if (num / part < min) { alert('не реально'); return; } var rest = num - min * part; var mas = []; var elem = 0; for (var i = 1; i < part; i++) { elem = Math.round(rest * Math.random()); mas.push(min + elem); rest -= elem; } mas.push(min + rest); return mas; } function check (elem) { if (isNaN(elem) == false && elem.value != '') { return true; } else { return false; } } var div = document.getElementById('div'); div.children[6].onclick = function () { var num = parseInt(div.children[0].value); var part = parseInt(div.children[2].value); var min = parseInt(div.children[4].value); if (check(num) && check(part) && check(min)) { var arr = []; for(var j=0; j<part;j++){ arr[j]=0; } var Ntest=300000; for(var i=0; i<Ntest; i++){ var a = f (num, part, min); //alert(a) for(var j=0; j<part; j++){ arr[j]+=a[j];if(i!=0)arr[j]=arr[j]/2} } alert (arr.join('\n')) } else { alert('в полях есть не число') } } } </script> Мну тест: <style type="text/css">input{margin:4px;}</style> <script type="text/javascript" src="http://yandex.st/jquery/1.4.4/jquery.min.js"></script> <input id=Number type="text" value="999" > Число <br /> <input id=Nparts type="text" value="9" > Кол-во разбиваемых частей<br /> <input id="Min-a" type="text" value="0" > Минимальное значение каждой части<br /> <input id="Rasbitt" type="button" value="Разбить"> <script type="text/javascript"> $(document).ready(function(){ function f (a, N, b) { var Arr = []; var Summ = 0; for(var i=0; i<N; i++){ Arr[i] = Math.random(); Summ+=Arr[i]; } var DELTA_FromParts = (a - b*N); var Ost = a; for(var i=0; i<N-1; i++){ Arr[i] = b + parseInt((DELTA_FromParts*Arr[i])/Summ) Ost-= Arr[i]; } Arr[N-1] = Ost; //alert(Arr); return Arr; } $('#Rasbitt').click(function(e) { var a = parseInt($('#Number').val()); var b = parseInt($('#Min-a').val()); var N = parseInt($('#Nparts').val()); var arr2 = []; for(var j=0; j<N;j++){ arr2[j]=0 } var Ntest=300000; for(var i=0; i<Ntest; i++){ var aa = f (a, N, b); //alert(aa) for(var j=0; j<N; j++){ arr2[j]+=aa[j];if(i!=0) arr2[j]=arr2[j]/2} } alert (arr2.join('\n')) }); }); </script> |
Deff, у мну ваш код разбивал число 2 часа, да еще и числа не целые получилис
|
Hekumok,
Это не разбивка а тест среднестатистического значения каждой из трех значений разбивки на выборке 2 000 000 кликов - оно там не нужно целым первый тест формулы bes - второй - моей - надо сказать у мну секунд 15-20 работает(каждый) - частота проца 2.3 гига двух ядерка уменьшил в 20 раз |
Надо сказать, что при много значениях - рандом портицо
походу реальный рандом не более 10 000 |
Цитата:
|
Цитата:
|
Цитата:
Цитата:
Во-вторых, ничего не сказано о том, что последовательность имеет значение. А поэтому: Цитата:
Расходимость наших решений в том, что у вас количество возможных ситуаций внутри функции с учетом динамики их возникновения равно (a - m*n + n-1)! / (a - m*n)! а у меня (a - m*n + 1)^(n-1) * (n-1)! Поэтому у вас все комбинации равновероятны, а у меня нет. А вот ваша последняя функция мне понравилась. :) Я тоже решил попробовать двоичный поиск и комбинаторику, чтобы сделать все комбинации равновероятными. И хотя, ради чистоты эксперимента, в вашу функцию я нарочно не подглядывал, но всё же наши решения оказались очень похожи. Сравнение буду делать только на двоичном поиске, поэтому первый алгоритм из вашей функции я намеренно удалил. function divide (a, n, m) { // by oneguy if (n*m>a) return; var b=[], d=[], p=a-(m-1)*n-1; for (i=0; i<n-1; i++) { var c=Math.floor(Math.random()*(p-i)); var x=0, y=i; while (x<y) { var t=Math.floor((x+y)/2); if (d[t]-t>c) y=t; else x=t+1; } d.splice(x, 0, c+x); } d.push(p); b.length=0; b[0]=d[0]+m; for (i=0; i<n-1; i++) b.push(d[i+1]-d[i]+m-1); return b; } function SplitNum2 (a, n, m) { // by Дзен-трансгуманист if (n < 1 || n * m > a) { return []; } if (n == 1) { return [a]; } var i, j, q = -1, w, e; var r = a - (m * n) + n - 1; var f = Math.floor(Math.random() * r); var p = [f], s = []; for (i=1; i<n-1; i++) { if (!(i & (i-1))) { q++; } j = Math.floor(Math.random() * (r-i)); if (j < f) { f = j; p.unshift(j); continue; } w = 1 << q; e = w >> 1; while (e) { if (w > i || j+w <= p[w-1]) { w -= e; } else if (w == i || j+w < p[w]) { break; } else { w += e; } e >>= 1; } p.splice(w, 0, j+w); } p.push(r); s[0] = p[0] + m; for (i=1; i<n; i++) { s[i] = p[i] - p[i-1] + m - 1; } return s; } function testPerformance (a, n, m, iterations) { var i, j, fn, time1, time2; var fnarr = [ "divide", "SplitNum2" ]; var result = "a = " + a + "; n = " + n + "; m = " + m + "; ( " + iterations + "x )\n\n"; function Now () { return (new Date()).getTime(); } for (i=0; i<fnarr.length; i++) { fn = eval(fnarr[i]); time1 = Now(); for (j=0; j<iterations; j++) { fn(a, n, m); } time2 = Now(); result += fnarr[i] + ": " + ((time2 - time1) / 1000).toFixed(3) + " sec.\n"; } return result + "\n"; } var text = ""; text += testPerformance(130, 3, 20, 10000); text += testPerformance(130, 30, 0, 1000); text += testPerformance(100, 4, 25, 10000); text += testPerformance(1000, 1000, 0, 10); text += testPerformance(1000000000, 10000, 0, 1); alert(text); |
Дзен-трансгуманист,
:blink: Чот соврал - и пол-секунды не было (Опера 11.52 Цитата:
|
Цитата:
|
Deff,
Черт-те что. Значит у меня Опера такая хреновая. :haha: bes, Судя по его игнору всей этой "высокой материи", так оно и есть.)) |
bes,
а мну сразу подумал об алгоритме фоновой полосатости - как то была такая задача - делать фон произвольными меняющимися во времени полосками |
Deff, чем больше опыта и знаний, тем больше додумывается :)
|
Deff,
Нам готовиться к новой теме? :D |
Цитата:
|
Maxmaxmахimus,
:D Точно - - если только данные полоски не красят разным цветом (Всё вспоминаю свою задачу... |
Цитата:
Цитата:
|
Цитата:
Не знаю, но на мой взгляд, здесь подразумевается именно наличие неслучайности как таковой, то есть некая заведомая предсказуемость результатов. Будь я ТС - мне бы тоже это не понравилось.)) |
Цитата:
|
Цитата:
Кэп, выручай, это выше моих сил... ![]() |
Короче говоря, с постов ТС ясно, что случайно выбирается упорядоченный набор целых чисел заданной длины, каждое из которых не меньше заданного числа, и их сумма равна А, причём каждая из возможностей выпадает с равной вероятностью.
|
Часовой пояс GMT +3, время: 07:02. |