箱子最优匹配法:插入物品的时候优先插入可用空间容量最小且大于物品尺寸的箱子。
由于箱子的剩余容量可能相同,所以我们采用一颗带有重复关键字的二叉搜索树来描述箱子。
节点的键为箱子剩余空间的大小,假如我们要插入物体的尺寸大小为n,我们首先比较该n与根节点的键大小,如果n小于根节点大侠则将n设为候选箱子,然后再根节点的左子树里面继续进行寻找,如果n大于左子树根节点的键,那么就得在左子树根节点的右子树进行寻找,然后重复刚才的查找方法,然后最后一个候选箱子就是我们要插入的那个箱子,然后我们更改箱子的剩余空间,删除这个箱子,然后重新将该箱子插入树中为下一次查找做准备。
下面是查找的代码:
template<class K,class E>
pair<const K,E>* dBinarySearchTreeWithGE<K,E>::findGE(const K& theKey)const
{
binaryTreeNode<pair<const K,E>>* currentNode=root;
pair<const K,E>* bestElement=NULL;//用来指向候选箱子
//对树进行搜索
while(currentNode!=NULL)//退出条件为下一搜索节点为空。
if(currentNode->element.first>=theKey)
bestElement=¤tNode->element;//currentNode是个候选者
currentNode=currentNode->leftChild;//在左子树中寻找更好的候选者
else
currentNode=currentNode->rightChild;//否则在右子树中进行寻找
return bestElement;
}
很容易理解。
void bestFitPack(int *objectSize,int numberOfObjects,int binCapacity)
{
int n=numberOfObjects;
int binUsed=0;
dBinarySearchTreeWithGE<int,int>theTree;//初始化一个空树
pair<int,int>theBin;
//将物品逐个装箱
for(int i=1;i<=n;i++)
{
pair<const int,int>* bestBin=theTree.findGE(objectSize[i]);//寻找最优的箱子
if(bestBin==NULL)
{//没有足够的箱子。启用一个新箱子
theBin.first=binCapacity;
theBin.second=++binsUsed;
}
else
{//从树theTree中删除最匹配的箱子
theBin=*bestBin;
theTree.erase(bestBin->first);
}
cout<<"pack object"<<i<<"in bin"<<theBin.second<<endl;
//将箱子插到树中,除非箱子已满
theBin.first-=objectSize[i];//更新箱子尺寸
if(theBin.first>0)
theTree.insert(theBin);//重新插入箱子
}
}
以上为匹配方法,首先初始化一个空的搜树二叉树,然后在树中寻找能插入物品的最好箱子,第一次肯定返回NULL,于是启用第一个空箱,计算空箱的剩余尺寸,然后再插入到树中,然后重复以上操作。