This is a variation of subset-sum problem, the answer to the classic problem involving only integers is pretty easy using DP, and can be found in many threads around StackOverflow, like this one.
However, there is a small tweak in your problem that makes it just slightly different from the classic integer subset-sum problem - you are dealing with values that don't have to be integers, they also have a decimal value.
It seems that in your case, the decimal value is up to 2 digits "after the dot". This means, you can easily transform your problem into a classic integers subset-sum problem by simply multiplying all your values in the array by 100, and search for 100*x
instead of x
.
In your example - you will need to look for 12,369 in the array of integer values {123, 345, 2011, 10013, 20008}
.
Attachment 1:
Solving SubsetSum Problem for integers:
This is done using Dynamic Programming, where the recursive formulas for the DP is:
f(x,0) = FALSE if x<0
f(0,0) = TRUE
f(x,i) = f(x,i-1) OR f(x-arr[i], i-1)
By calculating the above bottom-up, you get a matrix of size (W*100+1) x (n+1)
(where W
is your requested sum and n
is the number of elements in the array).
By searching for the column in the LAST row that holds the value true
when you are done - you found the "best" possible sum that is up to your number.
Attachment 2: Finding the actual subset of numbers.
By now, you have found the best sum you can get, but not the best numbers yet. In order to do so, you will need to use your matrix (which you calculated previously), and replay the steps you did in order to generate this sum. This is explained for a similar problem in this thread, and in nutshell it is done by:
line <- BEST //best solution found
i <- n
while (i> 0):
if table[line-array[i]][i-1] == TRUE:
the element 'i' is in the set
i <- i-1
line <- line-array[i]
else:
i <- i-1
Note: If this is too complex, and the size of your arrays is fairly small, or alternatively the "2 decimals after the dot" restriction is not true - you pretty much have to use an exponential solution - brute force, which creates all possible subsets, and chooses the best out of them. There is no (known) efficient solution in this case because this problem is known to be NP-Hard
tl;dr:
Multiply all values by 100, and then use an existing integers subset-sum problem algorithm to find the best fit.