Поскольку кто-то уже упомянул мой Deal 3.1, я хотел бы указать на некоторые из оптимизаций, которые я сделал в этом коде.
Прежде всего, чтобы получить наиболее гибкие ограничения, я хотел добавитьполный язык программирования для моего дилера, чтобы вы могли создавать целые библиотеки ограничений с различными типами оценщиков и правил.Я использовал Tcl для этого языка, потому что я уже изучал его для работы, и в 1994 году, когда был выпущен Deal 0.0, Tcl был самым простым языком для встраивания в приложение C.
Во-вторых, мне нужно было ограничениеязык бегать довольно быстро.Ограничения работают глубоко внутри цикла.Довольно много кода у моего дилера - это небольшая оптимизация с помощью справочных таблиц и т. П.
Одна из самых удивительных и простых оптимизаций заключалась в том, чтобы не сдавать карты на место до тех пор, пока на этом месте не будет проверено ограничение.Например, если вы хотите, чтобы север соответствовал ограничению A, а юг соответствовал ограничению B, а ваш код ограничения:
match constraint A to north
match constraint B to south
Только тогда, когда вы дойдете до первой строки, вы заполните северную стрелку.Если это не удается, вы отклоняете полную сделку.Если это проходит, затем заполните южную руку и проверьте ее ограничение.Если это не удастся, выбросить всю сделку.В противном случае завершите сделку и примите ее.
Я нашел эту оптимизацию, выполняя какое-то профилирование и заметив, что большую часть времени проводилось в генераторе случайных чисел.
Есть одна причудливая оптимизация,который может работать в некоторых случаях, назовите «умное наложение».
deal::input smartstack south balanced hcp 20 21
Это генерирует «фабрику» для южной руки, которая занимает некоторое время, но которая затем может очень быстро заполнить одну руку, чтобысоответствовать этому критерию.Из-за проблем, связанных с условной вероятностью, интеллектуальное суммирование может применяться только к одной руке за раз.[*]
Интеллектуальное накопление принимает «класс формы» - в данном случае «сбалансированный», «оценщик удержания», в данном случае «hcp», и диапазон значений для оценщика удержания.«Оценщик удержания» - это любой оценщик, который применяется к каждой масти, а затем суммируется, поэтому hcp, controls, проигравшие, hcp_plus_shape и т. Д. Все являются удерживающими эвалаторами.необходимо принять довольно ограниченный набор значений.Как работает умная укладка?Это может быть немного больше, чем у меня есть время, чтобы публиковать здесь, но это в основном огромный набор таблиц.
Один последний комментарий: Если вы действительно хотите эту программу только для практики торгов, а не для моделирования,Многие из этих оптимизаций, вероятно, не нужны.Это потому, что сама природа практики делает нецелесообразным время для того, чтобы практиковать чрезвычайно редкие предложения.Так что, если у вас есть состояние, которое встречается только один раз в миллиарде сделок, вам действительно не стоит беспокоиться об этом.:)
[Редактировать: Добавить умные детали стеков.]
Хорошо, в костюме точно 8192 = 2 ^ 13 возможных владений.Сгруппируйте их по длине и количеству чести:
Holdings(length,points) = { set of holdings with this length and honor count }
Итак
Holdings(3,7) = {AK2, AK3,...,AKT,AQJ}
и пусть
h(length,points) = |Holdings(length,points)|
Теперь перечислите все фигуры, которые соответствуют вашему состоянию (пики =5):
5-8-0-0
5-7-1-0
5-7-0-1
...
5-0-0-8
Обратите внимание, что коллекция всех возможных форм рук имеет размер 560, поэтому этот список невелик.
Для каждой фигуры перечислите способы, которыми вы можете получить общее количество.очки чести, которые вы ищете, перечисляя очки чести за костюм.Например,
Shape Points per suit
5-4-4-0 10-3-0-0
5-4-4-0 10-2-1-0
5-4-4-0 10-1-2-0
5-4-4-0 10-0-3-0
5-4-4-0 9-4-0-0
...
Используя наши наборы Holdings (длина, точки), мы можем вычислить количество способов получить каждую из этих строк.Например, для строки 5-4-4-0 10-3-0-0 вы должны иметь:
h(5,10)*h(4,3)*h(4,0)*h(0,0)
Итак, выберите одну из этих строк случайным образом с относительной вероятностью, основанной насчет, а затем, для каждой масти, выберите случайное владение из правильного набора Holdings ().
Очевидно, что чем шире диапазон форм и точек рук, тем больше строк вам нужно будет предварительно вычислить.Немного больше кода, вы все еще можете сделать это с некоторыми заранее определенными картами - если вы знаете, где пиковый туз или целая рука запада или что-то еще.
[*] Теоретически вы можете решить эти условные вероятности.проблемы для умного стека с несколькими руками, но решение проблемы сделало бы его эффективным только для крайне редких типов сделок.Это связано с тем, что количество строк в фабричной таблице примерно равно произведению количества строк для укладки в одну руку на количество строк для укладки в другую руку.Кроме того, в таблице h () необходимо указать количество способов деления n карт на раздачи 1, раздача 2 и другие раздачи, что изменяет число значений примерно с 2 ^ 13 до 3 ^ 13 возможных значений,что примерно на два порядка больше.