<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<title type="html"><![CDATA[Серый форум &mdash; AHK: Вероятность. Список элементов, получаемых с определённым шансом.]]></title>
	<link rel="self" href="https://forum.script-coding.com/extern.php?action=feed&amp;tid=15337&amp;type=atom" />
	<updated>2020-05-02T20:29:36Z</updated>
	<generator>PunBB</generator>
	<id>https://forum.script-coding.com/viewtopic.php?id=15337</id>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Вероятность. Список элементов, получаемых с определённым шансом.]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=139304#p139304" />
			<content type="html"><![CDATA[<p>Например, в моём случае — соответствие статистике.<br />Есть некоторый набор данных, представленных в виде списка, который обновляется с интервалом в один день, или около. Статистика представляет собой набор сигнатур с которыми обращались пользователи на сервер и поскольку частично, или полностью, их сигнатуры могли совпадать, в этом списке они отражены в виде процентов.</p><p>Можно так же смело отождествить этот процент с вероятностью, ведь если сигнатура &quot;А&quot; взаимодействовала с сервером 4% за измеряемый промежуток времени, то на момент измерений, вероятность её появления равнялась 4%.</p><p>Этот опыт можно использовать на других сервисах. Если список обновляется постоянно, то в загашнике всегда набор актуальных данных, соответствуя которым, можно не выделяться из толпы.</p>]]></content>
			<author>
				<name><![CDATA[KusochekDobra]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=33846</uri>
			</author>
			<updated>2020-05-02T20:29:36Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=139304#p139304</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Вероятность. Список элементов, получаемых с определённым шансом.]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=139302#p139302" />
			<content type="html"><![CDATA[<p>Хороший у меня вопрос, не как, а зачем. <img src="//forum.script-coding.com/img/smilies/smile.png" width="15" height="15" /></p>]]></content>
			<author>
				<name><![CDATA[serzh82saratov]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=27879</uri>
			</author>
			<updated>2020-05-02T19:44:11Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=139302#p139302</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Вероятность. Список элементов, получаемых с определённым шансом.]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=139301#p139301" />
			<content type="html"><![CDATA[<p>В играх? Например.</p>]]></content>
			<author>
				<name><![CDATA[serzh82saratov]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=27879</uri>
			</author>
			<updated>2020-05-02T19:43:22Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=139301#p139301</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Вероятность. Список элементов, получаемых с определённым шансом.]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=139299#p139299" />
			<content type="html"><![CDATA[<p>Ну просто выбор варианта с определённой вероятностью. Может в играх, например, применяться.</p>]]></content>
			<author>
				<name><![CDATA[teadrinker]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=24515</uri>
			</author>
			<updated>2020-05-02T19:36:24Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=139299#p139299</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Вероятность. Список элементов, получаемых с определённым шансом.]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=139297#p139297" />
			<content type="html"><![CDATA[<p>Почерк похож, но теперь не пойму зачем оно было нужно.</p>]]></content>
			<author>
				<name><![CDATA[serzh82saratov]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=27879</uri>
			</author>
			<updated>2020-05-02T19:26:21Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=139297#p139297</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Вероятность. Список элементов, получаемых с определённым шансом.]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=139294#p139294" />
			<content type="html"><![CDATA[<p>Вроде, ты этот код и писал.</p>]]></content>
			<author>
				<name><![CDATA[teadrinker]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=24515</uri>
			</author>
			<updated>2020-05-02T19:11:38Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=139294#p139294</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Вероятность. Список элементов, получаемых с определённым шансом.]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=139293#p139293" />
			<content type="html"><![CDATA[<p>А какова может быть практика применения? Что то ничего на ум не приходит.</p>]]></content>
			<author>
				<name><![CDATA[serzh82saratov]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=27879</uri>
			</author>
			<updated>2020-05-02T18:54:19Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=139293#p139293</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Вероятность. Список элементов, получаемых с определённым шансом.]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=139292#p139292" />
			<content type="html"><![CDATA[<p>Находил что-то на &quot;Сером форуме&quot;, но не то. Возможно, не то о и нашёл, раз &quot;не то&quot;. <img src="//forum.script-coding.com/img/smilies/smile.png" width="15" height="15" /><br />Надо было сразу спросить, но задача показалась не сложной и оставалось проверить это практически.</p>]]></content>
			<author>
				<name><![CDATA[KusochekDobra]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=33846</uri>
			</author>
			<updated>2020-05-02T18:51:00Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=139292#p139292</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Вероятность. Список элементов, получаемых с определённым шансом.]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=139285#p139285" />
			<content type="html"><![CDATA[<p>А у нас когда-то была такая тема, лень искать. Такие варианты в результате получились:<br /></p><div class="codebox"><pre><code>/*
ссылки:
Walker&#039;s alias method
Wiki:         https://goo.gl/lT15mg
Объяснение: http://goo.gl/p9ke8Q
Код:         http://goo.gl/F8SGKf
*/

; вероятности в виде процентных соотношений:
obj := {A: 20, B: 30, C: 50}
Random, peek, 1, 100
for k, v in obj, sum := 0
   sum += v
until sum &gt;= peek
MsgBox, % k

; общий случай:
obj := {A: 2, B: 3, C: 5}
for k, v in obj, _sum := 0
   _sum += v

Random, peek, 1, _sum
for k, v in obj, sum := 0
   sum += v
until sum &gt;= peek

MsgBox, % k

; проверка:
obj := {A: 2, B: 3, C: 5}
for k, v in obj, _sum := 0
   _sum += v

test := {A: 0, B: 0, C: 0}
Loop 10000  {
   Random, peek, 1, _sum
   for k, v in obj, sum := 0
      sum += v
   until sum &gt;= peek &amp;&amp; test[k]++
}

MsgBox, % test.A &quot;`n&quot; test.B &quot;`n&quot; test.C</code></pre></div><div class="codebox"><pre><code>; алгоритм на основе диапазонов значений
obj := {A: 2, B: 3, C: 5}

for k, v in obj, sum := 0
   sum += v

Random, rand,, 1.
for k, v in obj, prev := 0
    prev += v/sum  ; создаём диапазон для каждого ключа
until rand &lt;= prev ; и сразу проверяем, не попал ли rand в него
   
MsgBox, % k

; проверка алгоритма
SetBatchLines, -1
obj := {A: 20, B: 78.5, C: 1.5}

for k, v in obj, sum := 0
   sum += v

test := {A: 0, B: 0, C: 0}
Loop % N := 100000  {
   Random, rand,, 1.
   for k, v in obj, prev := 0
      prev += v/sum
   until rand &lt;= prev &amp;&amp; test[k]++
}
   
MsgBox, % &quot;A — &quot; Round(test.A/N*100, 1) &quot;%`nB — &quot; Round(test.B/N*100, 1) &quot;%`nC — &quot; Round(test.C/N*100, 1) &quot;%&quot;</code></pre></div>]]></content>
			<author>
				<name><![CDATA[teadrinker]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=24515</uri>
			</author>
			<updated>2020-05-02T15:11:54Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=139285#p139285</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[AHK: Вероятность. Список элементов, получаемых с определённым шансом.]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=139277#p139277" />
			<content type="html"><![CDATA[<p>Найти такой велосипед не удалось, вопрос оказался не популярным. Может кто-то так же будет искать.<br /></p><div class="codebox"><pre><code>; ===============================================================================================
;	Класс Probability
;	Эмулирует генерацию &quot;ситуации&quot;, вероятность которой может быть задана.
;	
;	Создаёт объект, метод Gen() которого возвращает булево значение, означающее, была ли
;		&quot;ситуация&quot; сгенерирована.
; ===============================================================================================
Class Probability
{
	; ===========================================================================================
	;	prob		- ( float ) Опиционально. В интервале от 0 до 100, обозначающий процент
	;					удачных срабатываний. Со значением по умолчанию, Gen() — всегда
	;					возвращает &quot;True&quot;
	; ===========================================================================================
	__New(prob := 100.0) {
		this.prob := prob &gt; 100 ? 100 : prob &lt; 0 ? 0 : prob
	}
	
	Gen() {
		Random, r, 0.0, 100.0
		Return r &lt;= this.prob
	}
}

; ===============================================================================================
;	Класс ProbabilityList
;	Формирует список из данных, которые затем можно получить с некоторой вероятностью,
;		устанавливаемой при добавлении данных.
; ===============================================================================================
Class ProbabilityList
{
	__New() {
		this._available_probability := 100.0
        this._count := 0
        this._storage := []
		this._last_prob := []
	}
	; ===========================================================================================
	;	Добавляет в список элемент.
	;	item		- ( any ) Данные, добавляемые в список.
	;	prob		- ( float ) Значение ожидания в интервале от 0 до 100, обозначающее щанс, с
	;					которым элемент может быть получен.
	;	Все методы добавляющие элемент в список, имеют этот же набор рагументов.
	; ===========================================================================================
	AddItem(item, prob) {
        this._storage.Push({ &quot;item&quot;: item, &quot;prob&quot;: new Probability(prob) })
		this._available_probability -= prob
        this._count += 1
	}
	
	; ===========================================================================================
	;	Добавляет в список элемент, учитывая максимально возможный шанс получения элементов
	;		списка равный 100% и распределяя этот пулл вероятности между всеми элементами списка
	;		согласно заявленному ожиданию. Таким образом, в список поместится не больше
	;		элементов, чем сумманый шанс получить каждый из них, опираясь на шанс ожидания.
	;	
	;	Следующие далее методы имеют это же поведение за исключением следующей особености:
	;	
	;		Попытки вместить элементы с шансом превышающим этот лимит — будут проигнорированы,
	;			кроме того случая, когда ещё есть &quot;неизрасходованная&quot; его часть, а добавляемый
	;			элемент ожидается с превышением этого значения. В этом случае, элемент всё же
	;			будет помещён в список, но будет установлен со значением этого остатка.
	; ===========================================================================================
	AddItemWhileAvailable(item, prob) {
		if (this._available_probability == 0 || prob &lt;= 0)
            return -1
			
		prob := prob &gt; this._available_probability ? this._available_probability : prob
		this._storage.Push({ &quot;item&quot;: item, &quot;prob&quot;: new Probability(prob) })
		this._count += 1
		this._available_probability -= prob
		return this._available_probability
	}
	
	; ===========================================================================================
	;	Добавляет в список элемент.
	;	
	;	Особенностью этого метода является заполнение всей оставшейся части из доступного лимита
	;		вероятности, установкой этого значения для последнего переданного элемента.
	;	
	;	Например: В список добавляется элемент &quot;А&quot; с ожидаемой вероятностью 7%, но
	;		устанавливается со значением 100%, так как доступный лимит ещё не начал
	;		расходоваться. Следующий элемент, &quot;Б&quot; добавляемый с вероятностью 30%, будет
	;		установлен со значением 93%, а элемент &quot;А&quot; — получит свои 7% на шанс. И так далее
	;		пока есть неизрасходованный лимит.
	; ===========================================================================================
	AddItemWhileAvailable_WithFilling(item, prob) {
		if (this._available_probability == 0 || prob &lt;= 0)
            return -1
		if (this._count)
            this._storage[ this._count ].prob := new Probability(this._last_prob[ this._count ])
			
		this._storage.Push({ &quot;item&quot;: item, &quot;prob&quot;: new Probability(this._available_probability) })
		
		prob := prob &gt; this._available_probability ? this._available_probability : prob
		this._count += 1
		this._last_prob.Push( prob )
		this._available_probability -= prob
		return this._available_probability
	}
	
	; ===========================================================================================
	;	Добавляет в список элемент.
	;	
	;	При добавлении первого элемента, создаётся элемент со значением, равным нулю и весь
	;		оставшейся лимит вероятности будет проецироваться на него. Таким образом, элементы
	;		всегда можно получать с ожидаемой частотой, даже если общая вероятность их получить
	;		меньше доступного лимита.
	; ===========================================================================================
	AddItemWhileAvailable_WithZeroFilling(item, prob) {
		if (this._available_probability == 0 || prob &lt;= 0)
            return -1
		
		prob := prob &gt; this._available_probability ? this._available_probability : prob
		this._storage.Push({ &quot;item&quot;: item, &quot;prob&quot;: new Probability(prob) })
		this._available_probability -= prob
		
		if (!this._count) {
			this._storage.Push({ &quot;item&quot;: 0, &quot;prob&quot;: new Probability(this._available_probability) })
			this._count += 1
		} else
			this._storage[ 2 ].prob := new Probability(this._available_probability)
		
		this._count += 1
		return this._available_probability
	}
	
	; ===========================================================================================
	;	Получает случайный элемент списка, согласно ожидаемой вероятности.
	; ===========================================================================================
	GetItem() {
		if (!this._count)
			return -1
		Loop {
			Loop,% this._count {
				Random, r, 1,% this._count
				if ((item := this._storage[ r ]).prob.Gen())
					return item.item
			}
		}
	}
	
	; ===========================================================================================
	;	Удаляет элемент из списка по значению, освобождая занимаемый им лимит.
	; ===========================================================================================
	RemoveItemByItem(item) {
		For index, value in this._storage {
			if (value.item == item) {
				this._available_probability += value.prob.prob
				if (this._last_prob.Count())
					this._last_prob.RemoveAt(index)
				this._storage.RemoveAt(index)
				this._count -= 1
				return true
			}
		} return false	
	}
	
	; ===========================================================================================
	;	Удаляет элемент из списка по индексу, освобождая занимаемый им лимит.
	; ===========================================================================================
	RemoveItemByIndex(index) {
		value := this._storage.RemoveAt(index)
		if (value != &quot;&quot;) {
			this._available_probability += value.prob.prob
			if (this._last_prob.Count())
				this._last_prob.RemoveAt(index)
			this._count -= 1
			return true
		} return false
	}
}</code></pre></div><p>Суть задачи состояла в том, чтобы иметь некий объект, который можно &quot;заряжать&quot; данными, с указанием вероятности, с которой затем можно у этого объекта их получать. Далее пример, иллюстрирующий работу разных методик формирования такого списка элементов, для разных ситуаций.<br /></p><div class="codebox"><pre><code>#NoEnv
#SingleInstance, Force

ListLines, Off
SetBatchLines, -1
#Include Probability.ahk

count := 100000
ww := 500

current_test_number := 1
tests := [&quot;&quot;, &quot;DoFullProbListTest&quot;
			, &quot;DoOverflowProbListTest&quot;
			, &quot;DoOverflowProbListTest_WithAvailable_Prob&quot;
			, &quot;DoDeficitProbListTest_WithAvailable_Prob&quot;
			, &quot;DoDeficitProbListTest_WithAvailable_Prob_AndFilling&quot;
			, &quot;DoDeficitProbListTest_WithAvailable_Prob_AndZeroFilling&quot;]

Gui, 1: Font, s10 w700 c099aaa, Consolas
Gui, 1: Add, Edit, r20 w%ww% v_edit
Gui, 1: Add, Button, w%ww% v_do_next gDoNext, Do Next
Gui, 1: Show

probs := [ 12.7, 4, 98.2, 37.447, 0.2 ]
For i, prob in probs {
	p := new Probability(prob)
	t := f := 0
	Loop,% count
		p.Gen() ? t += 1 : f += 1
	str .= Format(&quot;Из {} попыток и с вероятностью {}%, выпало:`nПоложительных &quot;
		. &quot;{}`nОтрицательных {}`n=======================`n&quot;, count, prob, t, f)
}
GuiControl, Text, _edit,% str

Return

DoNext:
	if (current_test_number + 1 &gt; tests.Count()) {
		MsgBox Done!
		Return
	} current_test_number += 1
	GuiControl, Disable, _do_next
	GoSub,% tests[ current_test_number ]
Return

DoFullProbListTest:
	str := &quot;Создание списка из элементов, сумма вероятностей использования&quot;
			. &quot; которых равна 100%.`nГенерация в цикле из &quot; . count
			. &quot; итераций:`n&quot;
	GuiControl, Text, _edit,% str
	result := {}
	p_list := new ProbabilityList()
	values := [ 43, 33, 12, 6, 3, 1.5, 1, 0.5 ]
	For i, value in values {
		key := value . &quot;%&quot;
		p_list.AddItem(key, value)
		result[ key ] := 0
	}

	Loop,% count
		result[ p_list.GetItem() ] += 1

	str .= PrintResult(result)
	GuiControl, Text, _edit,% str
	GuiControl, Enable, _do_next
Return

DoOverflowProbListTest:
	str := &quot;Создание списка из элементов, сумма вероятностей использования&quot;
			. &quot; которых превышает 100%.`nГенерация в цикле из &quot; . count
			. &quot; итераций:`n&quot;
	GuiControl, Text, _edit,% str
	result := {}
	p_list := new ProbabilityList()
	values := [ 42, 21, 3.7, 27, 11, 84, 100, 2 ]
	For i, value in values {
		key := value . &quot;%&quot;
		p_list.AddItem(key, value)
		result[ key ] := 0
	}

	Loop,% count
		result[ p_list.GetItem() ] += 1

	str .= PrintResult(result)
		. &quot;`n`nТеперь значения явно не соответствуют ожидаемым вероятностям,&quot;
		. &quot; но, как видно, срабатывания распределяются пропорционально этим &quot;
		. &quot;значениям. Это так же заметно по кратным значениям 21, 42 и 84%.&quot;
	GuiControl, Text, _edit,% str
	GuiControl, Enable, _do_next
Return

DoOverflowProbListTest_WithAvailable_Prob:
	str := &quot;Создание списка из элементов, сумма вероятностей использования&quot;
			. &quot; которых превышает 100%, но уже учитывая этот аспект.`nГене&quot;
			. &quot;рация в цикле из &quot; . count . &quot; итераций:`n&quot;
	GuiControl, Text, _edit,% str
	result := {}
	p_list := new ProbabilityList()
	values := [ 42, 21, 3.7, 27, 11, 84, 100, 2 ]
	For i, value in values {
		key := value . &quot;%&quot;
		avlb := p_list.AddItemWhileAvailable(key, value)
		result[ key ] := 0
		if (avlb == 0)
			Break
	}

	Loop,% count
		result[ p_list.GetItem() ] += 1

	str .= PrintResult(result)
		. &quot;`n`nВ этот раз вероятности были рассчитаны корректно, но список&quot;
		. &quot; вместил в себя только пять элементов, поместившихся в лимит. &quot;
		. &quot;К тому же, последний из них(в этом списке он первый) — должен&quot;
		. &quot; был рассчитываться с 11% вероятностью, но был рассчитан с те&quot;
		. &quot;м, что ему осталось от лимита, занятого элементами, попавшими&quot;
		. &quot; в список перед ним(100 - (42 + 21 + 3.7 + 27 = 93.7) = 6.3%).&quot;
	GuiControl, Text, _edit,% str
	GuiControl, Enable, _do_next
Return

DoDeficitProbListTest_WithAvailable_Prob:
	str := &quot;Создание списка из элементов, суммы вероятностей использования&quot;
			. &quot; которых(12 + 2.5 + 13.7 + 24.123 + 0.666 = 52.989) не хват&quot;
			. &quot;ает до 100%.`nГенерация в цикле из &quot; . count . &quot; итераций:`n&quot;
	GuiControl, Text, _edit,% str
	result := {}
	p_list := new ProbabilityList()
	values := [ 12, 2.5, 13.7, 24.123, 0.666 ]
	For i, value in values {
		key := value . &quot;%&quot;
		avlb := p_list.AddItemWhileAvailable(key, value)
		result[ key ] := 0
		if (avlb == 0)
			Break
	}

	Loop,% count
		result[ p_list.GetItem() ] += 1

	str .= PrintResult(result)
		. &quot;`n`nКак и в позапрошлом примере, срабатывания распределяются &quot;
		. &quot;пропорционально значениям, но всё же не отвечают ожиданиям.&quot;
	GuiControl, Text, _edit,% str
	GuiControl, Enable, _do_next
Return

DoDeficitProbListTest_WithAvailable_Prob_AndFilling:
	str := &quot;Создание списка из элементов, суммы вероятностей использования&quot;
			. &quot; которых(12 + 2.5 + 13.7 + 24.123 + 0.666 = 52.989) не хват&quot;
			. &quot;ает до 100%, чуть больше 47%.`nГенерация в цикле из &quot; . count
			. &quot; итераций:`n&quot;
	GuiControl, Text, _edit,% str
	result := {}
	p_list := new ProbabilityList()
	values := [ 12, 2.5, 13.7, 24.123, 0.666 ]
	For i, value in values {
		key := value . &quot;%&quot;
		avlb := p_list.AddItemWhileAvailable_WithFilling(key, value)
		result[ key ] := 0
		if (avlb == 0)
			Break
	}

	Loop,% count
		result[ p_list.GetItem() ] += 1

	str .= PrintResult(result)
		. &quot;`n`nТеперь, каждый элемент попавший в список последним, заполняет&quot;
		. &quot; собой всё доступное &#039;пространство&#039; вероятности, независимо от то&quot;
		. &quot;го, с какой ожидаемой вероятностью он попал в этот список. Наприм&quot;
		. &quot;ер, первый элемент, всегда имеет 100% вероятности быть полученным&quot;
		. &quot; из списка, даже если ожидается, что его вероятность = 5%. Но есл&quot;
		. &quot;и в список попадает следующий элемент, первый, получает свои 5% н&quot;
		. &quot;а шанс, а второму достаются остальные 95%.&quot;
	GuiControl, Text, _edit,% str
	GuiControl, Enable, _do_next
Return

DoDeficitProbListTest_WithAvailable_Prob_AndZeroFilling:
	str := &quot;Создание списка из элементов, суммы вероятностей использования&quot;
			. &quot; которых, как и прежде(12 + 2.5 + 13.7 + 24.123 + 0.666 = 5&quot;
			. &quot;2.989), не хватает до 100%, чуть более 47%.`nГенерация в ц&quot;
			. &quot;икле из &quot; . count . &quot; итераций:`n&quot;
	GuiControl, Text, _edit,% str
	result := {0: 0}
	p_list := new ProbabilityList()
	values := [ 12, 2.5, 13.7, 24.123, 0.666 ]
	For i, value in values {
		key := value . &quot;%&quot;
		avlb := p_list.AddItemWhileAvailable_WithZeroFilling(key, value)
		result[ key ] := 0
		if (avlb == 0)
			Break
	}

	Loop,% count
		result[ p_list.GetItem() ] += 1

	str .= PrintResult(result)
		. &quot;`n`nВ этот раз, оставшуюся вероятность заполняет собой элемент, &quot;
		. &quot;возвращающий ноль. Если из списка нужно получать элементы строго&quot;
		. &quot; соответствуя ожиданиям, то возвращаемый ноль можно просто отбрас&quot;
		. &quot;ывать из результатов.&quot;
	GuiControl, Text, _edit,% str
	GuiControl, Enable, _do_next
Return

GuiClose:
	ExitApp

PrintResult(result) {
	str := &quot;{`n    &quot;
	For k, v in result
		str .= Format(&quot;&#039;{}&#039;:`t{}`n    &quot;, k, v)
	return RTrim(str, &quot; &quot;) . &quot;}&quot;
}</code></pre></div>]]></content>
			<author>
				<name><![CDATA[KusochekDobra]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=33846</uri>
			</author>
			<updated>2020-05-02T11:03:25Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=139277#p139277</id>
		</entry>
</feed>
