I have a number n, and I want to find three numbers whose product is n but are as close to each other as possible. That is, if n = 12 then I’d like to get 3, 2, 2 as a result, as opposed to 6, 1, 2.
Another way to think of it is that if n is the volume of a cuboid then I want to find the lengths of the sides so as to make the cuboid as much like a cube as possible (that is, the lengths as similar as possible). These numbers must be integers.
I know there is unlikely to be a perfect solution to this, and I’m happy to use something which gives a good answer most of the time, but I just can’t think where to go with coming up with this algorithm. Any ideas?
Here’s my first algorithm sketch, granted that
nis relatively small:n.f1,f2,f3. If there are less than three factors, assign1.Edit
Let’s take
n=60.Its prime factors are
5 3 2 2.Set
f1=5,f2=3andf3=2.The remaining
2is multiplied tof3, because it is the smallest.We end up with
5 * 4 * 3 = 60.Edit
This algorithm will not find optimum, notice btillys comment:
Edit
Ok, here’s my second algorithm sketch with a slightly better heuristic:
Lto the prime factors ofn.rto the cube root ofn.F, initially set to1.L[i]with each of the factors in descending order.r, perform the multiplication and move on to the nextprime factor.
F. If out ofFs, multiply with the smallest one.This will work for the case of
17550:Iteration 1:
F[0] * 13is less thanr, setFto{13,1,1}.Iteration 2:
F[0] * 5 = 65is greated thanr.F[1] * 5 = 5is less thanr, setFto{13,5,1}.Iteration 3:
F[0] * 5 = 65is greated thanr.F[1] * 5 = 25is less thanr, setFto{13,25,1}.Iteration 4:
F[0] * 3 = 39is greated thanr.F[1] * 3 = 75is greated thanr.F[2] * 3 = 3is less thanr, setFto{13,25,3}.Iteration 5:
F[0] * 3 = 39is greated thanr.F[1] * 3 = 75is greated thanr.F[2] * 3 = 9is less thanr, setFto{13,25,9}.Iteration 6:
F[0] * 3 = 39is greated thanr.F[1] * 3 = 75is greated thanr.F[2] * 3 = 27is greater thanr, but it is the smallest F we can get. SetFto{13,25,27}.Iteration 7:
F[0] * 2 = 26is greated thanr, but it is the smallest F we can get. SetFto{26,25,27}.