Используя RcppAlgos
(я - автор), это тривиально.
RcppAlgos::permuteGeneral(seq(0, 8, 1), 4,
constraintFun = "sum",
comparisonFun = "==",
limitConstraints = 6)
Алгоритм ниже оптимизирован для быстрого удаления невозможных решений.Мы также рассматривали только проверку комбинаций, так как сложение / умножение коммутативно и порядок не имеет значения.Как только мы находим подходящую комбинацию, мы генерируем все перестановки этой конкретной комбинации.Также помогает то, что мы используем Rcpp
для значительного повышения эффективности.
Для реальной задачи ОП с 200 числами и 6 столбцами выполнимость будет сильно зависеть от необходимой суммы.Если мы рассмотрим среднюю сумму (которая произойдет больше всего), нам может потребоваться рассмотреть альтернативные подходы, поскольку число возможных решений сдвига превышает 2^31 - 1
.Это также займет значительное количество времени.Только с 5 столбцами и желаемой суммой в 500 я даже не могу произвести перестановки.Однако я могу создать комбинации:
res <- RcppAlgos::comboGeneral(1:200, 5,
constraintFun = "sum",
comparisonFun = "==",
limitConstraints = 500,
upper = 1e8) ## upper argument constrains the output to a maximum number of results
nrow(res)
[1] 7669861
И, учитывая, что повторов нет, мы можем рассчитать количество перестановок:
7669861 * factorial (5) =920 383 320
Вот ошибка, которую я получаю:
res <- RcppAlgos::permuteGeneral(1:200, 5,
constraintFun = "sum",
comparisonFun = "==",
limitConstraints = 500,
upper = 921000000)
Show Traceback
Rerun with Debug
Error: vector memory exhausted (limit reached?)
Если желаемая сумма относительно мала или велика по сравнению со средней суммой, вычисления возможны.Например, если желаемая сумма равна 100, мы можем быстро получить все перестановки:
system.time(res <- RcppAlgos::permuteGeneral(1:200, 6,
constraintFun = "sum",
comparisonFun = "==",
limitConstraints = 100,
upper = 1e8))
user system elapsed
2.213 0.525 2.753
nrow(res)
[1] 47395440