It's a bit complicated to explain but here we go. Basically, the issue is "How to break up problems into subproblems in an efficient way". "Efficient" here means, the broken up subproblems are as big as possible. Basically, it would be ideal if I don't have to break up the problems at all. However, because an worker can only work on specific blocks of the problems, I do need to break up. But I want to find a way to do this as coarse as possible.
Here is some pseudo code..
We have problems like this (Sorry it's in Java. If you don't understand, I'd be glad to explain).
class Problem {
final Set<Integer> allSectionIds = { 1,2,4,6,7,8,10 };
final Data data = //Some data
}
And a subproblem is:
class SubProblem {
final Set<Integer> targetedSectionIds;
final Data data;
SubProblem(Set<Integer> targetedSectionsIds, Data data){
this.targetedSectionIds = targetedSectionIds;
this.data = data;
}
}
Work will look like this, then.
class Work implements Runnable {
final Set<Section> subSections;
final Data data;
final Result result;
Work(Set<Section> subSections, Data data) {
this.sections = SubSections;
this.data = data;
}
@Override
public void run(){
for(Section section : subSections){
result.addUp(compute(data, section));
}
}
}
Now we have instances of 'Worker', that have their own state sections I have
.
class Worker implements ExecutorService {
final Map<Integer,Section> sectionsIHave;
{
sectionsIHave = {1:section1, 5:section5, 8:section8 };
}
final ExecutorService executor = //some executor.
@Override
public void execute(SubProblem problem){
Set<Section> sectionsNeeded = fetchSections(problem.targetedSectionIds);
super.execute(new Work(sectionsNeeded, problem.data);
}
}
phew.
So, we have a lot of Problem
s and Workers
are constantly asking for more SubProblems
. My task is to break up Problems
into SubProblem
and give it to them. The difficulty is however, that I have to later collect all the results for the SubProblems and merge (reduce) them into a Result
for the whole Problem
.
This is however, costly, so I want to give the workers "chunks" that are as big as possible (has as many targetedSections
as possible).
It doesn't have to be perfect (mathematically as efficient as possible or something). I mean, I guess that it is impossible to have a perfect solution, because you can't predict how long each computation will take, etc.. But is there a good heuristic solution for this? Or maybe some resources I can read up before I go into designing?
Any advice is highly appreciated!
EDIT: We have control over the Section Allocation, too, so controlling that is another options. Basically, the only restriction on this is that a worker can only have a fixed number of sections.