00001
00002
00003
00004
00005
00006
00007 #ifndef INCLUDE__SUBGRAPH_H__FILE
00008 #define INCLUDE__SUBGRAPH_H__FILE
00009
00010 #include "defs.h"
00011 #include "env.h"
00012 #include "EGException.h"
00013 #include "EGRandom.h"
00014 #include "EGTAbstractNode.h"
00015 #include "EGTVector.h"
00016
00022 template<class TN>
00023 class EGTSubGraph: public EGTAbstractNode<typename TN::Term> {
00024 public:
00025 typedef typename TN::Term Term;
00026 typedef EGTVector<Term*> Terms;
00027 typedef TN Node;
00028 typedef EGTVector<Node*> Nodes;
00029 typedef typename Nodes::Iterator NodesIterator;
00030 typedef typename Nodes::ConstIterator NodesConstIterator;
00031 typedef EGTAbstractNode<Term> Base;
00032 typedef EGTSubGraph<Node> Self;
00033
00034 static Node* m_tCreator;
00035
00037 EGTSubGraph() : Base(0, 0), m_tNodes(0), m_bOwner(false) { }
00038 EGTSubGraph(const Self&, bool);
00039 EGTSubGraph(const Nodes&, bool);
00041 virtual ~EGTSubGraph() { Clear(); }
00042
00043 virtual bool InitSubGraph(UInt uNumIn, UInt uNumOut, UInt arg = 0);
00044 virtual bool IsCompatible(const Self&) const;
00045 virtual bool ConnectSubGraph(Self&);
00046 virtual void SaveSubGraph(std::ostream&) const;
00047 virtual void Display(std::ostream&) const;
00048
00049 void Release(Nodes* dest);
00050 void SetOrigin(UInt n);
00051
00053 UInt GetNumNodes() const { return m_tNodes.Size(); }
00055 const Nodes* GetNodes() const { return &m_tNodes; }
00056
00057 bool operator==(const Self& rhs) const;
00058
00059 protected:
00060 virtual void DeepCopy(const Nodes&);
00061 virtual void RegistTerms();
00062 virtual void ConnectNodes(UInt uNumIn, UInt uNumOut);
00063
00064 Node* GetNode(UInt uNodeID);
00065 virtual void AddNode(Node*, UInt);
00066 void AddNodeNormal(Node*, UInt);
00067 void AddNodeCompleteCircuitForest(Node*, UInt);
00068
00069 void AssignNodeID();
00070 void Clear();
00071
00073 void RemoveInTerm(UInt uTermNum) {
00074 CheckNumInTerms(uTermNum, __FILE__, __LINE__);
00075 m_tInTerms.Erase(m_tInTerms.Begin()+uTermNum);
00076 }
00078 void RemoveOutTerm(UInt uTermNum) {
00079 CheckNumOutTerms(uTermNum, __FILE__, __LINE__);
00080 m_tOutTerms.Erase(m_tOutTerms.Begin()+uTermNum);
00081 }
00083 void AddInTerm(Term* pt) { m_tInTerms.PushBack(pt); }
00085 void AddOutTerm(Term* pt) { m_tOutTerms.PushBack(pt); }
00086 bool IsTermUnconnected(Term*) const;
00087
00089 Nodes m_tNodes;
00091 bool m_bOwner;
00092
00094 enum {LOOP_TIMES = 10};
00096 enum {BASE_NODE_SIZE = 5};
00097
00098 private:
00100 Self& operator=(const Self&);
00101 };
00102
00103
00104
00109 template<class TN>
00110 void EGTSubGraph<TN>::SetOrigin(UInt n)
00111 {
00112 NodesIterator itEnd = m_tNodes.End();
00113 for (NodesIterator it = m_tNodes.Begin(); it != itEnd; ++it) {
00114 (*it)->SetOrigin(n);
00115 }
00116 }
00117
00118
00128 template<class TN>
00129 EGTSubGraph<TN>::EGTSubGraph(const Self& rhs, bool owns = true)
00130 : Base(0, 0), m_tNodes(0), m_bOwner(owns)
00131 {
00132 if (owns) {
00133 DeepCopy(rhs.m_tNodes);
00134 }
00135 else {
00136 m_tNodes = rhs.m_tNodes;
00137 RegistTerms();
00138 }
00139 }
00140
00141
00147 template<class TN>
00148 EGTSubGraph<TN>::EGTSubGraph(const Nodes& rhs, bool owns = true)
00149 : Base(0, 0), m_tNodes(0), m_bOwner(owns)
00150 {
00151 if (owns) {
00152 DeepCopy(rhs);
00153 }
00154 else {
00155 m_tNodes = rhs;
00156 RegistTerms();
00157 }
00158 }
00159
00160
00169 template<class TN>
00170 bool EGTSubGraph<TN>::InitSubGraph(UInt uNumIn, UInt uNumOut, UInt arg)
00171 {
00172 UInt uMaxNodeSize = Env::Instance().MaxNodeSize();
00173
00174 Clear();
00175 Node* pn;
00176 Int iDiff;
00177 UInt uTryCount;
00178 for (uTryCount=0; uTryCount<LOOP_TIMES; ++uTryCount) {
00179 m_bOwner = true;
00180 UInt uNumNodes = EGRandom::NextInt(1, BASE_NODE_SIZE);
00181 for (UInt i=0; i<uNumNodes; ++i) {
00182 pn = m_tCreator->CreateNode();
00183 AddNode(pn, uNumOut);
00184 }
00185 iDiff = (uNumOut - uNumIn) - (GetNumOutTerms() - GetNumInTerms());
00186 while (((GetNumInTerms() < uNumIn) || (GetNumOutTerms() < uNumOut) ||
00187 (iDiff != 0)) && (GetNumNodes() < uMaxNodeSize)) {
00188 pn = m_tCreator->CreateNodeDiff(iDiff);
00189 AddNode(pn, uNumOut);
00190 iDiff = (uNumOut - uNumIn) - (GetNumOutTerms() - GetNumInTerms());
00191 }
00192 if (GetNumNodes() < uMaxNodeSize) {
00193 break;
00194 }
00195 else {
00196 Clear();
00197 }
00198 }
00199 if (uTryCount == LOOP_TIMES) {
00200 return false;
00201 }
00202 AssignNodeID();
00203 ConnectNodes(uNumIn, uNumOut);
00204 return true;
00205 }
00206
00207
00213 template<class TN>
00214 void EGTSubGraph<TN>::Release(Nodes* dest)
00215 {
00216 NodesIterator itEnd = m_tNodes.End();
00217 for (NodesIterator it = m_tNodes.Begin(); it != itEnd; ++it) {
00218 dest->PushBack(*it);
00219 }
00220 m_bOwner = false;
00221 Clear();
00222 }
00223
00224
00229 template<class TN>
00230 bool EGTSubGraph<TN>::ConnectSubGraph(Self& rhs)
00231 {
00232 UInt uRan;
00233 UInt uNumIn = GetNumInTerms();
00234 for (UInt i=0; i<uNumIn; ++i) {
00235 uRan = EGRandom::NextInt(0, rhs.GetNumOutTerms()-1);
00236 ConnectSrc(i, rhs.GetOutTerm(uRan));
00237 rhs.RemoveOutTerm(uRan);
00238 }
00239 UInt uNumOut = GetNumOutTerms();
00240 for (UInt i=0; i<uNumOut; ++i) {
00241 uRan = EGRandom::NextInt(0, rhs.GetNumInTerms()-1);
00242 ConnectDest(i, rhs.GetInTerm(uRan));
00243 rhs.RemoveInTerm(uRan);
00244 }
00245 return true;
00246 }
00247
00248
00255 template<class TN>
00256 bool EGTSubGraph<TN>::IsCompatible(const Self& rhs) const
00257 {
00258 if ((GetNumInTerms() == rhs.GetNumInTerms()) &&
00259 (GetNumOutTerms() == rhs.GetNumOutTerms())) {
00260 return true;
00261 }
00262 else {
00263 return false;
00264 }
00265 }
00266
00267
00274 template<class TN>
00275 bool EGTSubGraph<TN>::operator==(const Self& rhs) const
00276 {
00277 if (GetNumNodes() != rhs.GetNumNodes()) {
00278 return false;
00279 }
00280 const Nodes* tnodes = &(rhs.m_tNodes);
00281 bool bFind;
00282 NodesConstIterator itEnd = m_tNodes.End();
00283 NodesConstIterator itEnd2 = tnodes->End();
00284 for (NodesConstIterator it = m_tNodes.Begin(); it != itEnd; ++it) {
00285 bFind = false;
00286 for (NodesConstIterator it2 = tnodes->Begin(); it2 != itEnd2; ++it2) {
00287 if (*it == *it2) {
00288 bFind = true;
00289 break;
00290 }
00291 }
00292 if (bFind == false) {
00293 return false;
00294 }
00295 }
00296 return true;
00297 }
00298
00299
00304 template<class TN>
00305 void EGTSubGraph<TN>::Display(std::ostream& out) const
00306 {
00307 out << "NumNode: " << GetNumNodes() << ", ";
00308 out << "I/O: " << GetNumInTerms() << ',' << GetNumOutTerms() << '\n';
00309 SaveSubGraph(out);
00310 }
00311
00312
00317 template<class TN>
00318 void EGTSubGraph<TN>::SaveSubGraph(std::ostream& out) const
00319 {
00320 out << m_tNodes.Size() << ' ';
00321 NodesConstIterator itEnd = m_tNodes.End();
00322 for (NodesConstIterator it = m_tNodes.Begin(); it != itEnd; ++it) {
00323 out << (*it)->GetNodeID() << ' ';
00324 }
00325 out << '\n';
00326 }
00327
00328
00334 template<class TN>
00335 void EGTSubGraph<TN>::DeepCopy(const Nodes& rhs)
00336 {
00337
00338 NodesConstIterator itSrc = rhs.Begin();
00339 NodesConstIterator itSrcEnd = rhs.End();
00340 for (; itSrc != itSrcEnd; ++itSrc) {
00341 m_tNodes.PushBack(new Node(**itSrc));
00342 }
00343
00344 UInt uTermNum, uNodeID;
00345 NodesIterator itDest = m_tNodes.Begin();
00346 for (itSrc = rhs.Begin(); itSrc != itSrcEnd; ++itSrc, ++itDest){
00347 for (UInt i=0; i<(*itSrc)->GetNumInTerms(); ++i) {
00348 if (IsTermUnconnected((*itSrc)->GetInTerm(i)) == true) {
00349 AddInTerm((*itDest)->GetInTerm(i));
00350 }
00351 else {
00352 uNodeID = (*itSrc)->GetInTerm(i)->GetDestNodeID();
00353 uTermNum = (*itSrc)->GetInTerm(i)->GetDestTermNum();
00354 if (GetNode(uNodeID)) {
00355 (*itDest)->ConnectSrc(i, GetNode(uNodeID)->GetOutTerm(uTermNum));
00356 }
00357 }
00358 }
00359 for (UInt i=0; i<(*itSrc)->GetNumOutTerms(); ++i) {
00360 if (IsTermUnconnected((*itSrc)->GetOutTerm(i)) == true) {
00361 AddOutTerm((*itDest)->GetOutTerm(i));
00362 }
00363 }
00364 }
00365 }
00366
00367
00373 template<class TN>
00374 void EGTSubGraph<TN>::RegistTerms()
00375 {
00376 NodesIterator itEnd = m_tNodes.End();
00377 for (NodesIterator it = m_tNodes.Begin(); it != itEnd; ++it) {
00378 UInt uNumIn = (*it)->GetNumInTerms();
00379 for (UInt i=0; i<uNumIn; ++i) {
00380 if (IsTermUnconnected((*it)->GetInTerm(i))) {
00381 AddInTerm((*it)->GetInTerm(i));
00382 }
00383 }
00384 UInt uNumOut = (*it)->GetNumOutTerms();
00385 for (UInt i=0; i<uNumOut; ++i) {
00386 if (IsTermUnconnected((*it)->GetOutTerm(i))) {
00387 AddOutTerm((*it)->GetOutTerm(i));
00388 }
00389 }
00390 }
00391 }
00392
00393
00400 template<class TN>
00401 bool EGTSubGraph<TN>::IsTermUnconnected(Term* pt) const
00402 {
00403 if (pt->GetTerm() == 0) {
00404 return true;
00405 }
00406 UInt uNodeID = pt->GetDestNodeID();
00407 NodesConstIterator itEnd = m_tNodes.End();
00408 for (NodesConstIterator it = m_tNodes.Begin(); it != itEnd; ++it) {
00409 if ((*it)->GetNodeID() == uNodeID) {
00410 return false;
00411 }
00412 }
00413 return true;
00414 }
00415
00416
00424 template<class TN>
00425 void EGTSubGraph<TN>::AddNode(Node* pn, UInt uOut)
00426 {
00427 AddNodeNormal(pn, uOut);
00428 }
00429
00430
00438 template<class TN>
00439 void EGTSubGraph<TN>::AddNodeNormal(Node* pn, UInt uOut)
00440 {
00441 m_tNodes.PushBack(pn);
00442 UInt uNumIn = pn->GetNumInTerms();
00443 for (UInt i=0; i<uNumIn; ++i) {
00444 AddInTerm(pn->GetInTerm(i));
00445 }
00446 UInt uNumOut = pn->GetNumOutTerms();
00447 for (UInt i=0; i<uNumOut; ++i) {
00448 AddOutTerm(pn->GetOutTerm(i));
00449 }
00450 }
00451
00452
00461 template<class TN>
00462 void EGTSubGraph<TN>::AddNodeCompleteCircuitForest(Node* pn, UInt uOut)
00463 {
00464 UInt uRan;
00465 m_tNodes.PushBack(pn);
00466 for (UInt i=0; i<pn->GetNumOutTerms(); ++i) {
00467 if (GetNumOutTerms() < uOut) {
00468 AddOutTerm(pn->GetOutTerm(i));
00469 }
00470 else if (GetNumInTerms() > 0) {
00471 uRan = EGRandom::NextInt(0, GetNumInTerms()-1);
00472 ConnectSrc(uRan, pn->GetOutTerm(i));
00473 RemoveInTerm(uRan);
00474 }
00475 else {
00476 AddOutTerm(pn->GetOutTerm(i));
00477 }
00478 }
00479 for (UInt i=0; i<pn->GetNumInTerms(); ++i) {
00480 AddInTerm(pn->GetInTerm(i));
00481 }
00482 }
00483
00484
00490 template<class TN>
00491 void EGTSubGraph<TN>::ConnectNodes(UInt uNumIn, UInt uNumOut)
00492 {
00493 UInt uRanA, uRanB;
00494 while (GetNumOutTerms() != uNumOut) {
00495 uRanA = EGRandom::NextInt(0, GetNumInTerms()-1);
00496 uRanB = EGRandom::NextInt(0, GetNumOutTerms()-1);
00497 ConnectSrc(uRanA, GetOutTerm(uRanB));
00498 RemoveInTerm(uRanA);
00499 RemoveOutTerm(uRanB);
00500 }
00501 }
00502
00503
00507 template<class TN>
00508 void EGTSubGraph<TN>::AssignNodeID()
00509 {
00510 if (m_bOwner == false) {
00511 throw EGException("EGTSubGraph::AssignNodeID(), "
00512 "No ownership of the target Node.",
00513 __FILE__, __LINE__);
00514 }
00515 UInt i = 0;
00516 NodesIterator itEnd = m_tNodes.End();
00517 for (NodesIterator it = m_tNodes.Begin(); it != itEnd; ++it) {
00518 (*it)->SetNodeID(i++);
00519 }
00520 }
00521
00522
00523
00527 template<class TN>
00528 void EGTSubGraph<TN>::Clear()
00529 {
00530 if (m_bOwner) {
00531 NodesIterator itEnd = m_tNodes.End();
00532 for (NodesIterator it = m_tNodes.Begin(); it != itEnd; ++it) {
00533 delete (*it);
00534 }
00535 m_bOwner = false;
00536 }
00537 m_tNodes.Clear();
00538 m_tInTerms.Clear();
00539 m_tOutTerms.Clear();
00540 }
00541
00542
00548 template<class TN>
00549 TN* EGTSubGraph<TN>::GetNode(UInt uNodeID)
00550 {
00551 NodesConstIterator itEnd = m_tNodes.End();
00552 for (NodesConstIterator it = m_tNodes.Begin(); it != itEnd; ++it) {
00553 if ((*it)->GetNodeID() == uNodeID) {
00554 return *it;
00555 }
00556 }
00557 return 0;
00558 }
00559
00560
00561
00562 template<class TN>
00563 TN* EGTSubGraph<TN>::m_tCreator = 0;
00564
00565 #endif //INCLUDE__SUBGRAPH_H__FILE