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, время: 15:11. |