Data Structures, Algorithms, & Applications in Java
Chapter 14, Exercise 27
To implement the next fit strategy using the pseudocode
of Section 14.5.2, we must extend the class
ExtendedCWTree to include the method
parent(i), which returns the internal
node that is the parent if the external node
i.
The code for
parent(i) is given below.
public class ExtendedCWTree2 extends ExtendedCWTree
{
/** @return parent of the external node i */
public int parent(int i)
{
if (i < 1 || i >= player.length)
throw new IllegalArgumentException
("tree does not have an external node " + i);
if (i <= lowExt)
return (i + offset) / 2;
else
return (i - lowExt + player.length) / 2;
}
}
The code for nextFitPack is given below.
This code follows the pseudocode fairly closely.
public class NextFit
{
/** output next fit packing into bins of size c
* @param s[1:s.length-1] gives object size */
public static void nextFitPack(int s[], int c)
{
int n = s.length - 1; // number of objects
FirstFit.Bin [] bin = new FirstFit.Bin [n + 1]; // bins
ExtendedCWTree2 winTree = new ExtendedCWTree2();
// initialize n bins and winner tree
for (int i = 1; i <= n; i++)
bin[i] = new FirstFit.Bin(c); // initial unused capacity
winTree.initialize(bin);
int last = 0; // bin used for last object packed
// put objects in bins
for (int i = 1; i <= n; i++)
{// put s[i] in a bin
// see if there is a nonempty bin to the
// right of bin last that has enough capcity
// set j to next bin with enough capacity
int j = last + 1;
if (bin[j].unusedCapacity < s[i])
// there must be another bin j+1
if (bin[j + 1].unusedCapacity >= s[i])
j++;
else
{// move up the tree
// set p to parent of bin j
int p = winTree.parent(j);
boolean done = false;
if (p == n - 1)
{// special case
int q;
if (j % 2 == 1)
q = j + 1;
else
q = j + 2;
// q must be <= n
if (bin[q].unusedCapacity >= s[i])
{
j = q;
done = true;
}
}
if (!done)
{// move to nearest ancestor of p with enough capacity
p /= 2;
while (bin[winTree.getWinner(p)].unusedCapacity < s[i])
p /= 2;
// now move to leftmost child of p that has enough capacity
p *= 2; // start search at left child
while (p < n)
{
int winp = winTree.getWinner(p);
if (bin[winp].unusedCapacity < s[i])
// first bin is in right subtree
p++ ;
p *= 2; // move to left child
}
p /= 2; // undo last left child move
if (p < n)
{// at a tree node
j = winTree.getWinner(p);
// if j is right child, need to check
// bin j-1. No harm done by checking
// bin j-1 even if j is left child.
if (j > 1 && bin[j - 1].unusedCapacity >= s[i])
j--;
}
else // arises when n is odd
j = winTree.getWinner(p / 2);
}
}
// see if bin j is nonempty
if (bin[j].unusedCapacity == c)
{// empty bin, execute step 2
// find leftmost bin with enough capacity
int p = 2; // start search at left child of root
while (p < n)
{
int winp = winTree.getWinner(p);
if (bin[winp].unusedCapacity < s[i])
// first bin is in right subtree
p++ ;
p *= 2; // move to left child
}
p /= 2; // undo last left child move
if (p < n)
{// at a tree node
j = winTree.getWinner(p);
// if j is right child, need to check
// bin j-1. No harm done by checking
// bin j-1 even if j is left child.
if (j > 1 && bin[j - 1].unusedCapacity >= s[i])
j--;
}
else // arises when n is odd
j = winTree.getWinner(p / 2);
}
System.out.println("Pack object " + i + " in bin " + j);
bin[j].unusedCapacity -= s[i];
winTree.rePlay(j);
last = j;
}
}
}