You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

193 lines
4.2KB

  1. /* Graph Sort
  2. * Copyleft (C) 2002 David Griffiths <dave@pawfal.org>
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 2 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  17. */
  18. #include <iostream>
  19. #include "GraphSort.h"
  20. //#define GRAPHSORT_TRACE
  21. //////////////////////////////////////////////////////////
  22. GraphSort::GraphSort()
  23. {
  24. }
  25. GraphSort::~GraphSort()
  26. {
  27. }
  28. void GraphSort::Clear()
  29. {
  30. //m_Sorted.clear();
  31. m_Graph.clear();
  32. }
  33. const list<int> &GraphSort::GetSortedList()
  34. {
  35. return m_Sorted;
  36. }
  37. void GraphSort::Sort()
  38. {
  39. // walk back from all the roots
  40. m_Sorted.clear();
  41. list<int> RootNodes;
  42. for (map<int,Node>::iterator i=m_Graph.begin();
  43. i!=m_Graph.end(); i++)
  44. {
  45. // if there are no outputs, this must be a root
  46. if (i->second.Outputs.empty())
  47. {
  48. RecursiveWalk(i->first);
  49. }
  50. }
  51. #ifdef GRAPHSORT_TRACE
  52. for(list<int>::iterator i=m_Sorted.begin();
  53. i!=m_Sorted.end(); i++)
  54. {
  55. cerr<<*i<<" ";
  56. }
  57. cerr<<endl;
  58. #endif
  59. }
  60. void GraphSort::RecursiveWalk(int node)
  61. {
  62. // check it's not been logged already
  63. // (don't want to execute the node twice)
  64. if(find(m_Sorted.begin(),m_Sorted.end(),node)==m_Sorted.end())
  65. {
  66. #ifdef GRAPHSORT_TRACE
  67. //cerr<<"adding "<<node<<" to list"<<endl;
  68. #endif
  69. m_Sorted.push_back(node);
  70. }
  71. else
  72. {
  73. #ifdef GRAPHSORT_TRACE
  74. //cerr<<"Node "<<node<<" already logged, ending this path"<<endl;
  75. #endif
  76. return;
  77. }
  78. // branch back into the inputs
  79. map<int,Node>::iterator i=m_Graph.find(node);
  80. for(list<int>::iterator ii=i->second.Inputs.begin();
  81. ii!=i->second.Inputs.end(); ii++)
  82. {
  83. RecursiveWalk(*ii);
  84. }
  85. }
  86. void GraphSort::Dump()
  87. {
  88. for (map<int,Node>::iterator i=m_Graph.begin();
  89. i!=m_Graph.end(); i++)
  90. {
  91. cerr<<"Node "<<i->first<<endl;
  92. cerr<<"i=";
  93. for (list<int>::iterator ii=i->second.Inputs.begin();
  94. ii!=i->second.Inputs.end(); ii++)
  95. {
  96. cerr<<*ii<<" ";
  97. }
  98. cerr<<endl<<"o=";
  99. for (list<int>::iterator oi=i->second.Outputs.begin();
  100. oi!=i->second.Outputs.end(); oi++)
  101. {
  102. cerr<<*oi<<" ";
  103. }
  104. cerr<<endl;cerr<<endl;
  105. }
  106. }
  107. void GraphSort::AddConnection(int SID, int DID)
  108. {
  109. map<int,Node>::iterator si=m_Graph.find(SID);
  110. if (si==m_Graph.end())
  111. {
  112. Node newnode;
  113. m_Graph[SID]=newnode;
  114. #ifdef GRAPHSORT_TRACE
  115. cerr<<"added "<<SID<<endl;
  116. #endif
  117. }
  118. map<int,Node>::iterator di=m_Graph.find(DID);
  119. if (di==m_Graph.end())
  120. {
  121. Node newnode;
  122. m_Graph[DID]=newnode;
  123. #ifdef GRAPHSORT_TRACE
  124. cerr<<"added "<<DID<<endl;
  125. #endif
  126. }
  127. m_Graph[SID].Outputs.push_back(DID);
  128. m_Graph[DID].Inputs.push_back(SID);
  129. Sort();
  130. }
  131. void GraphSort::RemoveConnection(int SID, int DID)
  132. {
  133. map<int,Node>::iterator si=m_Graph.find(SID);
  134. if (si==m_Graph.end())
  135. {
  136. cerr<<"GraphSort::RemoveConnection - can't find source node"<<endl;
  137. }
  138. map<int,Node>::iterator di=m_Graph.find(DID);
  139. if (di==m_Graph.end())
  140. {
  141. cerr<<"GraphSort::RemoveConnection - can't find dest node"<<endl;
  142. }
  143. list<int>::iterator soi = find(si->second.Outputs.begin(), si->second.Outputs.end(), DID);
  144. if (soi==si->second.Outputs.end()) cerr<<"GraphSort::RemoveConnection - can't find soi"<<endl;
  145. else si->second.Outputs.erase(soi);
  146. list<int>::iterator dii = find(di->second.Inputs.begin(), di->second.Inputs.end(), SID);
  147. if (dii==di->second.Inputs.end()) cerr<<"GraphSort::RemoveConnection - can't find dii"<<endl;
  148. else di->second.Inputs.erase(dii);
  149. // check to remove the nodes
  150. if (si->second.Outputs.empty() && si->second.Inputs.empty())
  151. {
  152. m_Graph.erase(si);
  153. #ifdef GRAPHSORT_TRACE
  154. cerr<<"removed "<<SID<<endl;
  155. #endif
  156. }
  157. if (di->second.Outputs.empty() && di->second.Inputs.empty())
  158. {
  159. m_Graph.erase(di);
  160. #ifdef GRAPHSORT_TRACE
  161. cerr<<"removed "<<DID<<endl;
  162. #endif
  163. }
  164. Sort();
  165. }