Minimization can be expressed with plain `NMinimize`

in a bit awkward manner:

```
NextHighlyCompositeNumber[n_Integer?Positive, primes:{__Integer?PrimeQ}] :=
With[{parms = Unique[] & /@ primes},
With[{eqn = Inner[Power, primes, parms, Times]},
Floor@First@NMinimize[{eqn, eqn >= n &&
parms \[Element] Integers && And @@ (# >= 0 & /@ parms)}, parms]]]
AbsoluteTiming@Table[NextHighlyCompositeNumber[n, {2, 3, 5}], {n, 1, 10}]
(* {3.063287, {1, 2, 3, 4, 5, 6, 8, 8, 9, 10}} *)
```

Alternatively, a shorter but more explicit exposition is possible using `LinearProgramming`

:

```
NextHighlyCompositeNumber[n_Integer?Positive, primes:{__Integer?PrimeQ}] :=
Quiet@Inner[Power, primes,
LinearProgramming[Log[primes], {Log[primes]}, {Log[n]}, Automatic, Integers],
Times]
AbsoluteTiming@Table[NextHighlyCompositeNumber[n, {2, 3, 5}], {n, 1, 50}]
(* {0.140417, {1, 2, 3, 4, 5, 6, 8, 8, 9, 10, 12, 12, 15, 15, 15, 16, 18,
18, 20, 20, 24, 24, 24, 24, 25, 27, 27, 30, 30, 30, 32, 32, 36, 36,
36, 36, 40, 40, 40, 40, 45, 45, 45, 45, 45, 48, 48, 48, 50, 50}} *)
```

Idea in the latter case is to turn product-of-powers representing all possible values representable by these primes into sum-of-products by applying logarithm on all constraints. This makes the problem a dot product which is, naturally, amenable to linear programming.

Explicit `LinearProgramming`

implementation (or variant of `NMinimize`

that would have been written to the same form) is dramatically faster and numerically easier to evaluate.

**EDIT:**

Not so surprisingly, generating consecutive highly composite numbers is much faster than integer linear programming approach. This tail-recursive code achieves it (sorry, it's bit of a mess, nowhere near elegant):

```
HighlyCompositesTo[n_Integer?Positive, primes:{__Integer?PrimeQ}] :=
HighlyCompositesTo[n, primes, {1}, 1 & /@ primes, primes, Min[primes]]
HighlyCompositesTo[n_, primes_, list_, pos_, next_, min_] := list /; Last[list] >= n
HighlyCompositesTo[n_, primes_, list_, pos_, next_, min_] :=
With[{nlist = Append[list, min],
npos = MapThread[If[#1 == min, #2 + 1, #2] &, {next, pos}]},
With[{nnext = MapThread[If[#1 == min, #3 nlist[[#2]], #1] &, {next, npos, primes}]},
HighlyCompositesTo[n, primes, nlist, npos, nnext, Min[nnext]]]]
```

This performs much better than `NextHighlyCompositeNumber`

in extracting values up to 10000:

```
HighlyCompositesTo[10000, {2, 3, 5, 7}]; // AbsoluteTiming
(* {0.007496, Null} *)
NestWhileList[NextHighlyCompositeNumber[# + 1, {2, 3, 5, 7}] &,
1, # < 10000 &]; // AbsoluteTiming
(* {5.247371, Null} *)
```

Both produce the same result:

```
NestWhileList[NextHighlyCompositeNumber[# + 1, {2, 3, 5, 7}] &, 1, # < 10000 &] ==
HighlyCompositesTo[10000, {2, 3, 5, 7}]
(* True *)
```

1So, using

`RLink`

is not an option, I guess? – Leonid Shifrin – 2013-07-01T20:27:41.8103@LeonidShifrin A solution in

Mathematicaproper would be preferable. – Sasha – 2013-07-01T21:04:10.080