Ок, давайте думать коллективно. Вчера ночью на трассе было пол-часа, подумал, и пришел к выводу, что таки есть эвристики. Как минимум одна.
Сильно "отстающие" комбинации можно вырубать уже на ранней стадии, когда ясно, что за оставшиеся шаги нельзя набрать достаточно, чтобы перекрыть лучший вариант. Как? А вот как:
Для каждого отморозка (i) находим для всех возможных топоров (j) значение отставания от лучшего топора для данного отморозка (max[i=const,0<=jj<M](A(i,jj)) - A(i,j)), и пришпиливаем это значение к каждой паре (i,j) - B(i,j) (Разумеется, лучший топор для данного отморозка сам получит значение B(i,jj)=0). Этот алгоритм включает серию сортировок и несложно доказать, что он полиномиальный.
Далее, начинаем "умно" перебирать, начиная от самого удачного для каждого дикаря (минимальный B(i,j), сначала 0, потом 2-й минимум, потом третий и т.д.). Каждый выбор, разумеется, вычеркивает данный томагавк для выбора другим претендентом. Если накопившийся штраф (сумма отставаниий B(i,j) от начала комбинации) превышает этот же у лучшего из законченных комбинаций, то данная комбинация херится на месте без продолжения.
Ясно, что лучшая комбинация будет среди первых, а чем дальше от оптимального, тем скорее будут убиваться на раннем этапе бесперспективные комбинации.
Все элементы алгоритма полиномиальные, кроме самого перебора - тут вопрос, как посчитать эффект от оптимизации на кол-во пермутаций. Если еще пол-часа поездить, думаю, это можно будет решить.
|