Suppose we would like to compute an approximate prime factorization of a large integer x in the sense that the difference between x and its approximation is minimized. A naive way to state the problem in Mathematica is as follows.
n = 50;
x = RandomInteger[10^100];
vars = Map[z[#] &, Range[n]];
f = Abs[Times@@Map[Prime[#]^z[#] &, Range[n]] - x];
cons = Map[# >= 0 &, vars];
NMinimize[{f, cons}, vars \[Element] Integers]
The result is not very convincing and simply increasing n does not help. Do you have a better way to solve the problem?
Update: To account for the criticism presented by @yarchik, let me define the problem more precisely by demanding that the largest prime $p$ usable in the factorization must satisfy $10^p \leq x$. The naive Mathematica formulation above can be adapted as follows (being still naive but more precise).
x = RandomInteger[10^100];
p = {2};
While[NextPrime@Last@p <= Floor@Log[10, x], AppendTo[p, NextPrime@Last@p]];
n = Length[p];
vars = Map[z[#] &, Range[n]];
f = Abs[Times@@Map[#[[1]]^#[[2]] &, Thread[{p, vars}]] - x];
cons = Map[# >= 0 &, vars];
NMinimize[{f, cons}, vars \[Element] Integers]
Besides a better method to address this problem, I am also interested in lower and upper bounds of the solution for a given x.
Update 2: @DanielLichtblau suggested an encoding as knapsack problem which indeed improves the result obtained by NMinimize. One way to compute the resulting vars rules is as follows.
Thread[vars -> KnapsackSolve[Thread[{Log[p], Log[p]}], Log[x]]]
z[1], z[2]would enhanced the readability of your code. Another point is that there is an obvious limit to your functionfthat you try to minimize. Take the factors to be 2 and[x/2]. The error is at most 1. In other words, you need a better target function. $\endgroup$x. Are you aware of an upper/lower bound to the optimization problem givenxandn(or a list of factors alternatively)? $\endgroup$