Страницы: 1
RSS
Случайные числа в диапазоне
 
Выручайте!  
Ну никак не могу сообразить как это можно сделать:  
Необходимо сгенерировать диапазон случайных целых чисел в пяти ячейках чтобы сумма пяти ячеек была равна 13  
 
Заранее благодарен!
 
Вопрос, я так понимаю, в алгоритме.  
Можно сгенерировать 4 случайных целых числа в заданном диапазоне.  
А пятое число вычислить как 13 минус сумма четырех случайных целых.
 
{quote}{login=ZVI}{date=29.12.2010 04:24}{thema=}{post}Вопрос, я так понимаю, в алгоритме.  
Можно сгенерировать 4 случайных целых числа в заданном диапазоне.  
А пятое число вычислить как 13 минус сумма четырех случайных целых.{/post}{/quote}  
Ну тогда не совсем случайно будет... :)  
Дело в том, что нужно сгенерировать таких 15*60 групп по 5 цифр.... И если внимательно приглядеться то вычислить закономерность можно.. Может я не совсем верно поставил вопрос :) Я имел в виду как это сделать по-человечески, а не например так:  
 
=ЕСЛИ(C2<9;ЕСЛИ(C2<8;ЕСЛИ(C2<7;ЕСЛИ(C2<6;ЕСЛИ(C2<5;ЕСЛИ(C2<4;ЕСЛИ(C2<3;ЕСЛИ(C2<2;3;СЛУЧМЕЖДУ(1;8));СЛУЧМЕЖДУ(1;7));СЛУЧМЕЖДУ(1;6));СЛУЧМЕЖДУ(1;5));СЛУЧМЕЖДУ(1;4));СЛУЧМЕЖДУ(1;3));СЛУЧМЕЖДУ(1;2));1)  
 
В любом случае вопрос уже решил на C а получившиеся результаты закачал в Excel... Но тем не менее спасибо :)
 
Теперь понятно, что устроит VBA-код, а не формула.  
Уточните ещё, в каком диапазоне должны быть целые числа, ведь без ограничений они могут оказаться и отрицательными.
 
Решение от MCH: http://www.planetaexcel.ru/forum.php/?thread_id=22252
 
Напросился такой алгоритм:  
В случайную позицию массива добавлять по единичке до набора необходимой суммы.  
Пример кода приведен ниже, его не сложно переделать в функцию или расширить для многомерного массива.  
 
Sub RndArray_WithDefinedSum()  
   
 Const MinVal& = 1  
 Const MaxVal& = 7  
 Const SumVal& = 13  
 Const DestCell = "A1"  
   
 Dim a&(1 To 5), i&, j&, LB&, UB&  
 LB = LBound(a)  
 UB = UBound(a)  
   
 ' Добавлять по единичке в случайную позицию массива, пока не достигнуто SumVal  
 Randomize  
 For i = 1 To SumVal  
   j = Int((UB - LB + 1) * Rnd + LB)  
   a(j) = a(j) + 1  
 Next  
   
 ' Записать результат  
 Range(DestCell).Resize(, UB - LB + 1).Value = a()  
   
 ' Для отладки  
 Dim sum  
 For i = LB To UB  
   Debug.Print a(i);  
   sum = sum + a(i)  
 Next  
 Debug.Print "Total:"; sum  
   
End Sub
 
Эти строки кода лишние:  
Const MinVal& = 1  
Const MaxVal& = 7
 
или так:  
 
Sub t()  
Dim r&, arr(1 To 5, 1 To 1), s!, i&, dn!, dk!  
On Error GoTo er  
s = 13: dn = 0: dk = 12  
   Randomize  
   r = Fix(Rnd * 5! - 0.000001!) + 1  
   For i = 1 To 4  
       arr(i, 1) = dn + Fix(WorksheetFunction.Min((dk - dn + 1), s) * Rnd)  
       s = s - arr(i, 1)  
   Next  
   If r < 5 Then arr(5, 1) = arr(r, 1)  
   arr(r, 1) = s  
   [a1].Resize(5) = arr
   Exit Sub  
er: Resume Next  
End Sub
Живи и дай жить..
 
{quote}{login=слэн}{date=29.12.2010 09:40}{thema=}{post}или так:  
   For i = 1 To 4  
       arr(i, 1) = dn + Fix(WorksheetFunction.Min((dk - dn + 1), s) * Rnd)  
       s = s - arr(i, 1)  
   Next  
End Sub{/post}{/quote}  
а не окажемся ли мы в ситуации Арамиса, чьи шансы убить Д'Артаньяна были существенно меньше чем у Атоса?  
 
То есть если мы бросаем шарики вначале в первую коробку, оставшиеся во вторую и т.д,    
То нам следует перемешать наши коробки, иначе 12 в первой будут вcтречаться, гораздо чаще чем во второй, а пятая вобще будет на шариковой диете...  
 
итого: одной случайной перестановки коробок не достаточно.
 
пожалуй..
Живи и дай жить..
 
тогда так:  
 
Sub t2()  
Dim r&, arr(1 To 5, 1 To 1), s!, i&, dn!, dk!, cl As New Collection  
On Error GoTo er  
s = 13: dn = 0: dk = 12  
   Randomize  
   For i = 1 To 4  
       cl.Add dn + Fix(WorksheetFunction.Min((dk - dn + 1), s) * Rnd), CStr(i)  
       s = s - cl(cl.Count)  
   Next  
   cl.Add s, "5"  
   For i = 5 To 1 Step -1  
       r = Fix(Rnd * i - 0.000001!) + 1  
       arr(i, 1) = cl®  
       cl.Remove ®  
   Next  
   [a1].Resize(5) = arr
   Exit Sub  
er: Resume Next  
End Sub
Живи и дай жить..
 
вот за это я Вас Слэн не только уважаю,  
но и Вам завидую :)
 
за что, уважаемый DL?  :)  
 
извращаюсь ведь, zvi проще.  
 
хотя если будет не 13, а поболе, то можно посмотреть..
Живи и дай жить..
Страницы: 1
Читают тему
Наверх