Тут я кстати попробовал прикрутить хеширование к последней (ну ладно, крайней) модификации своей проги, той, где перебор с границами альфа-бета. И столкнулся вот с чем.
Во-первых, если в варианте с точными результатами (а не с границами) можно было оперировать таблицей внутри цикла ходов, то здесь это не проходит. Т.е. вызывается рекурсия (на каком-то уровне), и первое, что должно быть сделано (после усечения интервала альфа-бета в случае, когда new_depth<depth), это запись расклада в таблицу (конечно для ходов, когда на всех руках одинаковое кол-во карт), если этот расклад встретился впервые. После этого (для впервые встретившегося расклада) мы пробегаем по всем ходам, в результате чего получаем новое значение оценки альфа этого уровня, и его записываем в кеш.
А если же на этапе проверки "первичности" расклада выясняется, что такой расклад уже был (речь идёт конечно о транспонированных раскладах), это означает, что в таблицу некая оценка альфа уже была закеширована. И тогда нам уже нет смысла пробегать по всех ходам, чтобы её получить, мы её берём просто из кеша. Но здесь возникает вот какая штука. Если в прошлой версии программы, где шла работа с точными значениями, а не с оценками, нам кроме расклада и знания, чей сейчас ход, больше ничего нужно не было, и мы могли сразу взять закешированный ранее точный результат из таблицы, то в случае с оценками не так всё просто. Ведь здесь рекурсивная функция вызывается с параметрами. И если эти начальные параметры альфа и бета не кешировать вместе с раскладом, то всё считается неправильно. Поэтому ещё на этапе записи расклада в кеш (т.е. перед циклом ходов) туда же записываются и текущие альфа с бетой. А при проверке первичности/повторности расклада он считается повторным только в том случае, когда когда не только все карты совпадают, но и записанные в таблицу альфа и бета совпадают с теми альфой и бетой, которые на данный момент являются параметрами рекурсивной функции.
Как нетрудно догадаться, это сильно увеличивает количество якобы "разных" раскладов, но только в этом случае результат работы программы получается корректным. Вообще даже в этом случае для единичных раскладов скорость расчёта выше (не намного, не больше, чем в 2 раза), чем в версии без альфа-бета перебора, а вот на массиве раскладов скорость, наоборот, ниже. Что объяснимо, конечно. Как минимизировать количество этих "разных" раскладов, и соответственно количество записей в кеш, я че-то пока не пойму. Каким-то образом надо "играть" с границами.
|