#include "chain.h" #include #include chain::chain(link *linkList, int linkNum) : sentinelCost(-1) { this->linkList = new link[linkNum]; for (int i = 0; i < linkNum; i++) this->linkList[i] = linkList[i]; this->linkNum = linkNum; } chain::~chain() { for (int i= 0; i < tableSize; i++) { delete []minCostTable[i]; } delete []minCostTable; delete []linkList; } // table size may differ from linkNum for some types of chain void chain::initTable(int tableSize) { this->tableSize = tableSize; minCostTable = new partitionCost*[tableSize]; for (int i= 0; i < tableSize; i++) { minCostTable[i] = new partitionCost[tableSize]; for (int k= 0; k < tableSize; k++) { minCostTable[i][k].cost = sentinelCost; } } } double chain::minCost(int i, int k) { // indices are shifted by accessor methods // if it's already calculated, return it if (getMCTValue(i,k) > sentinelCost) return getMCTValue(i,k); // if k < i + 2, there's no cost if (k < i + 2) { setMCTValue(i, k, 0.0); setMCTSplit(i, k, i); // arbitrary split } else { double tmpMin; // candidate minimum for (int j= i + 1; j != k; j++) { tmpMin= minCost(i, j) + minCost(j, k) + componentWeight(i, j, k); if (j == i + 1 || tmpMin < getMCTValue(i,k)) { setMCTValue(i, k, tmpMin); setMCTSplit(i, k, j); } } } assert(getMCTValue(i, k) > sentinelCost); return getMCTValue(i, k); } /***************************************************************** * componentWeight: cost of one unit of the partition. * We put a trivial return value in the base class, since it is * meant to be overridden. ****************************************************************/ double chain::componentWeight(int i, int j, int k) { return 0.0; } /***************************************************************** * minPartition: list the components of this partition inOrder ****************************************************************/ componentNode *chain::minPartition(int i, int k) { componentNode *componentList= NULL, *leftList, *rightList; // make sure minCost has been calculated.. // no need to use its return value minCost(i, k); if (k - i > 1) { int j = getMCTSplit(i, k); componentList= new componentNode; assert(componentList != NULL); componentList->value.i= i; componentList->value.j= j; componentList->value.k= k; componentList->tail= componentList; // tail so far... // get inOrder lists of right and left partitions rightList= chain::minPartition(j, k); leftList= chain::minPartition(i, j); componentList->next= rightList; // works if its NULL too if (rightList != NULL) { componentList->tail= rightList->tail; } if (leftList == NULL) { leftList= componentList; // lose empty leftList } else { leftList->tail->next= componentList; } leftList->tail= componentList->tail; // leftList can't be empty componentList= leftList; } return componentList; } double chain::partitionTally(componentNode *partitionList) { double sum= 0.0; componentNode *nextNode= partitionList; while (nextNode != NULL) { sum += componentWeight(nextNode->value.i, nextNode->value.j, nextNode->value.k); nextNode= nextNode->next; } return sum; } int chain::getMCTSplit(int i, int k) { return minCostTable[i][k].j; } int chain::setMCTSplit(int i, int k, int j) { return minCostTable[i][k].j = j; } double chain::getMCTValue(int i, int k) { return minCostTable[i][k].cost; } double chain::setMCTValue(int i, int k, double d) { return minCostTable[i][k].cost = d; }