UPDATE: To help clarify what I'm asking I have posted a little java code that gets the idea across.
A while ago I asked a question on how to get an algorithm to break down a set of numbers, the idea was to give it a list of numbers (1,2,3,4,5)
and a total(10
) and it would figure out all the multiples of each number that would add up to the total('1*10'
or '1*1,1*2,1*3,1*4
' or '2*5
',etc..). It was the first programming exercise I ever did so it took me a while and I got it working but now I want to try to see if I can scale it. The person in the original question said it was scalable but I'm a bit confused at how to do it. The recursive part is the area I'm stuck at scaling the part that combines all the results(the table it is referring to is not scalable but applying caching I am able to make it fast)
I have the following algorithm(pseudo code):
//generates table
for i = 1 to k
for z = 0 to sum:
for c = 1 to z / x_i:
if T[z - c * x_i][i - 1] is true:
set T[z][i] to true
//uses table to bring all the parts together
function RecursivelyListAllThatWork(k, sum) // Using last k variables, make sum
/* Base case: If we've assigned all the variables correctly, list this
* solution.
*/
if k == 0:
print what we have so far
return
/* Recursive step: Try all coefficients, but only if they work. */
for c = 0 to sum / x_k:
if T[sum - c * x_k][k - 1] is true:
mark the coefficient of x_k to be c
call RecursivelyListAllThatWork(k - 1, sum - c * x_k)
unmark the coefficient of x_k
I'm really at a loss at how to thread/multiprocess the RecursivelyListAllThatWork function. I know if I send it a smaller K( which is int of total number of items in list) it will process that subset but I don't know how to do ones that combine results across the subset. For example, if list is [1,2,3,4,5,6,7,8,9,10]
and I send it K=3 then only the 1,2,3 get processed which is fine but what about if I need results that include 1 and 10? I have tried to modify the table(variable T) so only the subset I want are there but still doesn't work because, like the solution above, it does a subset but cannot process answers that require a wider range.
I don't need any code just if someone can explain how to conceptually break this recursive step to so other cores/machines can be used.
UPDATE: I still can't seem to figure out how to turn RecursivelyListAllThatWork into a runnable(I know technically how to do it, but I don't understand how to change the RecursivelyListAllThatWork algorithm so it can be ran in parallel. The other parts are just here to make the example work, I only need to implement runnable on RecursivelyListAllThatWork method). Here's the java code:
import java.awt.Point;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class main
{
public static void main(String[] args)
{
System.out.println("starting..");
int target_sum = 100;
int[] data = new int[] { 10, 5, 50, 20, 25, 40 };
List T = tableGeneator(target_sum, data);
List<Integer> coeff = create_coeff(data.length);
RecursivelyListAllThatWork(data.length, target_sum, T, coeff, data);
}
private static List<Integer> create_coeff(int i) {
// TODO Auto-generated method stub
Integer[] integers = new Integer[i];
Arrays.fill(integers, 0);
List<Integer> integerList = Arrays.asList(integers);
return integerList;
}
private static void RecursivelyListAllThatWork(int k, int sum, List T, List<Integer> coeff, int[] data) {
// TODO Auto-generated method stub
if (k == 0) {
//# print what we have so far
for (int i = 0; i < coeff.size(); i++) {
System.out.println(data[i] + " = " + coeff.get(i));
}
System.out.println("*******************");
return;
}
Integer x_k = data[k-1];
// Recursive step: Try all coefficients, but only if they work.
for (int c = 0; c <= sum/x_k; c++) { //the c variable caps the percent
if (T.contains(new Point((sum - c * x_k), (k-1))))
{
// mark the coefficient of x_k to be c
coeff.set((k-1), c);
RecursivelyListAllThatWork((k - 1), (sum - c * x_k), T, coeff, data);
// unmark the coefficient of x_k
coeff.set((k-1), 0);
}
}
}
public static List tableGeneator(int target_sum, int[] data) {
List T = new ArrayList();
T.add(new Point(0, 0));
float max_percent = 1;
int R = (int) (target_sum * max_percent * data.length);
for (int i = 0; i < data.length; i++)
{
for (int s = -R; s < R + 1; s++)
{
int max_value = (int) Math.abs((target_sum * max_percent)
/ data[i]);
for (int c = 0; c < max_value + 1; c++)
{
if (T.contains(new Point(s - c * data[i], i)))
{
Point p = new Point(s, i + 1);
if (!T.contains(p))
{
T.add(p);
}
}
}
}
}
return T;
}
}