Страницы: 1
RSS
Генерация случайных чисел заданной суммы
 
Добрый день, стоит такая задача :
сгенерировать произвольное кол-во строк случайных чисел от 1-1000, но так что бы их сумма была равна заданному числу.Помогите плис с макросом.
 
http://www.planetaexcel.ru/forum/index.php?PAGE_NAME=read&FID=8&TID=22953
 
предлагаю такой вариантик)))

обнаружил что работает безотказно когда искомое число не более 1 000 - если число выше, и чем выше, тем меньше попаданий но при <=1000 попадание генераций 100%
Изменено: marker_mc - 17.05.2013 01:52:18
 
marker_mc, уж не в этой ли строчке дело - "For r = 1 To 15"?

вот мой вариант разбивки (правда условие чуть чуть другое), но работает шустро
Изменено: ber$erk - 17.05.2013 08:39:43
Учимся сами и помогаем другим...
 
ber$erk, дело то в этой строчке, но на что заменить to 15 у меня знаний не хватило))))

Посмотрел Ваш вариант. Да, реально работает шустрее но есть два НО.
1. почему то иногда проскакивают отрицательные числа.
2. Следует делать очистку строки, поскольку при генерации данных на меньшее количество элементов, ряд данных предыдущего рандома остается.
Изменено: marker_mc - 17.05.2013 10:04:53
 
строго говоря  - это невозможно..

но можно получить n случайных чисел суммой меньше заданной, а последнее задать как разницу между заданной и суммой n
Живи и дай жить..
 
Прошу прощения, но видимо не правильно сформулировал задачу :
Вообщем есть сумма скажем 729 898
Необходимо генерить случайные числа в заданном диапазоне от 1-1000 до тех пор пока их сумма не будет максимально приближенной ( в идеале конечно же равной ) заданной. Сколько получится число членов ряда не важно.
Изменено: romarioageos - 17.05.2013 10:07:03
 
Цитата
romarioageos пишет: Прошу прощения, но видимо не правильно сформулировал задачу :
Вообщем есть сумма скажем 729 898
а что вас тогда смущает, вариант который предложил ber$erk вполне справился с этой задачей. Установил сумму ту что вы написали, поставил количество элементов 1000, все сработало.
 
Цитата
Слэн пишет: ...но можно получить n случайных чисел суммой меньше заданной, а последнее задать как разницу между заданной и суммой n
Да , вроде бы правильно
 
Цитата
marker_mc пишет:
который предложил ber$erk вполне справился с этой задачей. Установил сумму ту что вы написали, поставил количество элементов 1000, все сработало.
Вы меня не поняли, кол-во элементов, не 1000, а произвольное кол-во, сколько получится столько и получиться, 1-1000- это диапазон значений которое может принимать случайное число . Т.е числа генерируются до тех пор пока их сумма не будет равна заданой
 
щас подправлю свой вариант
Учимся сами и помогаем другим...
 
Так тогда задача простая - генерим и суммируем, считаем - как только разница суммы и суммы <=1000 - это и есть последнее число.
 
вариант для обоих случаев: когда количество числе указано, и когда оно произвольно
Учимся сами и помогаем другим...
 
Спасибо огромное , волшебно работает, только очень долго, если цифра большая . Но видимо способа сделать процесс мгновенным не существует?
 
Попаразитировал на Генерация суммы из случайных чисел.xlsm....
Код
Sub tt()
    Dim k As New Collection

    Dim rndStart As Long, rndFin As Long, i As Long, Summa As Long, SummaFin As Long, rndVal As Long


    [G:G].ClearContents
    rndStart = [B2]
    rndFin = [B3]
    Summa = [B4]

    Randomize
    SummaFin = 0

    Do While Summa - SummaFin > rndFin
        rndVal = Int((rndFin - rndStart + 1) * rnd + rndStart)
        SummaFin = SummaFin + rndVal
        k.Add rndVal
    Loop
    k.Add Summa - SummaFin


    ReDim b(1 To k.Count, 1 To 1)
    For Each el In k: i = i + 1: b(i, 1) = el: Next
    [g1].Resize(k.Count, 1) = b
End Sub
 
Классно, коллекция реально быстрее работает. А я тут с массивами че-та ковыряю  :)
Учимся сами и помогаем другим...
 
Мне только не нравится этот переклад из коллекции в массив, чтоб на лист вывалить... Но другого способа не помню, искать неохота. А может и нет другого...
 
из массива в диапазон вывалить разом все данные я тоже не могу. Может просто я чего то не знаю?  :)
Учимся сами и помогаем другим...
 
Так вот же:
Код
[g1].Resize(k.Count, 1) = b

Вместо  k.Count можно писать ubound(b)
Но массив должен быть двумерным.
 
вот с массивом, по скорости одинаково:

Код
Sub ttt()
    Dim k As New Collection

    Dim rndStart As Long, rndFin As Long, i As Long, Summa As Long, SummaFin As Long, rndVal As Long
    Dim ar, t!
    t = Timer
    Range("b8", Cells(8, Columns.Count).End(xlToLeft).Offset(, 1)).ClearContents
    rndStart = [B2]
    rndFin = [B3]
    Summa = [B4]

    Randomize
    SummaFin = 0
    ReDim ar(1 To 1, 1 To 9)
    On Error GoTo er
    Do While Summa - SummaFin > rndFin
        rndVal = Int((rndFin - rndStart + 1) * rnd + rndStart)
        SummaFin = SummaFin + rndVal
        i = i + 1
        ar(1, i) = rndVal
    Loop
    i = i + 1
    ar(1, i) = Summa - SummaFin


    [b8].Resize(, UBound(ar, 2)) = ar
    [f1] = Timer - t
    Exit Sub
er:
    ReDim Preserve ar(1 To 1, 1 To UBound(ar, 2) + 9)
    ar(1, i) = rndVal
    Resume Next
End Sub
Живи и дай жить..
 
а можно то же самое, только чтобы результат отображался не в строку, а в столбик?
 
Цитата
ber$erk написал:
вариант для обоих случаев: когда количество числе указано, и когда оно произвольно

Отлично, я нашёл почти то, что нужно! Осталось пара нюансов. Боюсь, конечно, что никто спустя столько лет не увидит даже активность в теме, но не хотелось бы открывать новую тему, когда есть уже эта. Вариант ber$erk очень может подойти для моей задачи после доработки. Я правда не понял, потом то что Hugo и Слэн предлагали, увы, я только могу открыть excel и пользоваться, как паразит, пробовал вставлять их коды, заменяя код ber$erk, но сразу же переставало работать, но думаю там суть та же, там работали над скоростью. Итак, что же мне не хватает:
Не должно быть отрицательных чисел в генерации.
Не должны быть повторы в одной строчке генерации (то есть 10=2+2+5+1 — такой вариант не подходит).
И вот что самое главное: возможность добавлять числа исключения, то есть чтобы при генерации, какие то числа не выпадали.

Дело в том что у меня ячейки, допустим, от 1 до 320. Мне нужно разложить 1000 на 10 чисел. Выставляю эти параметры: 1000 финальная сумма, 10 чисел, минимум 1, максимум 320, оно распределило

2057360322329542434151
я эти ячейки закрыл (зачеркнул), через неделю нужно повторить, но уже не трогая зачеркнутые ячейки.

Ну и при невозможности операции выдавать какую то ошибку или что то такое. В имеющемся коде невозможности операции быть не может, так как отрицательные числа есть и повторы возможны).

Спасибо за внимание.
 
так?
Программисты - это люди, решающие проблемы, о существовании которых Вы не подозревали, методами, которых Вы не понимаете!
 
прикольно. Давно я здесь не был. а дело мое живет :-)
Учимся сами и помогаем другим...
 
в моем случае это тупиковое ответвление полностью на формулах
Программисты - это люди, решающие проблемы, о существовании которых Вы не подозревали, методами, которых Вы не понимаете!
 
Цитата
Ігор Гончаренко написал:
так?
О, спасибо за оперативность! Так и не догнал, что означает значение в ячейке D5 (понял только, что оно никогда не выше количества чисел), а иногда появляется в E5. При клацании на F9 у меня один раз в столбце генириуемых чисел вышел 0 почему то, хотя минимум 1 установлен.  Выставил количество чисел 5, у меня суммы выше установленного макс 320 через раз выскакивают. Как я понял, в ячейке E5 выскакивает значение (0.хххх), когда как раз таки выходит число выше максимума или 0. Так же ставил количество чисел 2, то есть создал невозможное условие (сумма 1000, а генерируемые числа не должны превышать 320), оно генерирует, а не выдает ошибку. И ещё не нашел куда вставлять числа исключения (это вот самая главная просьба). Вот что пока довелось выяснить.  
Изменено: elimbony - 26.02.2021 16:59:58
 
на желтом фоне формулы, их желательно не поломать (как и в первых 3-х колонках, А и В скрыты)
система с "минимумом мозгов"
на данных имеющих множество решений должна генерировать все новые и новые случайные варианты с каждым нажатием F9
Программисты - это люди, решающие проблемы, о существовании которых Вы не подозревали, методами, которых Вы не понимаете!
 
То есть то что отображается в ячейке D5 — не объяснимо, не забивать себе голову? Ну в E5 как я понял значение выходит, если ошибка только.
На счет всё новых и новых генераций это конечно здорово, но не в конкретно моём случае, так как у меня уже какое то количество ячеек закрыто, плюс сумма будет меняться, не всегда 1000. А я хотел добавить уже закрытые ячейки в исключения, сгенерировать, полученные генерацией числа-ячейки закрыть, сразу же добавить их в исключения, и так далее. Плюс с этими ячейками не только я работаю, то есть некоторые ячейки помимо меня в хаотичном порядке закрывают, так что через неделю я прихожу и проверяю, что изменилось с моего последнего ухода, то есть так же новые закрытые добавлял бы в исключения)
 
история та же...
я рещаю ту задачу, которую понял
указано 4 параметра: количество чисел, сумма чисел, минимальное и максимальное число
задача:
случайным образом подобрать указанное количество чисел так чтобы:
1. числа не повторялись
2. их сумма равнялась бы заданной сумме
3. числа не должны выходить за рамки заданных мин. и макс. значений
если формулу в Е5 заменить на такую
Код
=ЕСЛИ(ИЛИ(D1<>F1;D3<F3;D4>F4);"Нажми F9!";"")
и соотв. если в Е5 написано Нажми F9! - значит какое-то из условий не соблюдено, и нужно нажать F9

и
в моем решении, закроете файл, откроете а все числа уже другие...
потому что я не знаю какую задачу вы решаете и зачем вам нужны эти числа
Изменено: Ігор Гончаренко - 26.02.2021 18:07:24
Программисты - это люди, решающие проблемы, о существовании которых Вы не подозревали, методами, которых Вы не понимаете!
 
Ок, на счёт Е5 всё понятно.

Цитата
Ігор Гончаренко написал:
потому что я не знаю какую задачу вы решаете и зачем вам нужны эти числа

Сейчас объясню на примере. Вот есть поле https://prnt.sc/107p1sa
Цвета закрашенных ячеек не важны, это просто закрытые ячейки.
Итак, мне, например, на 7 дней (может 10 дней, не важно, но в данном примере возьмём 7) дали 800 фантиков (пускай будут фантики, опять же сумму могут дать иную). Нужно распределить их. Ввожу данные https://prnt.sc/107p4on . Получаю генерацию, перехожу в свою таблицу, заполняю, например, красным цветом, вот что вышло https://prnt.sc/107p5v1 . Отлично! Но сами понимаете, это мне повезло, ни одна ячейка не была занята. Но в следующий раз попадется, что ячейка будет занята, а со временем будет всё меньше свободных ячеек.
Так то Вы мне уже помогли, даже если ничего сделать нельзя, я буду пользоваться, пока это будет эффективно. Просто может действительно интересно, но не понятно, как я объясняю, поэтому вот пример. Если не понятно, спрашивайте.  
Изменено: elimbony - 26.02.2021 19:13:48
Страницы: 1
Наверх