Data Structures, Algorithms, & Applications in Java
Chapter 13, Exercise 33
A changeMin can be done by changing the root element
and then performing a root to leaf scan of the min heap (as in a remove
min) sliding elements up if they are smaller than the new element.
The derived class has all the public member
methods of MinHeap
plus the method changeMin.
The code for the derived class ExtendedMinHeap
is given below.
public class ExtendedMinHeap extends MinHeap
{
// constructor
public ExtendedMinHeap(int initialCapacity)
{super(initialCapacity);}
public ExtendedMinHeap()
{super();}
/** replace the current min element by theElement
* @return original min element */
public Comparable changeMin(Comparable theElement)
{
if (size == 0)
{// heap is empty, heap capacity is at least 1
heap[++size] = theElement;
return null;
}
// save min element in e
Comparable e = heap[1];
// put replacement element into the heap
int i = 1, // location of vacancy
ci = 2; // ci is child of i
while (ci <= size)
{// find place to put theElement
if (ci < size && heap[ci].compareTo(heap[ci + 1]) > 0)
ci++;
// now ci points to smaller child of i
// can we put theElement in heap[i]?
if (theElement.compareTo(heap[ci]) <= 0)
break; // yes
// no
heap[i] = heap[ci]; // move child up
// move i and ci one level down
i = ci;
ci *= 2;
}
heap[i] = theElement;
return e;
}
}
With the availability of the
changeMin
method, the code for
makeSchedule may be made more efficient.
The new code is given below. The lines that have changed are
shown in red. A test program and output
appear in the files
ImprovedLPTSchedule.*.
public static void makeSchedule(JobNode [] a, int m)
{
if (a.length <= m)
{
System.out.println("Schedule each job on a different machine.");
return;
}
HeapSort.heapSort(a); // in ascending order
// initialize m machines and the min heap
ExtendedMinHeap machineHeap = new ExtendedMinHeap(m);
for (int i = 1; i <= m; i++)
{
MachineNode x = new MachineNode(i, (Operable) a[1].time.zero());
machineHeap.put(x);
}
// construct schedule
for (int i = a.length - 1; i >= 1; i--)
{// schedule job i on first free machine
MachineNode x = (MachineNode) machineHeap.getMin();
System.out.println("Schedule job " + a[i].id
+ " on machine " + x.id + " from " + x.avail
+ " to " + x.avail.add(a[i].time));
x.avail.increment(a[i].time); // new available time for this machine
machineHeap.changeMin(x);
}
}