2

I'm looking for exact algorithm which find the best solution on task schedule in N identical processors.

The time of this algorithm is not important, the most important is one best solution (miminum time of all processors when the last task will be finished).

In theory equation describing this algorithm is as follows: P||Cmax

If anyone has an algorithm (especially in Java) or pseudocode I will be grathefull for help.

I tried write my own exact algoritm but id doesn't work :(. In the code below the permUtil is a class which corresponds for permutations.

Method args:
- tasks --> all task where index identity the task and value time
- op --> assignment processor (processor which assign a tasks)
// we have a global array op processors proc where index is identity and value is task schedule time on this processor

public void schedule(Byte[] tasks, int op)
{
    PermUtil<Byte> permA = new PermUtil<Byte>(tasks);
    Byte[] a;
    // permutation of all tasks
    while ((a = permA.next()) != null)
    {

        // assign tasks
        for(int i=1; i< a.length; i++)
        {
            // get the b set from i to end
            Byte[] b = Arrays.copyOfRange(a, i, a.length);
            // all permutations off b set
            PermUtil<Byte> permB = new PermUtil<Byte>(b);
            while ((b = permB.next()) != null)
            {
                // task on assign processor
                proc[op] = sum(Arrays.copyOfRange(a, 0, i));
                if (op < proc.length)
                    schedule(b, ++op);
                else
                {
                    proc[++op] = sum(b);
                }
            }
        }
    }
}
Przemek Nowak
  • 7,173
  • 3
  • 53
  • 57
  • 1
    Why do you assign a task to a specific processor? If you want an optimal solution, why don't you use an Executor which assigns each task to the next available thread. – Peter Lawrey Jan 13 '11 at 19:06
  • how is if(op < proc.length) { } else { proc[++op] = sum(b); } going to work. Your first test determines that op must be >= proc.length so your else clause must always throw an exception. – Peter Lawrey Jan 13 '11 at 19:08
  • Why are your comments bilingual? – rownage Jan 13 '11 at 19:12
  • I'm looking for algorithm, I'm not saying that this algorithm works, whether you have a better solution? – Przemek Nowak Jan 13 '11 at 20:01
  • 1
    For an "exact" algorithm, you generate all permutations of processor-task distribution, and then pick the one with the lowest time. Your code doesn't do that; in fact, I'm not sure what it does do. – Anon Jan 13 '11 at 20:21
  • Could you help me to write code which check all permutations of N processors? – Przemek Nowak Jan 13 '11 at 20:33

1 Answers1

2

Here's a blueprint of iterating over all the possible assignments. In a real implementation you should replace long with BigInteger, and move the array initialization outside the inner loop.

public void processOne(int nProcs, int nTasks, int[] assignment) {
    /* ... */
}

public void checkAll(int nProcs, int nTasks) {
    long count = power(nProcs, nTasks);
    /* Iterate over all the possible assignments */
    for (long j = 0; j < count; j++) {
        int[] assignment = new int[nTasks];
        for (int i = 0; i < nTasks; i++)
            assignment[i] = (int) (j / power(nProcs, i) % nProcs);
        processOne(nProcs, nTasks, assignment);
    }
}

The trick is to encode an assignment in a number. Since an assignment represents nTasks decisions, each with nProcs outcomes, it can be thought of as a number in base nProcs having nTasks digits. Every such number corresponds to a valid assignment and every assignment has a unique number in such range. It's easy to iterate over all the assignments, since we're basically iterating over a range of integers.

All you have to do is to fill in the processOne(int, int, int[]) function, which should be rather straightforward.

Bolo
  • 11,542
  • 7
  • 41
  • 60
  • I understand, index in assignment array is number of task and value is processor where task have to assign? Yes? – Przemek Nowak Jan 13 '11 at 22:44
  • Thanks, You're fantastic, You saved me a lot of time and a lot of hair from the head :) Is this algorithm use Gray's code? – Przemek Nowak Jan 13 '11 at 22:53
  • @Przemek No. First of all, Gray code is binary, while here you can have more than two processors. But even for two processors, this algorithm yields the assignments (interpreted here as binary numbers) in a different sequence than Gray code. – Bolo Jan 13 '11 at 23:04
  • 1
    @Przemek Glad I could help! If you find a question, an answer, or a comment useful, don't hesitate to "upvote" it (click on the upper triangle on the left of the post). Also, if it happens to be an answer to your question, you may choose to "accept" it (click on the hollow tick mark on the left). – Bolo Jan 13 '11 at 23:29
  • Bolo this line: assignment[i] = (int) (j / Math.pow(nProcs, i) % nProcs), whether it is a special mathematical formula with name? – Przemek Nowak Jan 14 '11 at 17:35
  • 1
    @Przemek Not that I'm aware of. I'd call it "extracting the (zero-based) i-th last digit from a number written in base nProcs". Example: let `nProcs = 10; j = 157246; i = 3`. The formula becomes: `j = 157246 / power(10, 3) % 10 = 157246 / 1000 % 10 = 157 % 10 = 7`. Warning: don't use `Math.pow(double, double)`, stick to fixed-point arithmetic instead. Write a simple `power(int, int)` function that returns a `long`. Otherwise you may loose precision. – Bolo Jan 14 '11 at 18:27