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, Судя по его игнору всей этой "высокой материи", так оно и есть.)) |
Часовой пояс GMT +3, время: 17:58. |