|
Случайная выборка | ☑ | ||
---|---|---|---|---|
0
Asmody
15.03.13
✎
09:12
|
простая задача, не могу придумать эффективного решения.
есть ТЗ, одна из колонок - Вероятность, от 0до 100. Нужно придумать функцию, которая возвращает строку ТЗ с вероятностью Вероятность/Итог(Вероятность). При этом считаем, что функция Случайное() возвращает случайное число от 0 до 100 |
|||
1
mikecool
15.03.13
✎
09:13
|
не понял, предлагаешь придумать генератор случайного числа?
|
|||
2
1C-band
15.03.13
✎
09:13
|
ГенераторСлучайныхЧисел (RandomNumberGenerator)
СлучайноеЧисло (RandomNumber) Синтаксис: СлучайноеЧисло(<НижнийДиапазон>, <ВерхнийДиапазон>) Параметры: <НижнийДиапазон> (необязательный) Тип: Число. Нижний диапазон. Задается целым числом и не может быть меньше 0. Значение по умолчанию: 0 <ВерхнийДиапазон> (необязательный) Тип: Число. Верхний диапазон. Задается целым числом и не может быть больше 4294967295 (2^32 - 1), а также меньше значения параметра <НижнийДиапазон>. Значение по умолчанию: 4294967295 Возвращаемое значение: Тип: Число. Описание: Возвращает случайное целое число в заданном диапазоне. Нижний диапазон не может быть меньше 0, а верхний диапазон не может быть больше 2^32 - 1. Доступность: Тонкий клиент, сервер, толстый клиент, внешнее соединение. Пример: ГСЧ = Новый ГенераторСлучайныхЧисел(255); ГСЧ.СлучайноеЧисло(0, 10000); |
|||
3
Asmody
15.03.13
✎
09:14
|
(1) (2) спасибо, вы задачу не читали
|
|||
4
mikecool
15.03.13
✎
09:15
|
или нужно найти строку, у которой будет
Вер/Итог(Вер) = Случайное() ? |
|||
5
1C-band
15.03.13
✎
09:15
|
(3) Итог(Вероятность) всегда будет = 1. Или я не догоняю?
|
|||
6
Asmody
15.03.13
✎
09:15
|
(4) мне нужна строка ТЗ
|
|||
7
mikecool
15.03.13
✎
09:15
|
(3) а ты сам прочитай ее, них не понятно
|
|||
8
Asmody
15.03.13
✎
09:16
|
(5) колонка Вероятность от 0 до 100
|
|||
9
dk
15.03.13
✎
09:16
|
(0) уже пятницу отмечаешь что ли? ))
если будет 3 строки с вероятностью стр 1 - 30 стр 2 - 60 стр 3 - 90 ---- какую выборку ты думаешь получить? |
|||
10
Wobland
15.03.13
✎
09:16
|
Функция ПолучитьСлучайнуюНоменклатуру(Исключаемые=0) Экспорт
ГСЧ=Новый ГенераторСлучайныхЧисел; Запрос=Новый Запрос; Запрос.Текст= "ВЫБРАТЬ | Номенклатура.Ссылка |ИЗ | Справочник.Номенклатура КАК Номенклатура |ГДЕ | (НЕ Номенклатура.Ссылка В (&Исключение) ИЛИ &Исключение=0) | И НЕ Номенклатура.ПометкаУдаления"; Запрос.УстановитьПараметр("Исключение", Исключаемые); Результат=Запрос.Выполнить().Выгрузить(); Если Результат.Количество()=0 Тогда Возврат Справочники.Номенклатура.ПустаяСсылка(); Иначе Возврат Результат[ГСЧ.СлучайноеЧисло(0, Результат.Количество()-1)].Ссылка; КонецЕсли; КонецФункции |
|||
11
НафНаф
15.03.13
✎
09:16
|
вероятность не может быть от 0 до 100, только до 1
|
|||
12
Asmody
15.03.13
✎
09:22
|
пример:
в 20 случаев из 60 должна выпасть строка 1, в 30 из 60 - строка 2, в 10 из 60 - строка 3. естественно, речь о статистическом количестве. (извините за качество, пишу с утюга) |
|||
13
Asmody
15.03.13
✎
09:24
|
(11) Вероятность/Итог(Вероятность) всегда меньше 1, не так ли?
|
|||
14
Гефест
15.03.13
✎
09:24
|
Размножь строки таблицы так, чтобы их количество было пропорционально вероятности, потом ткни случайно в строку
|
|||
15
Wobland
15.03.13
✎
09:25
|
(13) или равно
|
|||
16
Karavanych
15.03.13
✎
09:25
|
Функция возвращаемСтроку()
ТЗ=Новый ТаблицаЗначений; МаксВероятность; НомерВозвращаемойСтроки; НПП=0; Для каждого СтрокаТЗ из ТЗ цикл НПП=НПП+1; Если ТЗ.Вероятность*Случайное()>МаксВероятность тогда НомерВозвращаемойСтроки=НПП; МаксВероятность=ТЗ.Вероятность*Случайное(); КонецЕсли; КонецЦикла; возврат Тз.Получить(НомерВозвращаемойСтроки); КонецФункции |
|||
17
Asmody
15.03.13
✎
09:26
|
(14) это была первая идея. думал что-то поэффективнее найти
|
|||
18
Karavanych
15.03.13
✎
09:29
|
(17) ИтогВероятности=ТЗ.Итог("Вероятность");
возьми случайное число от 0 до ИтогВероятности; Распредели полученное как остаток построчно, где закончилось - ту строку возвращай. P.S. и эта... я перевел 65$m. |
|||
19
Asmody
15.03.13
✎
09:30
|
(18) сейчас до офиса доберусь, все сделаю
|
|||
20
Lama12
15.03.13
✎
09:30
|
(12) Если не ошибаюсь, это называется метод монте-карло.
Верно понял задачу? |
|||
21
dk
15.03.13
✎
09:31
|
можно решить через вспомогательную таблицу, но мутно конечно
1. считаем вероятность для каждой строки как КоличествоПопаданий = ОКР(ТЗ.Вероятность/ТЗ.Итог(Вероятность)*1000) 2. Создаем вспомогательную ТЗ2 с Колонкой "НомерСтрокиИсхТЗ" 3. Записываем в ТЗ2 номер строки из ТЗ столько раз, сколько посчитали в КоличествоПопаданий 4. Надо перемешать ТЗ2 в случайном порядке (еще 1 цикл + сортировка) 5. Строим выборку по ТЗ2 - тупо по очереди считываем и дергаем данные из ТЗ по номеру строки |
|||
22
Karavanych
15.03.13
✎
09:32
|
(19) и эта... про Итог по вероятности отличная идея кстати, не пропусти. эффективнее метода нет.
|
|||
23
Asmody
15.03.13
✎
09:33
|
пока в голове крутится вариант сделать еще колонку, в котором посчитать вероятности накопленным итогом, потом уже элементарный поиск
|
|||
24
HeroShima
15.03.13
✎
09:33
|
Каждой вероятности выделить диапазон значений Случайное().
|
|||
25
dk
15.03.13
✎
09:36
|
(14) быстрый и простой вариант, но распределение может не совпадать с заданным
(21) гарантированное заданное распределение |
|||
26
Xapac_2
15.03.13
✎
09:36
|
(23)может расскажете полное условие задачи, чтобы люди не гадали?
я(0) понял строка = ТабличнаяЧасть[Рандом(КоличествоСтрок)] |
|||
27
shpioleg
15.03.13
✎
09:36
|
Тоже был бы интересен оригинальный алгоритм. Пока сделано аналогично как в (14), но и вероятности у меня поменьше (от 1 до 10), т.к. что массив для выборки случайного индекса получается небольшой.
|
|||
28
Asmody
15.03.13
✎
09:37
|
(20) ну да, похоже. но я бы сказал, что это реализация дискретной случайной величины с заданной гистограммой
|
|||
29
Лефмихалыч
15.03.13
✎
09:37
|
(0) что на вход этой функции подается?
что означает формулировка "возвращает строку ТЗ с вероятностью Вероятность/Итог(Вероятность)"? |
|||
30
Karavanych
15.03.13
✎
09:38
|
вот смотри пример
Вероятность Данные 10 ололо 20 олололо 5 ололол 15 олололо Итог(50); Ты берешь случайно от 0 до 50, и соответственно начинаешь раскидывать остаток. например рендом дал 34. ты берешь построчно распределяешь полученное 10 - 10, закрлось 20 - 20 закрылось 5 - 4, не закрылось - возвращаем эту строку... все у тебя 100% верное распределение получается, используя рендом 1 раз не дробя строки. |
|||
31
Лефмихалыч
15.03.13
✎
09:43
|
(12) а, вон оно чо. Ну сделай соответствие из 60 элементов. Индекс соответствия - число от 0 до 60. Значение - индекс строки. Заполняй при обходе исходной таблицы - первые 20 значений = 1, следующие 30 = 2, остальные 10 = 3.
Далее просто генери случайное число от 1 до 60 и по этому числу получай из соответствия номер строки. Главное, чтобы генератор не возврщал дублей, а это легко решается |
|||
32
Asmody
15.03.13
✎
09:43
|
(30) да, это вариант. попробуем
|
|||
33
НафНаф
15.03.13
✎
09:45
|
(13) сама по себе вероятность - величина в интервале от 0 до 1
|
|||
34
HeroShima
15.03.13
✎
09:46
|
(30) и если отсортировать по убыванию вероятности, будет работать быстрее
|
|||
35
HeroShima
15.03.13
✎
09:47
|
(33) а вероятность * 100% уже не вероятность? )
|
|||
36
Asmody
15.03.13
✎
09:51
|
задачу тут кто-то просил целиком, озвучиваю:
задумали наши продажники акцию: при сумме заказа от... подарок покупателю. но чтоб все было по-честному, подарок сам должен в заказ вставляться вот с такой вероятностью. вот, собственно, и все |
|||
37
Asmody
15.03.13
✎
09:54
|
(36)+ ну т. е. подарков несколько видов, похуже, получше. ну и получается, что на один телевизор 5000 ручек и т. д.
|
|||
38
Karavanych
15.03.13
✎
09:54
|
(36) вероятность определяет какой именно подарок ?
|
|||
39
Ivan Bezdomnyi
15.03.13
✎
09:57
|
Мой вариант.
Вспомогательную колонку "Предел" если смотреть на вариант (12) +---+----+ ! 1 ! 20 ! 20 +---+----+ ! 2 ! 30 ! 50 +---+----+ ! 3 ! 10 ! 60 +---+----+ и т.д. следующее = сумме предыдущих по колонке "Вероятность". В итоге получим случайное число от 0 до (Итог по колонке "Вероятность") и найдем соответствующую строку. Т.е. если выпало 11 - первая строка например 35 - вторая строка если 56 - третья |
|||
40
Лефмихалыч
15.03.13
✎
10:01
|
(36) каша какая-то. так от чего зависит, какой подарок должен в накладную подставляться? Чем больше сумма, тем лучше подарок или как?
|
|||
41
Xapac_2
15.03.13
✎
10:02
|
(40)думаю вероятность сами манегеры выставляют.
|
|||
42
ptiz
15.03.13
✎
10:03
|
К таблице из (12) добавляем пару колонок (первая- значение из пред.строки +1, вторая - накопительный итог):
+---+----+ ----+----+ ! 1 ! 20 ! 1 ! 20 ! +---+----+ ----+----+ ! 2 ! 30 ! 21 ! 50 ! +---+----+ ----+----+ ! 3 ! 10 ! 51 ! 60 ! +---+----+ ----+----+ Генерируем сл.число от 1 до 60 и смотрим, в какой диапазон оно попадает (с конца таблицы проходим). И такую строку берем. |
|||
43
ptiz
15.03.13
✎
10:04
|
+(42) про "с конца таблицы" - не читать :)
Собственно, в (39) то же самое |
|||
44
Лефмихалыч
15.03.13
✎
10:09
|
(41) при чем тогда здесь "чтобы все было по-честному" и "на один телевизор 5000 ручек"?..
|
|||
45
Xapac_2
15.03.13
✎
10:15
|
(0) ладно уговорил давай логин пароль посмотрим.
|
|||
46
Лефмихалыч
15.03.13
✎
10:38
|
все гораздо проще на самом деле
И дальше уже выбирать из таблицы выбора строки по очереди. Получится искомое распределение - первый подарок будет выбран с вероятностью 20/60, второй - 30/60 и третий - 10/60 |
|||
47
acsent
15.03.13
✎
10:42
|
(46) так надо не все строки выбрать а одну
|
|||
48
Лефмихалыч
15.03.13
✎
10:43
|
(47) при оформлении каждой отдельной накладной выбираетсмя одна строка из ТаблицаВыбора и по ней определяется одна строка из ТаблицаПодарков. Откуда ты взял выбор всех строк, расскажи?
|
|||
49
sda553
15.03.13
✎
10:48
|
Все не читал, автора какой нибудь телепат смог понять?
|
|||
50
YHVVH
15.03.13
✎
10:59
|
(49) если я правильно понял
вероятность - это вес строки, строки с большим весом должны выбираться чаще. |
|||
51
dk
15.03.13
✎
11:16
|
(46) в (21) тоже самое
|
|||
52
Лефмихалыч
15.03.13
✎
13:16
|
(51) возможно. я там ни фига не понял
|
|||
53
shpioleg
15.03.13
✎
14:54
|
Сделал вот для своих целей. Для Номенклатуры тоже сгодится, если добавить реквизит ВероятностьУчастияВАкции. Блок кода который делит вероятности на более мелкие части (тут в ветке кто-то жаловался на неравномерное распределение) можно выкинуть.
&НаСервереБезКонтекста Функция ПолучитьСлучайныйПунктНаСервере () ЧислоРазрезкиВероятности = 1;// Число разрезаний исходной ТЗ на более мелкие части вероятностей. Если 0, то не разрезаем Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | Ссылка, | ВероятностьПоездки Вероятность |ИЗ | Справочник.Пункты |ГДЕ | ВероятностьПоездки > 0 | И НЕ ПометкаУдаления"; ТЗРезультата = Запрос.Выполнить().Выгрузить(ОбходРезультатаЗапроса.Прямой); Если НЕ ТЗРезультата.Количество() Тогда Возврат Неопределено; КонецЕсли; ГСЧ = Новый ГенераторСлучайныхЧисел(); //Чутка помешаем. Разобьем вероятность на ЧислоРазрезкиВероятности.Хз нужно ли это вообще для более равномерного распределения. Для ш = 1 по ЧислоРазрезкиВероятности Цикл ТЗДобавленныхВероятностей = ТЗРезультата.СкопироватьКолонки(); Для каждого стрТЗРезультата из ТЗРезультата Цикл СлучайноеЧисло = ГСЧ.СлучайноеЧисло(0,стрТЗРезультата.Вероятность - 1); Если СлучайноеЧисло Тогда стрТЗРезультата.Вероятность = стрТЗРезультата.Вероятность - СлучайноеЧисло; НоваяСтрока = ТЗДобавленныхВероятностей.Добавить(); НоваяСтрока.Ссылка = стрТЗРезультата.Ссылка; НоваяСтрока.Вероятность = СлучайноеЧисло; КонецЕсли; КонецЦикла; Для каждого стрТЗДобавленныхВероятностей из ТЗДобавленныхВероятностей Цикл НоваяСтрока = ТЗРезультата.Добавить(); НоваяСтрока.Ссылка = стрТЗДобавленныхВероятностей.Ссылка; НоваяСтрока.Вероятность = стрТЗДобавленныхВероятностей.Вероятность; КонецЦикла; КонецЦикла; //Найдем в ТЗ строку соответствующую Случайному числу СлучайноеЧисло = ГСЧ.СлучайноеЧисло(1,ТЗРезультата.Итог("Вероятность")); Для каждого стрТЗРезультата из ТЗРезультата Цикл СлучайноеЧисло = СлучайноеЧисло - стрТЗРезультата.Вероятность; Если СлучайноеЧисло <= 0 Тогда Возврат (стрТЗРезультата.Ссылка); КонецЕсли; КонецЦикла; Возврат Неопределено; КонецФункции &НаКлиенте Процедура ПолучитьСлучайныйПункт(Команда) Сообщить (ПолучитьСлучайныйПунктНаСервере ()); КонецПроцедуры |
|||
54
NcSteel
15.03.13
✎
15:15
|
(0) Пишешь алгоритм для рекламных банеров?
|
|||
55
Torquader
15.03.13
✎
19:07
|
Если у вас есть события с разной вероятностью - то это отрезок, разбитый на части, которые пропорциональны вероятности событий.
В строгой теории длина отрезка всегда равна единице, но может и отличаться. В случае единицы мы просто генерим случайное число от 0 до 1 и "кидаем" его на отрезок. В чью часть отрезка оно попало - того и выбрали. Конечно, для правильности выбора нужен равномерный случайный генератор. P.S. если сумма вероятностей не ноль, то генерим случайное число, равное длине отрезка. |
|||
56
HeroShima
16.03.13
✎
19:01
|
Для семёрки можно содрать отсюда: http://urlai.ru/2013/03/16/прототипируем-разработку-для-1с-и-полу/
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |