void randomtan::finalisePass()
{
assert(trainingIsFinished_ == false);
crosstab<float> cmi = crosstab<float>(noCatAtts_);
getCondMutualInf(xxyDist_, cmi);
// find the maximum spanning tree
CategoricalAttribute firstAtt = 0;
parents_[firstAtt] = NOPARENT;
float *maxWeight;
CategoricalAttribute *bestSoFar;
CategoricalAttribute topCandidate = firstAtt;
std::set<CategoricalAttribute> available;
safeAlloc(maxWeight, noCatAtts_);
safeAlloc(bestSoFar, noCatAtts_);
maxWeight[firstAtt] = -std::numeric_limits<float>::max();
//此处通过第一次遍历选择出来第一个节点之后的条件互信息最大的节点加入当前网络,并且更新
//当前剩余节点的最好的父节点信息。
for (CategoricalAttribute a = firstAtt + 1; a < noCatAtts_; a++)
{
//maxWeigt用来表示当前节点和已经加入网络中的所有节点集合中使得权重最大的节点的值
maxWeight[a] = cmi[firstAtt][a];
if (cmi[firstAtt][a] > maxWeight[topCandidate])
//opCondidate用来在还没有加入网络的节点中选择和已经加入网络的节点使得条件互信息最大的节点
topCandidate = a;
bestSoFar[a] = firstAtt;
//将除第一个节点外剩余的节点全部加入available
available.insert(a);
}
while (!available.empty())
{
//current相当于是马上就要加入网络的最优节点
const CategoricalAttribute current = topCandidate;
parents_[current] = bestSoFar[current];
//将第一个和firstAtt节点相连条件互信息最大的节点从available中除去
available.erase(current);
if (!available.empty())
{
//遍历剩余的还没有加入网络的节点
topCandidate = *available.begin();
for (std::set<CategoricalAttribute>::const_iterator it =
available.begin(); it != available.end(); it++)
{
//用来更新maxWeiight的值以及更新节点的最优父节点
//如果对于每一个还未加入网络的节点和已经在网络中的节点的条件互信息小于
//和刚刚加入的节点的条件互信息,则更新还未加入网络中节点和此时网络中节点的条件互信息。
//并且更新还未加入网络中的最优父节点信息。使其指向刚刚加入网络中的节点
if (maxWeight[*it] < cmi[current][*it])
{
maxWeight[*it] = cmi[current][*it];
bestSoFar[*it] = current;
}
//不断更新找到下一个maxWeight最大的值
if (maxWeight[*it] > maxWeight[topCandidate])
topCandidate = *it;
}
}
}
delete[] bestSoFar;
delete[] maxWeight;
trainingIsFinished_ = true;
}