Back to Top page.

EGTSubGraph.h

Go to the documentation of this file.
00001 /****************************************************************************
00002 
00003 $Id: EGTSubGraph.h,v 1.7 2002/12/17 10:22:24 motegi Exp $
00004 Copyright (C) 2002 Higuchi Lab. All rights reserved.
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);                 // for AddNode
00067   void AddNodeCompleteCircuitForest(Node*, UInt);  // for AddNode
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; //Releases ownership
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   //Makes a deep copy of the array of Nodes.
00338   NodesConstIterator itSrc    = rhs.Begin();
00339   NodesConstIterator itSrcEnd = rhs.End();
00340   for (; itSrc != itSrcEnd; ++itSrc) {
00341     m_tNodes.PushBack(new Node(**itSrc));
00342   }
00343   //Reproduces the edge information.
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