00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00028 #ifndef _DAG_H
00029 #define _DAG_H
00030
00031 #include<iostream>
00032 #include<map>
00033 #include<set>
00034 #include<vector>
00035 #include<iterator>
00036 #include<set>
00037 #include<string>
00038 #include<sstream>
00039 #include "setTemplates.C"
00040 #include <queue>
00041
00042 using namespace std;
00043
00044
00045 template< typename NodeType > class DAG;
00046
00047
00052 template< typename NodeInfo > class DAGNode
00053 {
00054 friend class DAG< DAGNode < NodeInfo > >;
00055
00056 private:
00057 NodeInfo _nodeInfo;
00058
00059 protected:
00060 set< DAGNode< NodeInfo > *> parents[3],ancestors[3];
00061 set< DAGNode< NodeInfo > *> children[3], descendants[3];
00062
00063 public:
00065 DAGNode()
00066 : _nodeInfo(), parents(), ancestors(), children(), descendants()
00067 {}
00068 DAGNode(const NodeInfo &info)
00069 : _nodeInfo(info), parents(), ancestors(), children(), descendants()
00070 {}
00071
00077 DAGNode(const DAGNode& rhs)
00078 : _nodeInfo(rhs._nodeInfo), parents(), ancestors(), children(), descendants()
00079 {}
00080
00081
00082 virtual ~DAGNode()
00083 {}
00084
00085 virtual void addChild(DAGNode< NodeInfo > *child, unsigned int type = 0)
00086 {
00087 #ifdef DEBUG
00088
00089
00090
00091
00092 #endif
00093
00094 if (isParent(child, type))
00095 cerr << "DAG::addChild(): adding child " << child->_nodeInfo.getId()
00096 << " for node " << _nodeInfo.getId() << " but child is already a parent!"
00097 << endl;
00098 children[type].insert(child);
00099
00100 children[0].insert(child);
00101
00102 }
00103
00104 virtual void addParent(DAGNode< NodeInfo > *parent, unsigned int type = 0)
00105 {
00106 #ifdef DEBUG
00107
00108
00109 #endif
00110
00111 if (isChild(parent, type))
00112 cerr << "DAG::addParent(): adding parent " << parent->_nodeInfo.getId()
00113 << " for node " << _nodeInfo.getId() << " but parent is already a child!"
00114 << endl;
00115 parents[type].insert(parent);
00116
00117 parents[0].insert(parent);
00118 }
00119
00120 virtual set< DAGNode< NodeInfo > *> getParents(unsigned int type = 0)
00121 {
00122 return(parents[type]);
00123 }
00124
00128 virtual unsigned int getParentEdgeType(DAGNode< NodeInfo > *parent)
00129 {
00130 for (unsigned int i = 1; i < 3; i++)
00131 if (isParent(parent, i))
00132 return(i);
00133
00134 cerr << "DAG::getParentEdgeType(): No edge type known for node " << _nodeInfo.getId()
00135 << " and parent " << parent->_nodeInfo.getId() << endl;
00136 return(0);
00137 }
00138
00139
00140 set< DAGNode< NodeInfo > *> getChildren(unsigned int type = 0)
00141 {
00142 return(children[type]);
00143 }
00144
00145 virtual set< DAGNode< NodeInfo > *> getAncestors(int type = 0)
00146 {
00147
00148
00149 if(ancestors[type].size()>0)
00150 return ancestors[type];
00151 ancestors[type]= parents[type];
00152 for(typename set< DAGNode< NodeInfo > *>::iterator i = parents[type].begin();
00153 i != parents[type].end(); i++)
00154 ancestors[type]= setunion((*i)->getAncestors(type), ancestors[type]);
00155
00156 return ancestors[type];
00157 }
00158
00159 virtual set< DAGNode< NodeInfo > *> getDescendants(int type = 0)
00160 {
00161
00162 if(descendants[type].size()>0)
00163 return descendants[type];
00164 descendants[type] = children[type];
00165 for(typename set< DAGNode< NodeInfo > *>::iterator i = children[type].begin();
00166 i != children[type].end(); i++)
00167 descendants[type]= setunion((*i)->getDescendants(type), descendants[type]);
00168
00169 return descendants[type];
00170 }
00171
00172
00174 virtual NodeInfo getNodeInfo() const
00175 {
00176 return(_nodeInfo);
00177 }
00178
00179
00181 virtual NodeInfo &getNodeInfo()
00182 {
00183 return(_nodeInfo);
00184 }
00185
00186
00190 virtual bool isChild(DAGNode< NodeInfo > *node, unsigned int type = 0)
00191 {
00192 return(children[type].end() != children[type].find(node));
00193
00194 }
00195
00199 virtual bool isParent(DAGNode< NodeInfo > *node, unsigned int type = 0)
00200 {
00201 return(parents[type].end() != parents[type].find(node));
00202
00203 }
00204
00205 };
00206
00207
00208
00209
00214 template< typename NodeType > class DAG
00215 {
00216
00217 protected:
00218
00219 vector< NodeType* > _nodes;
00220
00221 map< const NodeType*, unsigned int > _nodesToIndices;
00222
00223 protected:
00224
00225
00226 void _copy(const DAG< NodeType > &rhs);
00227
00228
00229 void _copyNodes(const DAG< NodeType > &rhs);
00230
00231
00232 unsigned int _getNodeIndex(const NodeType *node) const
00233 {
00234 return(_nodesToIndices.find(node)->second);
00235 }
00236
00237
00238
00239 public:
00242 DAG()
00243 : _nodes(), _nodesToIndices()
00244 {}
00245
00248 DAG(const DAG< NodeType > &rhs)
00249 {
00250 _copy(rhs);
00251 }
00252
00253
00256 DAG(istream *in);
00257
00259 virtual ~DAG()
00260 {
00261 clear();
00262 }
00263
00264
00268 const DAG< NodeType > &operator=(const DAG &rhs)
00269 {
00270 if (this != &rhs)
00271 {
00272 clear();
00273 _copy(rhs);
00274 }
00275 return(*this);
00276 }
00277
00280 void clear()
00281 {
00282 for (unsigned int i = 0; i < _nodes.size(); i++)
00283 delete _nodes[i];
00284 _nodes.clear();
00285 _nodesToIndices.clear();
00286 }
00287
00288
00295 virtual void addNode(NodeType *node)
00296 {
00297 #ifdef DEBUG
00298
00299
00300 #endif
00301 _nodes.push_back(node);
00302 _nodesToIndices[node] = _nodes.size() - 1;
00303 }
00304
00311
00312
00313
00314
00315
00316
00335 void computeDifference(DAG< NodeType> &other, DAG< NodeType> &difference);
00336
00337
00351 virtual void computePower(unsigned int exponent, DAG< NodeType> &powerDAG);
00352
00354 virtual void computeLeaves(vector< NodeType* > &leaves, unsigned int type = 0);
00355
00357 virtual void computeRoots(vector< NodeType* > &roots, unsigned int type = 0);
00358
00359
00373 virtual void computeTopologicalSort(vector< NodeType* > &sortedFunctions,
00374 unsigned int type = 0);
00375
00376
00385 virtual void computeTransitiveClosure(DAG< NodeType> &closedDAG);
00386
00399 virtual void computeTransitiveReduction(DAG< NodeType> &reducedDAG);
00400
00401
00402
00406
00407
00411
00412
00431
00432
00443
00444
00458
00459
00470
00471
00475
00476
00483
00484
00485
00486
00487
00488
00489
00490
00491
00494 unsigned int getNumEdges() const;
00495
00498 unsigned int getNumNodes() const;
00499
00506 void print(string file) const;
00507
00514 void print(ostream &ostr) const;
00515
00516
00517 };
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544 template< typename NodeType >
00545 void DAG< NodeType >::_copyNodes(const DAG< NodeType > &rhs)
00546 {
00547
00548 for (unsigned int i = 0; i < rhs._nodes.size(); i++)
00549 {
00550 addNode(new NodeType(*rhs._nodes[i]));
00551
00552
00553 }
00554 }
00555
00556 template< typename NodeType >
00557 void DAG< NodeType >::_copy(const DAG< NodeType > &rhs)
00558 {
00559 _copyNodes(rhs);
00560 unsigned int parentIndex, edgeType;
00561 NodeType *node, *parent;
00562 typename set< NodeType *>::iterator pitr;
00563
00564 for (unsigned int i = 0; i < rhs._nodes.size(); i++)
00565 {
00566 node = _nodes[i];
00567 set< NodeType *> parents = rhs._nodes[i]->getParents();
00568 for (pitr = parents.begin(); pitr != parents.end(); pitr++)
00569 {
00570 parentIndex = rhs._getNodeIndex(*pitr);
00571 parent = _nodes[parentIndex];
00572 edgeType = rhs._nodes[i]->getParentEdgeType(*pitr);
00573
00574 node->addParent(parent, edgeType);
00575 parent->addChild(node, edgeType);
00576 }
00577 }
00578 }
00579
00580 template< typename NodeType >
00581 unsigned int DAG< NodeType >::getNumEdges() const
00582 {
00583
00584 typename vector< NodeType* >::const_iterator nitr;
00585 unsigned int numEdges = 0;
00586 for (nitr = _nodes.begin(); nitr != _nodes.end(); nitr++)
00587 {
00588 set< NodeType *> parents = (*nitr)->getParents();
00589 numEdges += parents.size();
00590 }
00591 return(numEdges);
00592 }
00593
00594 template< typename NodeType >
00595 unsigned int DAG< NodeType >::getNumNodes() const
00596 {
00597 return(_nodes.size());
00598 }
00599
00600 template< typename NodeType >
00601 void DAG< NodeType >::print(string file) const
00602 {
00603 ofstream fstr(file.c_str());
00604 print(fstr);
00605 fstr.close();
00606 }
00607
00608 template< typename NodeType >
00609 void DAG< NodeType >::print(ostream &ostr) const
00610 {
00611
00612 typename vector< NodeType* >::const_iterator nitr;
00613 typename set< NodeType *>::const_iterator sitr;
00614 for (nitr = _nodes.begin(); nitr != _nodes.end(); nitr++)
00615 {
00616 set< NodeType *> parents = (*nitr)->getParents();
00617 #ifdef DEBUG
00618
00619
00620 #endif
00621 for (sitr = parents.begin(); sitr != parents.end(); sitr++)
00622 ostr << (*nitr)->_nodeInfo.getId()
00623 << "\t" << (*sitr)->_nodeInfo.getId()
00624 << "\t" << (*nitr)->getParentEdgeType(*sitr)
00625 << endl;
00626 }
00627
00628 }
00629
00630 template< typename NodeType >
00631 void DAG< NodeType >::computeDifference(DAG< NodeType> &other,
00632 DAG< NodeType> &difference)
00633 {
00634
00636 difference._copyNodes(*this);
00637
00638
00639
00640
00641
00642
00643
00644 typename set< NodeType * >::iterator pitr;
00645 NodeType *nodeInOther, *nodeInDifference, *parentInOther, *parentInDifference;
00646 unsigned int parentIndex, parentEdgeType;
00647
00648 for (unsigned int i = 0; i < _nodes.size(); i++)
00649 {
00650 nodeInOther = other._nodes[i];
00651 nodeInDifference = difference._nodes[i];
00652 set< NodeType *> parents = _nodes[i]->getParents();
00653 for (pitr = parents.begin(); pitr != parents.end(); pitr++)
00654 {
00655 parentIndex = _getNodeIndex(*pitr);
00656 parentInOther = other._nodes[parentIndex];
00657 parentEdgeType = _nodes[i]->getParentEdgeType(*pitr);
00658 if (nodeInOther->isParent(parentInOther))
00659
00660 continue;
00661
00662
00663
00664 parentInDifference = difference._nodes[parentIndex];
00665 nodeInDifference->addParent(parentInDifference, parentEdgeType);
00666 parentInDifference->addChild(nodeInDifference, parentEdgeType);
00667 }
00668 }
00669
00670 }
00671
00672 template< typename NodeType >
00673 void DAG< NodeType >::computeLeaves(vector< NodeType* > &leaves, unsigned int type)
00674 {
00675 for (unsigned int i = 0; i < _nodes.size(); i++)
00676 {
00677 if (0 == _nodes[i]->getChildren(type).size())
00678
00679 leaves.push_back(_nodes[i]);
00680 }
00681 }
00682
00683 template< typename NodeType >
00684 void DAG< NodeType >::computePower(unsigned int exponent, DAG< NodeType> &powerDAG)
00685 {
00686 if (0 == exponent)
00687 return;
00688 if (1 == exponent)
00689 {
00690 powerDAG = *this;
00691 return;
00692 }
00693 DAG< NodeType > grandparentDAG;
00694 if (2 < exponent)
00695
00696 {
00697 computePower(exponent - 1, grandparentDAG);
00698 }
00699 else
00700 grandparentDAG = *this;
00701
00702
00703
00704
00705
00706
00707 powerDAG._copyNodes(*this);
00708
00709
00710
00711
00712
00713
00714 NodeType *nodeInDAG, *parentInGrandparentDAG, *grandparentInPowerDAG;
00715 typename set< NodeType *>::iterator pitr, gitr;
00716 unsigned int grandparentIndex;
00717
00718 for (unsigned int i = 0; i < _nodes.size(); i++)
00719 {
00720
00721 set< NodeType *> parents = _nodes[i]->getParents();
00722 for (pitr = parents.begin(); pitr != parents.end(); pitr++)
00723 {
00724
00725 parentInGrandparentDAG = grandparentDAG._nodes[_getNodeIndex(*pitr)];
00726
00727 set< NodeType *> grandparents = parentInGrandparentDAG->getParents();
00728 for (gitr = grandparents.begin(); gitr != grandparents.end(); gitr++)
00729 {
00730
00731
00732
00733 grandparentIndex = grandparentDAG._getNodeIndex(*gitr);
00734 grandparentInPowerDAG = powerDAG._nodes[grandparentIndex];
00735 powerDAG._nodes[i]->addParent(grandparentInPowerDAG);
00736 grandparentInPowerDAG->addChild(powerDAG._nodes[i]);
00737 }
00738 }
00739 }
00740 }
00741
00742
00743 template< typename NodeType >
00744 void DAG< NodeType >::computeRoots(vector< NodeType* > &roots, unsigned int type)
00745 {
00746 for (unsigned int i = 0; i < _nodes.size(); i++)
00747 {
00748 if (0 == _nodes[i]->getParents(type).size())
00749
00750 roots.push_back(_nodes[i]);
00751 }
00752 }
00753
00754 template< typename NodeType >
00755 void DAG< NodeType >::computeTopologicalSort(vector< NodeType* > &sortedNodes,
00756 unsigned int type)
00757 {
00758 map< NodeType *, unsigned int > numVisitedParents;
00759 set< NodeType * > roots;
00760 deque< NodeType * > nodeQueue;
00761 for (unsigned int i = 0; i < _nodes.size(); i++)
00762 {
00763
00764 numVisitedParents[_nodes[i]] = 0;
00765 if (0 == _nodes[i]->getParents(type).size())
00766
00767 roots.insert(_nodes[i]);
00768
00769 }
00770 NodeType *nextNode;
00771
00772 while (!nodeQueue.empty() || !roots.empty())
00773 {
00774 if (nodeQueue.empty())
00775
00776
00777
00778
00779 {
00780 nodeQueue.push_back(*(roots.begin()));
00781 roots.erase(roots.begin());
00782 }
00783
00784 nextNode = nodeQueue.front();
00785 nodeQueue.pop_front();
00786 sortedNodes.push_back(nextNode);
00787
00788 set< NodeType *> children = nextNode->getChildren(type);
00789 typename set< NodeType* >::const_iterator itr;
00790
00791 for (itr = children.begin();
00792 itr != children.end(); itr++)
00793 {
00794 numVisitedParents[*itr]++;
00795
00796 if (numVisitedParents[*itr] == (*itr)->getParents().size())
00797 nodeQueue.push_back(*itr);
00798 }
00799 }
00800 }
00801
00802 template< typename NodeType >
00803 void DAG< NodeType >::computeTransitiveClosure(DAG< NodeType> &closedDAG)
00804 {
00805 cout << "DAG has " << getNumNodes() << " nodes and " << getNumEdges()
00806 << " edges." << endl;
00807
00808
00809 closedDAG = *this;
00810 cout << "Copy of DAG has " << closedDAG.getNumNodes() << " nodes and "
00811 << closedDAG.getNumEdges() << " edges." << endl;
00812
00813
00814
00815
00816 unsigned int numClosureEdges = 0;
00817 typename set< NodeType *>::iterator aitr;
00818
00819 for (unsigned int i = 0; i < closedDAG._nodes.size(); i++)
00820 {
00821 cout << "DAG::computeTransitiveClosure(): Processing " << closedDAG._nodes[i]->_nodeInfo.getId() << endl;
00822
00823 set< NodeType *> ancestors = closedDAG._nodes[i]->getAncestors();
00824 for (aitr = ancestors.begin(); aitr != ancestors.end(); aitr++)
00825
00826 {
00827 cout << "\tChild " << closedDAG._nodes[i]->_nodeInfo.getId()
00828 << ", parent " << (*aitr)->_nodeInfo.getId() << endl;
00829 closedDAG._nodes[i]->addParent(*aitr);
00830 (*aitr)->addChild(closedDAG._nodes[i]);
00831 numClosureEdges++;
00832 }
00833 }
00834 cout << "DAG< NodeType >::computeTransitiveClosure(): added "
00835 << numClosureEdges << " edges to the transitive closure." << endl;
00836 cout << "Transitive closure of DAG has " << closedDAG.getNumNodes() << " nodes and "
00837 << closedDAG.getNumEdges() << " edges." << endl;
00838 }
00839
00840
00841
00842 template< typename NodeType >
00843 void DAG< NodeType >::computeTransitiveReduction(DAG< NodeType> &reducedDAG)
00844 {
00845 cout << "DAG has " << getNumNodes() << " nodes and "
00846 << getNumEdges() << " edges." << endl;
00847 DAG< NodeType > closedDAG, squareClosedDAG;
00848
00849
00850 closedDAG = *this;
00851 cout << "Copy of DAG has "
00852 << closedDAG.getNumNodes() << " nodes and "
00853 << closedDAG.getNumEdges() << " edges." << endl;
00854
00855
00856 closedDAG.computePower(2, squareClosedDAG);
00857 cout << "Square of transitive closure of DAG has "
00858 << squareClosedDAG.getNumNodes() << " nodes and "
00859 << squareClosedDAG.getNumEdges() << " edges." << endl;
00860
00861
00862 closedDAG.computeDifference(squareClosedDAG, reducedDAG);
00863 cout << "Transitive reduction of DAG has "
00864 << reducedDAG.getNumNodes() << " nodes and "
00865 << reducedDAG.getNumEdges() << " edges." << endl;
00866 }
00867
00868
00869 #endif // _DAG_H
00870