graph.c 71 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696
  1. /*!
  2. Temelia - Graph algorithms implementation source file
  3. Copyright (C) 2008 Ceata (http://ceata.org/proiecte/temelia)
  4. @author Dascalu Laurentiu
  5. This program is free software; you can redistribute it and
  6. modify it under the terms of the GNU General Public License
  7. as published by the Free Software Foundation; either version 3
  8. of the License, or (at your option) any later version.
  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. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  16. */
  17. #include "include/graph.h"
  18. #include "include/vector.h"
  19. #include "include/queue.h"
  20. #include "include/pair.h"
  21. #include "include/sort.h"
  22. #include "include/heap.h"
  23. #include <stdlib.h>
  24. struct _graph_t
  25. {
  26. /*! Maximum number of vertices */
  27. unsigned int size;
  28. /*! Array of vertices */
  29. vector_t vertices;
  30. /*! Graph context */
  31. void *graph;
  32. /*! Vertex delete function */
  33. void (*vertex_delete)(vertex_t);
  34. /*! Edge delete function */
  35. void(*edge_delete)(edge_t);
  36. /*! Pointer to the graph implementation */
  37. graph_implementation_t implementation;
  38. };
  39. // === Private functions declaration ===
  40. /*!
  41. * @brief DFS travel starting from node.
  42. * Complexity O(V)
  43. *
  44. * @param Graph
  45. * @param Node identifier
  46. */
  47. static void _graph_dfs(graph_t graph, unsigned int node);
  48. /*!
  49. * @brief BFS travel.
  50. * Complexity O(V)
  51. *
  52. * @param Graph
  53. * @param Node identifier
  54. */
  55. static void _graph_bfs(graph_t graph, unsigned int node);
  56. /*!
  57. * @brief Time variable, used to synchronize operations.
  58. * Library doesn't export it because user shouldn't care about this variable.
  59. */
  60. static unsigned int current_time = 0;
  61. /*!
  62. * @brief Resets parameters of all vertices to their default value :
  63. * 1. unvisited
  64. * 2. colored with WHITE
  65. * 3. parent nil (-1)
  66. * 4. time_start and time_travel 0
  67. * Complexity O(V)
  68. *
  69. * @param Graph
  70. */
  71. static void _graph_reset_vertices(graph_t graph);
  72. /*!
  73. * @brief Core function for finding articulation points. It's based on DFS and compares times
  74. * when vertices are discovered in order to find the cut-vertices.
  75. * Complexity O(E/V))
  76. *
  77. * @param Graph
  78. * @param Current node
  79. * @param Color array
  80. * @param Time start array
  81. * @param Low time array
  82. * @param Parent array
  83. * @param Cut-vertex array. A vertex v is cut-vertex only if cut_vertex[v] = 1
  84. */
  85. unsigned int _articulation_points_travel(graph_t graph, unsigned int u,
  86. int *color, unsigned int *start, unsigned int *low,
  87. unsigned int *parent, int *cut_vertex);
  88. /*!
  89. * @brief Modified DFS travel used to find cycles contained by a graph.
  90. * Complexity O(V)
  91. *
  92. * @param Graph
  93. * @param Current node
  94. * @param Linked list where the next cycle is stored
  95. * @param Pointer to parent
  96. * @param Pointer to color
  97. * @param Pointer to visited
  98. * */
  99. static void _cycles_travel(graph_t graph, unsigned int current_node,
  100. linked_list_t current_cycles, unsigned int *parent, int *color,
  101. int *visited);
  102. /*!
  103. * @brief Rebuilds the path from current_node to next_node, basing on parents vector.
  104. * Complexity O(V)
  105. *
  106. * @param Current node identifier
  107. * @param Next node identifier
  108. * @param Parent array
  109. * @param Linked list where the cycle will be stored
  110. */
  111. static void _rebuild_cycle(unsigned int current_node, unsigned int next_node,
  112. unsigned int *parent, linked_list_t small_cycle);
  113. /*!
  114. * @brief Comparison function used by Kruskal's algorithm to compare set nodes.
  115. * @param First node identifier.
  116. * @param Second node identifier.
  117. */
  118. static int _compare_nodes_unsigned(void *x, void *y, void *context);
  119. /*!
  120. * @brief Internal function comparing time of two unsigned int vertex identifiers.
  121. */
  122. static int _compare_nodes_strongly_connected_components(void *x, void *y,
  123. void *context);
  124. /*!
  125. * @brief Comparison function used by Dijkstra's algorithm. It uses as context the distance vector.
  126. * @param First vertex identifier.
  127. * @param Second vertex identifier.
  128. */
  129. static int _compare_dijkstra(void *x, void *y, void *context);
  130. /*!
  131. * @brief Comparison function used by Prim's algorithm. It uses as context a pointer to minimum weights.
  132. * @param First vertex identifier
  133. * @param Second vertex identifier
  134. */
  135. static int _compare_prim(void *x, void *y, void *context);
  136. /*!
  137. * @brief Comparison function used by Kruskal's algorithm to sort edges by their cost.
  138. * @param First edge reference
  139. * @param Second edge reference
  140. */
  141. static int _compare_edges_kruskal(void *x, void *y, void *context);
  142. /*!
  143. * @brief Comparison function used by Kruskal's algorithm to compare set nodes.
  144. * @param First node identifier
  145. * @param Second node identifier
  146. */
  147. static int _compare_nodes_kruskal(void *x, void *y, void *context);
  148. /*!
  149. * @brief Sets the flow matrix keys to 0 double value.
  150. * Complexity O(V*V)
  151. *
  152. * @param Flow matrix
  153. */
  154. static void _init_flow(matrix_t flow);
  155. /*!
  156. * @brief Returns the minimum flow over a path in graph.
  157. * Complexity O(V)
  158. *
  159. * @param Graph
  160. * @param Flow matrix
  161. * @param Path list
  162. */
  163. static double _min_flow_path(graph_t graph, matrix_t max_flow,
  164. linked_list_t path);
  165. /*!
  166. * @brief Computes max_flow using DFS travel - used by Ford-Fulkerson algorithm.
  167. * Complexity O(E*max_flow)
  168. *
  169. * @param Graph
  170. * @param Start node identifier - source; this variable is changing because DFS travels
  171. * the vertices in a recursive way
  172. * @param End node identifier - destination
  173. * @param Path, where the result is stored
  174. * @param Max flow matrix
  175. */
  176. static void _flow_dfs(graph_t graph, unsigned int current_node,
  177. unsigned int destination, linked_list_t path, matrix_t max_flow);
  178. /*!
  179. * @brief Computer max_flow using BFS travel - used by Edmonds-Karp algorithm.
  180. * Complexity O(V*E*E)
  181. *
  182. * @param Graph
  183. * @param Start node identifier - source
  184. * @param End node identifier - destination
  185. * @param Path, where the result is stored
  186. * @param Max flow matrix
  187. */
  188. static void _flow_bfs(graph_t graph, unsigned int source,
  189. unsigned int destination, linked_list_t path, matrix_t max_flow);
  190. /*!
  191. * @brief Iterates over a path and actualizes the flow on it; the function add the min_flow to
  192. * all the edges from the path.
  193. * Complexity O(V)
  194. *
  195. * @param Flow matrix
  196. * @param Path
  197. * @param Minimum flow value
  198. */
  199. static void _add_flow_on_path(matrix_t max_flow, linked_list_t path,
  200. double min_flow);
  201. /*!
  202. * @brief Returns the capacity of edge between vertices i and j.
  203. * Complexity O(1)
  204. *
  205. * @param Graph
  206. * @param First vertex identifier
  207. * @param Second vertex identifier
  208. */
  209. INLINE static double CAPACITY(graph_t graph, unsigned int i, unsigned int j);
  210. /*!
  211. * @brief Returns the flow of edge between vertices i and j.
  212. * Complexity O(1)
  213. *
  214. * @param Flow matrix
  215. * @param First vertex identifier
  216. * @param Second vertex identifier
  217. */
  218. INLINE static double FLOW(matrix_t max_flow, unsigned int i, unsigned int j);
  219. // === End ===
  220. graph_t graph_new(unsigned int max, graph_implementation_t implementation,
  221. void(*m_vertex_delete)(vertex_t), void(*m_edge_delete)(edge_t))
  222. {
  223. graph_t graph;
  224. LOGGER(
  225. "[graph new] max size %u, implementation %p, vertex destructor %p, edge destructor\n",
  226. max, implementation, m_vertex_delete, m_edge_delete);
  227. _ASSERT(max, <=, 0, INVALID_INPUT, NULL);
  228. _ASSERT(implementation, ==, NULL, NULL_POINTER, NULL);
  229. graph = (struct _graph_t *) _new(sizeof(struct _graph_t));
  230. graph->size = max;
  231. graph->implementation = implementation;
  232. graph->graph = graph->implementation->new_g(max);
  233. _ASSERT(graph->graph, ==, NULL, NULL_POINTER, NULL);
  234. graph->vertices = vector_new(max);
  235. _ASSERT(graph->vertices, ==, NULL, NULL_POINTER, NULL);
  236. if (m_vertex_delete)
  237. graph->vertex_delete = m_vertex_delete;
  238. else
  239. graph->vertex_delete = vertex_delete;
  240. if (m_edge_delete)
  241. graph->edge_delete = m_edge_delete;
  242. else
  243. graph->edge_delete = edge_delete;
  244. // free() is the default destructor
  245. if (graph->implementation->delete_vertex_context == NULL)
  246. graph->implementation->delete_vertex_context = (void(*)(void **)) free;
  247. return graph;
  248. }
  249. static void _graph_delete_edge(edge_t key, void *context)
  250. {
  251. ((void(*)(edge_t)) context)(key);
  252. }
  253. void graph_delete(graph_t graph)
  254. {
  255. unsigned int i;
  256. LOGGER("[graph delete] graph %p\n", graph);
  257. _ASSERT(graph, ==, NULL, NULL_POINTER,);
  258. graph->implementation->iterate_edges(graph->graph, _graph_delete_edge,
  259. graph->edge_delete);
  260. graph->implementation->delete_g(graph->graph);
  261. for (i = 0; i < graph->size; i++)
  262. graph->vertex_delete(vector_get_key_at(graph->vertices, i));
  263. vector_delete(graph->vertices);
  264. graph->size = 0;
  265. _delete(graph);
  266. }
  267. unsigned int graph_add_vertex(graph_t graph, char *label, void *key)
  268. {
  269. unsigned int i, n;
  270. int empty_place = 0;
  271. vertex_t vertex;
  272. LOGGER("[graph add vertex] graph %p, label %s, key %p\n", graph, label, key);
  273. _ASSERT(graph, ==, NULL, NULL_POINTER, (unsigned int) -1);
  274. _ASSERT((unsigned int) vector_get_size(graph->vertices), >= , graph->size, FULL, (unsigned int) -1);
  275. vertex = vertex_new(label, (unsigned int) vector_get_size(graph->vertices), key);
  276. _ASSERT(vertex, ==, NULL, NULL_POINTER, -1);
  277. // Find an empty place to insert the vertex.
  278. n = vector_get_size(graph->vertices);
  279. for (i = 0; i < n; i++)
  280. {
  281. if (vector_get_key_at(graph->vertices, i) == NULL)
  282. {
  283. vector_set_key_at(graph->vertices, i, vertex);
  284. empty_place = 1;
  285. break;
  286. }
  287. }
  288. if (empty_place)
  289. return i;
  290. // If no empty place found, add the vertex to the end
  291. vector_push_back(graph->vertices, vertex);
  292. return vector_get_size(graph->vertices) - 1;
  293. }
  294. vertex_t graph_remove_vertex(graph_t graph, unsigned int identifier)
  295. {
  296. vertex_t vertex;
  297. unsigned int i, n;
  298. LOGGER("[graph remove vertex] graph %p, vertex %u\n", graph, identifier);
  299. _ASSERT(graph, ==, NULL, NULL_POINTER, NULL);
  300. _ASSERT(identifier, >=, (unsigned int) vector_get_size(graph->vertices), EMPTY, NULL);
  301. vertex = vector_get_key_at(graph->vertices, identifier);
  302. vector_set_key_at(graph->vertices, identifier, NULL);
  303. if (graph->implementation->delete_vertex_edges)
  304. graph->implementation->delete_vertex_edges(graph->graph, identifier,
  305. graph->edge_delete);
  306. else
  307. {
  308. n = graph->size;
  309. for (i = 0; i < n; i++)
  310. {
  311. graph->edge_delete(graph->implementation->get_edge(graph->graph, i,
  312. identifier));
  313. graph->edge_delete(graph->implementation->get_edge(graph->graph,
  314. identifier, i));
  315. }
  316. }
  317. return vertex;
  318. }
  319. int graph_is_vertex(graph_t graph, unsigned int identifier)
  320. {
  321. LOGGER("[graph is vertex] graph %p, identifier %u\n", graph, identifier);
  322. _ASSERT(graph, ==, NULL, NULL_POINTER, -1);
  323. _ASSERT(identifier, >=, (unsigned int) vector_get_size(graph->vertices), INVALID_INPUT, 0);
  324. return vector_get_key_at(graph->vertices, identifier) != NULL;
  325. }
  326. vertex_t graph_get_vertex(graph_t graph, unsigned int identifier)
  327. {
  328. LOGGER("[graph get vertex] graph %p, identifier %u\n", graph, identifier);
  329. _ASSERT(graph, ==, NULL, NULL_POINTER, NULL);
  330. _ASSERT(identifier, >=, (unsigned int) vector_get_size(graph->vertices), INVALID_INPUT, NULL);
  331. return vector_get_key_at(graph->vertices, identifier);
  332. }
  333. edge_t graph_get_edge(graph_t graph, unsigned int identifier1,
  334. unsigned int identifier2)
  335. {
  336. LOGGER("[graph get edge] graph %p, identifier1 %u, identifier2 %u\n",
  337. graph, identifier1, identifier2);
  338. _ASSERT(graph, ==, NULL, NULL_POINTER, NULL);
  339. _ASSERT(identifier1, >=, (unsigned int) vector_get_size(graph->vertices), INVALID_INPUT, NULL);
  340. _ASSERT(identifier2, >=, (unsigned int) vector_get_size(graph->vertices), INVALID_INPUT, NULL);
  341. return graph->implementation->get_edge(graph->graph, identifier1,
  342. identifier2);
  343. }
  344. void graph_add_edge(graph_t graph, unsigned int vertex1, unsigned int vertex2,
  345. double cost, char *label, void *key)
  346. {
  347. vertex_t m_vertex1, m_vertex2;
  348. edge_t edge;
  349. LOGGER(
  350. "[graph add edge] graph %p, identifier1 %u, identifier2 %u, cost %lf, label %s, key %p\n",
  351. graph, vertex1, vertex2, cost, label, key);
  352. _ASSERT(graph, ==, NULL, NULL_POINTER,);
  353. _ASSERT(vertex1, >=, (unsigned int) vector_get_size(graph->vertices), INVALID_INPUT, );
  354. _ASSERT(vertex2, >=, (unsigned int) vector_get_size(graph->vertices), INVALID_INPUT, );
  355. m_vertex1 = vector_get_key_at(graph->vertices, vertex1);
  356. m_vertex2 = vector_get_key_at(graph->vertices, vertex2);
  357. _ASSERT(m_vertex1, ==, NULL, NULL_POINTER,);
  358. _ASSERT(m_vertex2, ==, NULL, NULL_POINTER,);
  359. // Create an edge between the two vertices.
  360. edge = edge_new(m_vertex1, m_vertex2, cost, label, key);
  361. _ASSERT(edge, ==, NULL, NULL_POINTER,);
  362. graph->implementation->add_edge(graph->graph, vertex1, vertex2, edge);
  363. }
  364. edge_t graph_remove_edge(graph_t graph, unsigned int vertex1,
  365. unsigned int vertex2)
  366. {
  367. LOGGER("[graph remove edge] graph %p, identifier1 %u, identifier2 %u\n",
  368. graph, vertex1, vertex2);
  369. _ASSERT(graph, ==, NULL, NULL_POINTER, NULL);
  370. _ASSERT(vertex1, >=, (unsigned int) vector_get_size(graph->vertices), INVALID_INPUT, NULL);
  371. _ASSERT(vertex2, >=, (unsigned int) vector_get_size(graph->vertices), INVALID_INPUT, NULL);
  372. return graph->implementation->remove_edge(graph->graph, vertex1, vertex2);
  373. }
  374. int graph_is_edge(graph_t graph, unsigned int vertex1, unsigned int vertex2)
  375. {
  376. LOGGER("[graph is edge] graph %p, identifier1 %u, identifier2 %u\n", graph,
  377. vertex1, vertex2);
  378. _ASSERT(graph, ==, NULL, NULL_POINTER, -1);
  379. _ASSERT(vertex1, >=, (unsigned int) vector_get_size(graph->vertices), INVALID_INPUT, -1);
  380. _ASSERT(vertex2, >=, (unsigned int) vector_get_size(graph->vertices), INVALID_INPUT, -1);
  381. return graph->implementation->get_edge(graph->graph, vertex1, vertex2)
  382. != NULL;
  383. }
  384. int graph_is_empty(graph_t graph)
  385. {
  386. LOGGER("[graph is empty] graph %p\n", graph);
  387. _ASSERT(graph, ==, NULL, NULL_POINTER, -1);
  388. return vector_get_size(graph->vertices) == 0;
  389. }
  390. unsigned int graph_get_size(graph_t graph)
  391. {
  392. unsigned int count = 0, i, n;
  393. LOGGER("[graph get size] graph %p\n", graph);
  394. _ASSERT(graph, ==, NULL, NULL_POINTER, -1);
  395. n = vector_get_size(graph->vertices);
  396. for (i = 0; i < n; i++)
  397. if (vector_get_key_at(graph->vertices, i) != NULL)
  398. count++;
  399. return count;
  400. }
  401. unsigned int graph_get_dimension(graph_t graph)
  402. {
  403. unsigned int count = 0, i, j, n;
  404. LOGGER("[graph get dimension] graph %p\n", graph);
  405. _ASSERT(graph, ==, NULL, NULL_POINTER, -1);
  406. if (graph->implementation->dimension)
  407. return graph->implementation->dimension(graph->graph);
  408. // dimension() not implemented, use default algorithm
  409. n = vector_get_size(graph->vertices);
  410. for (i = 0; i < n; i++)
  411. for (j = 0; j < n; j++)
  412. if (graph->implementation->get_edge(graph->graph, i, j) != NULL)
  413. count++;
  414. return count;
  415. }
  416. unsigned int graph_vertex_degree(graph_t graph, unsigned int identifier)
  417. {
  418. unsigned int i, n, degree = 0;
  419. LOGGER("[graph vertex degree] graph %p, identifier %u\n", graph, identifier);
  420. _ASSERT(graph, ==, NULL, NULL_POINTER, -1);
  421. _ASSERT(identifier, >=, (unsigned int) vector_get_size(graph->vertices), INVALID_INPUT, -1);
  422. if (graph->implementation->vertex_degree)
  423. return graph->implementation->vertex_degree(graph->graph, identifier);
  424. // vertex_degree() not implemented, use default algorithm
  425. n = vector_get_size(graph->vertices);
  426. for (i = 0; i < n; i++)
  427. {
  428. if (graph->implementation->get_edge(graph->graph, identifier, i))
  429. degree++;
  430. if (graph->implementation->get_edge(graph->graph, i, identifier))
  431. degree++;
  432. }
  433. return degree;
  434. }
  435. unsigned int graph_vertex_out_degree(graph_t graph, unsigned int identifier)
  436. {
  437. unsigned int i, n, out_degree = 0;
  438. LOGGER("[graph out vertex degree] graph %p, identifier %u\n", graph,
  439. identifier);
  440. _ASSERT(graph, ==, NULL, NULL_POINTER, -1);
  441. _ASSERT(graph->implementation, ==, NULL, NULL_POINTER, -1);
  442. _ASSERT(identifier, >=, (unsigned int) vector_get_size(graph->vertices), INVALID_INPUT, -1);
  443. if (graph->implementation->vertex_out_degree)
  444. return graph->implementation->vertex_out_degree(graph->graph,
  445. identifier);
  446. // vertex_out_degree() not implemented, use default algorithm
  447. n = vector_get_size(graph->vertices);
  448. for (i = 0; i < n; i++)
  449. if (graph->implementation->get_edge(graph->graph, identifier, i))
  450. out_degree++;
  451. return out_degree;
  452. }
  453. unsigned int graph_vertex_in_degree(graph_t graph, unsigned int identifier)
  454. {
  455. unsigned int i, n, in_degree = 0;
  456. LOGGER("[graph in vertex degree] graph %p, identifier %u\n", graph,
  457. identifier);
  458. _ASSERT(graph, ==, NULL, NULL_POINTER, -1);
  459. _ASSERT(graph->implementation, ==, NULL, NULL_POINTER, -1);
  460. _ASSERT(identifier, >=, (unsigned int) vector_get_size(graph->vertices), INVALID_INPUT, -1);
  461. if (graph->implementation->vertex_in_degree)
  462. return graph->implementation->vertex_in_degree(graph->graph, identifier);
  463. // vertex_in_degree() not implemented, use default algorithm
  464. n = vector_get_size(graph->vertices);
  465. for (i = 0; i < n; i++)
  466. if (graph->implementation->get_edge(graph->graph, i, identifier))
  467. in_degree++;
  468. return in_degree;
  469. }
  470. void graph_iterate_vertices(graph_t graph, void vertex_handler(vertex_t v,
  471. void *context), void *context)
  472. {
  473. unsigned int i, n;
  474. LOGGER(
  475. "[graph iterate vertices] graph %p, vertex handler %p, context %p\n",
  476. graph, vertex_handler, context);
  477. _ASSERT(graph, ==, NULL, NULL_POINTER,);
  478. _ASSERT(vertex_handler, ==, NULL, NULL_POINTER,);
  479. n = vector_get_size(graph->vertices);
  480. for (i = 0; i < n; i++)
  481. if (vector_get_key_at(graph->vertices, i))
  482. vertex_handler(vector_get_key_at(graph->vertices, i), context);
  483. }
  484. void graph_iterate_edges(graph_t graph, void edge_handler(edge_t e,
  485. void *context), void *context)
  486. {
  487. LOGGER("[graph vertex degree] graph %p, edge handler %p, context %p\n",
  488. graph, edge_handler, context);
  489. _ASSERT(graph, ==, NULL, NULL_POINTER,);
  490. _ASSERT(edge_handler, ==, NULL, NULL_POINTER,);
  491. graph->implementation->iterate_edges(graph->graph, edge_handler, context);
  492. }
  493. void graph_transpose_graph(graph_t graph)
  494. {
  495. LOGGER("[graph transpose] graph %p\n", graph);
  496. _ASSERT(graph, ==, NULL, NULL_POINTER,);
  497. graph->implementation->transpose(graph->graph);
  498. }
  499. void graph_dfs(graph_t graph, unsigned int start_vertex_identifier)
  500. {
  501. unsigned int node, nodes_number;
  502. LOGGER("[graph dfs] graph %p, start vertex %u\n", graph,
  503. start_vertex_identifier);
  504. _ASSERT(graph, ==, NULL, NULL_POINTER, );
  505. graph_set_current_time(0);
  506. if (start_vertex_identifier == (unsigned int) -1)
  507. {
  508. nodes_number = vector_get_size(graph->vertices);
  509. for (node = 0; node < nodes_number; node++)
  510. _graph_dfs(graph, node);
  511. }
  512. else
  513. {
  514. _ASSERT(start_vertex_identifier, >=, (unsigned int) vector_get_size(graph->vertices), INVALID_INPUT,);
  515. _graph_dfs(graph, start_vertex_identifier);
  516. }
  517. }
  518. void graph_bfs(graph_t graph, unsigned int start_vertex_identifier)
  519. {
  520. unsigned int node, nodes_number;
  521. LOGGER("[graph bfs] graph %p, start vertex %u\n", graph,
  522. start_vertex_identifier);
  523. _ASSERT(graph, ==, NULL, NULL_POINTER, );
  524. graph_set_current_time(0);
  525. if (start_vertex_identifier == (unsigned int) -1)
  526. {
  527. nodes_number = vector_get_size(graph->vertices);
  528. for (node = 0; node < nodes_number; node++)
  529. _graph_bfs(graph, node);
  530. }
  531. else
  532. {
  533. _ASSERT(start_vertex_identifier, >=, (unsigned int) vector_get_size(graph->vertices), INVALID_INPUT,);
  534. _graph_bfs(graph, start_vertex_identifier);
  535. }
  536. }
  537. void graph_reset_vertices(graph_t graph)
  538. {
  539. LOGGER("[graph reset vertices] graph %p\n", graph);
  540. _ASSERT(graph, ==, NULL, NULL_POINTER,);
  541. _graph_reset_vertices(graph);
  542. }
  543. int graph_is_undirected(graph_t graph)
  544. {
  545. unsigned int i, j, n;
  546. edge_t u, v;
  547. LOGGER("[graph is undirected] graph %p\n", graph);
  548. _ASSERT(graph, ==, NULL, NULL_POINTER, -1);
  549. n = vector_get_size(graph->vertices);
  550. // If there exists an edge from a node to itseft then it's
  551. // not undirected.
  552. for (i = 0; i < n; i++)
  553. if (graph_get_edge(graph, i, i))
  554. return 0;
  555. for (i = 0; i < n - 1; i++)
  556. {
  557. for (j = i + 1; j < n; j++)
  558. {
  559. u = graph_get_edge(graph, i, j);
  560. v = graph_get_edge(graph, j, i);
  561. // If there is a pair of NULL and not-NULL edges
  562. // then the graph_t is undirected
  563. if ((u && !v) || (v && !u))
  564. return 0;
  565. }
  566. }
  567. return 1;
  568. }
  569. void graph_set_current_time(unsigned int time)
  570. {
  571. LOGGER("[graph set current time] time %d\n", time);
  572. current_time = time;
  573. }
  574. int graph_get_current_time()
  575. {
  576. LOGGER("[graph get current time] time %d\n", current_time);
  577. return current_time;
  578. }
  579. void graph_dfs_edges_classification(graph_t graph)
  580. {
  581. unsigned int i, j, nodes_number, type;
  582. vertex_t u, v;
  583. void *context;
  584. LOGGER("[graph dfs edges classification] graph %p\n", graph);
  585. _ASSERT(graph, ==, NULL, NULL_POINTER, );
  586. /*
  587. * Start a complete DFS travel in order to compute values,
  588. * requested by the classification.
  589. */
  590. graph_dfs(graph, -1);
  591. type = DFS_UNKNOWN_EDGE;
  592. nodes_number = vector_get_size(graph->vertices);
  593. for (i = 0; i < nodes_number; i++)
  594. {
  595. u = vector_get_key_at(graph->vertices, i);
  596. v = graph->implementation->first_vertex(graph->graph, i, &context);
  597. while (1)
  598. {
  599. if (v == NULL)
  600. break;
  601. j = vertex_get_identifier(v);
  602. if (i == j)
  603. type = DFS_BACK_EDGE;
  604. // t_start[u] < t_start[v] < t_stop[v] < t_stop[v]
  605. else if (vertex_get_time_start(u) < vertex_get_time_start(v)
  606. && vertex_get_time_stop(v) < vertex_get_time_stop(u))
  607. {
  608. // parent[v] = u => tree edge
  609. if (vertex_get_parent_identifier(v) == vertex_get_identifier(u))
  610. type = DFS_TREE_EDGE;
  611. // parent[v] != u => forward edge
  612. else
  613. type = DFS_FORWARD_EDGE;
  614. }
  615. // t_start[v] < t_start[u] < t_stop[u] < t_stop[v].
  616. else if (vertex_get_time_start(v) < vertex_get_time_start(u)
  617. && vertex_get_time_stop(u) < vertex_get_time_stop(v))
  618. type = DFS_BACK_EDGE;
  619. // t_start[v] < t_stop[v] < t_start[u] < t_stop[u].
  620. else if (vertex_get_time_stop(v) < vertex_get_time_start(u))
  621. type = DFS_CROSS_EDGE;
  622. edge_set_type(graph_get_edge(graph, i, j), type);
  623. v = graph->implementation->next_vertex(graph->graph, i, &context);
  624. }
  625. }
  626. }
  627. void graph_bfs_edges_classification(graph_t graph)
  628. {
  629. unsigned int i, j, k, nodes_number, type;
  630. vertex_t u, v;
  631. void *context;
  632. LOGGER("[graph bfs edges classification] graph %p\n", graph);
  633. _ASSERT(graph, ==, NULL, NULL_POINTER, );
  634. /*
  635. * Start a complete BFS travel in order to compute values,
  636. * requested by the classification.
  637. */
  638. graph_bfs(graph, -1);
  639. type = BFS_UNKNOWN_EDGE;
  640. nodes_number = vector_get_size(graph->vertices);
  641. for (i = 0; i < nodes_number; i++)
  642. {
  643. u = vector_get_key_at(graph->vertices, i);
  644. v = graph->implementation->first_vertex(graph->graph, i, &context);
  645. while (1)
  646. {
  647. if (v == NULL)
  648. break;
  649. j = vertex_get_identifier(v);
  650. // u = parent[v]
  651. if (i == vertex_get_parent_identifier(v))
  652. type = BFS_TREE_EDGE;
  653. else
  654. {
  655. k = i;
  656. while (k != (unsigned) -1 && k != j)
  657. k = vertex_get_parent_identifier(vector_get_key_at(
  658. graph->vertices, k));
  659. if (k != (unsigned) -1)
  660. type = BFS_BACK_EDGE;
  661. // parent[..parent[u]] = v;
  662. else if (vertex_get_cost(v) <= (vertex_get_cost(u) + 1))
  663. type = BFS_CROSS_EDGE;
  664. }
  665. edge_set_type(graph_get_edge(graph, i, j), type);
  666. v = graph->implementation->next_vertex(graph->graph, i, &context);
  667. }
  668. }
  669. }
  670. void graph_connected_components(graph_t graph,
  671. linked_list_t connected_components, int check)
  672. {
  673. unsigned int nodes_number, node, it, current_time, max_time, this_time;
  674. vertex_t u;
  675. linked_list_t add;
  676. LOGGER(
  677. "[graph connected components] graph %p, connected components %p, check %d\n",
  678. graph, connected_components, (int) check);
  679. _ASSERT(graph, ==, NULL, NULL_POINTER,);
  680. _ASSERT(connected_components, ==, NULL, NULL_POINTER,);
  681. if (check)
  682. if (!graph_is_undirected(graph))
  683. return;
  684. graph_set_current_time(0);
  685. nodes_number = vector_get_size(graph->vertices);
  686. max_time = current_time = 0;
  687. for (node = 0; node < nodes_number; node++)
  688. {
  689. _graph_dfs(graph, node);
  690. /*
  691. * Find the maximum stop time in order to find a new connected component
  692. * of the current graph_t. It contains the vertices of which
  693. * t_start and t_stop is between current_time and max_time
  694. */
  695. for (it = 0; it < nodes_number; it++)
  696. {
  697. this_time = vertex_get_time_stop(vector_get_key_at(graph->vertices,
  698. it));
  699. if (max_time < this_time)
  700. max_time = this_time;
  701. }
  702. add = linked_list_new();
  703. for (it = 0; it < nodes_number; it++)
  704. {
  705. u = vector_get_key_at(graph->vertices, it);
  706. this_time = vertex_get_time_stop(u);
  707. if (this_time > current_time && this_time <= max_time)
  708. linked_list_push_back(add, (void *) it);
  709. }
  710. current_time = max_time;
  711. if (linked_list_get_size(add) > 0)
  712. linked_list_push_back(connected_components, add);
  713. else
  714. linked_list_delete(add);
  715. }
  716. }
  717. static void *key_at(void *data, int index)
  718. {
  719. return (void *) ((unsigned int *) data)[index];
  720. }
  721. static void set_key_at(void *data, int index, void *new_value)
  722. {
  723. ((unsigned int *) data)[index] = (unsigned int) new_value;
  724. }
  725. void graph_strongly_connected_components(graph_t graph,
  726. linked_list_t strongly_connected_components)
  727. {
  728. unsigned int *vertices, i, j, nodes_number, t_start, t_stop, aux;
  729. linked_list_t add;
  730. LOGGER("[graph strongly connected components] graph %p, list %p\n", graph,
  731. strongly_connected_components);
  732. _ASSERT(graph, ==, NULL, NULL_POINTER,);
  733. _ASSERT(strongly_connected_components, ==, NULL, NULL_POINTER,);
  734. // Make a complete DFS travel and sort the vertices after t_stop.
  735. graph_dfs(graph, -1);
  736. nodes_number = vector_get_size(graph->vertices);
  737. vertices = (unsigned int *) _new(nodes_number * sizeof(unsigned int));
  738. for (i = 0; i < nodes_number; i++)
  739. vertices[i] = i;
  740. quick_sort(vertices, nodes_number, key_at, set_key_at,
  741. _compare_nodes_strongly_connected_components, graph->vertices);
  742. graph_transpose_graph(graph);
  743. graph_set_current_time(0);
  744. _graph_reset_vertices(graph);
  745. for (i = 0; i < nodes_number; i++)
  746. {
  747. if (vertex_get_visited(vector_get_key_at(graph->vertices, i)))
  748. continue;
  749. t_start = graph_get_current_time();
  750. _graph_dfs(graph, vertices[i]);
  751. t_stop = graph_get_current_time();
  752. add = linked_list_new();
  753. for (j = 0; j < nodes_number; j++)
  754. {
  755. aux = vertex_get_time_stop(vector_get_key_at(graph->vertices, j));
  756. if (aux > t_start && aux <= t_stop)
  757. linked_list_push_back(add, (void *) j);
  758. }
  759. if (linked_list_get_size(add) > 0)
  760. linked_list_push_back(strongly_connected_components, add);
  761. else
  762. // Delete allocated memory in order to avoid memory leaks.
  763. linked_list_delete(add);
  764. }
  765. _delete(vertices);
  766. graph_transpose_graph(graph);
  767. }
  768. int graph_topological_sort(graph_t graph, linked_list_t sort)
  769. {
  770. unsigned int i, j, nodes_number;
  771. int ok, dead_lock;
  772. LOGGER("[graph topological sort] graph %p, list %p\n", graph, sort);
  773. _ASSERT(graph, ==, NULL, NULL_POINTER, -1);
  774. _ASSERT(sort, ==, NULL, NULL_POINTER, -1);
  775. _graph_reset_vertices(graph);
  776. nodes_number = vector_get_size(graph->vertices);
  777. while (1)
  778. {
  779. dead_lock = 1;
  780. for (i = 0; i < nodes_number; i++)
  781. {
  782. ok = 1;
  783. // Check if there is a vertex with 0 in-degree. I simulate
  784. // edges removing by visiting nodes.
  785. for (j = 0; j < nodes_number; j++)
  786. {
  787. if (!vertex_get_visited(vector_get_key_at(graph->vertices, j))
  788. && graph_is_edge(graph, j, i))
  789. {
  790. ok = 0;
  791. break;
  792. }
  793. }
  794. if (ok
  795. && !vertex_get_visited(
  796. vector_get_key_at(graph->vertices, i)))
  797. {
  798. // If vertex i has 0 in-degree then add it to
  799. // topological sort list and visit it.
  800. linked_list_push_back(sort, (void *) i);
  801. vertex_set_visited(vector_get_key_at(graph->vertices, i), 1);
  802. dead_lock = 0;
  803. }
  804. }
  805. if (linked_list_get_size(sort) == nodes_number)
  806. break;
  807. if (dead_lock)
  808. return -1;
  809. }
  810. graph_reset_vertices(graph);
  811. return 0;
  812. }
  813. int graph_bipartite(graph_t graph, linked_list_t first_set,
  814. linked_list_t second_set)
  815. {
  816. unsigned int i, j, n, ok;
  817. vertex_t vertex;
  818. void *context;
  819. LOGGER("[graph bipartite] graph %p, first set %p, second set %p\n", graph,
  820. first_set, second_set);
  821. _ASSERT(graph, ==, NULL, NULL_POINTER, -1);
  822. _ASSERT(first_set, ==, NULL, NULL_POINTER, -1);
  823. _ASSERT(second_set, ==, NULL, NULL_POINTER, -1);
  824. // Do a complete BFS travel.
  825. graph_bfs(graph, -1);
  826. n = vector_get_size(graph->vertices);
  827. // Check if all pairs of neighbors don't have even sum distance.
  828. for (i = 0; i < n - 1; i++)
  829. {
  830. vertex = graph->implementation->first_vertex(graph->graph, i, &context);
  831. ok = 1;
  832. while (1)
  833. {
  834. if (vertex == NULL)
  835. break;
  836. j = vertex_get_identifier(vertex);
  837. if (j > i)
  838. {
  839. if (!(vertex_get_cost(vector_get_key_at(graph->vertices, i))
  840. + vertex_get_cost(vector_get_key_at(graph->vertices, j))))
  841. ok = 0;
  842. }
  843. else
  844. {
  845. graph->implementation->delete_vertex_context(&context);
  846. break;
  847. }
  848. vertex = graph->implementation->next_vertex(graph->graph, i,
  849. &context);
  850. }
  851. if (!ok)
  852. return 1;
  853. }
  854. // For-each vertex in graph, if it's distance is odd add to A, else
  855. // add it to B.
  856. for (i = 0; i < n; i++)
  857. {
  858. if (((unsigned int) vertex_get_cost(vector_get_key_at(graph->vertices,
  859. i))) % 2)
  860. linked_list_push_back(first_set, (void *) i);
  861. else
  862. linked_list_push_back(second_set, (void *) i);
  863. }
  864. return 0;
  865. }
  866. unsigned int graph_diameter(graph_t graph, unsigned int *first_node,
  867. unsigned int *second_node)
  868. {
  869. unsigned int max1, max2, i, n, aux;
  870. LOGGER("[graph diameter] graph %p, first node %p, second node %p\n", graph,
  871. first_node, second_node);
  872. _ASSERT(graph, ==, NULL, NULL_POINTER, -1);
  873. _ASSERT(first_node, ==, NULL, NULL_POINTER, -1);
  874. _ASSERT(second_node, ==, NULL, NULL_POINTER, -1);
  875. // Make two BFS travels: first, starting from first node of graph_t
  876. // and the second, starting from a leaf node of the first travel.
  877. // Return the leaf nodes and the distance between them.
  878. _graph_reset_vertices(graph);
  879. _graph_bfs(graph, 0);
  880. n = vector_get_size(graph->vertices);
  881. max1 = max2 = 0;
  882. for (i = 0; i < n; i++)
  883. {
  884. aux = (unsigned int) vertex_get_cost(vector_get_key_at(graph->vertices,
  885. i));
  886. if (max1 < (unsigned int) aux)
  887. {
  888. max1 = aux;
  889. *first_node = i;
  890. }
  891. }
  892. _graph_reset_vertices(graph);
  893. _graph_bfs(graph, *first_node);
  894. for (i = 0; i < n; i++)
  895. {
  896. aux = (unsigned int) vertex_get_cost(vector_get_key_at(graph->vertices,
  897. i));
  898. if (max2 < (unsigned int) aux)
  899. {
  900. max2 = aux;
  901. *second_node = i;
  902. }
  903. }
  904. _graph_reset_vertices(graph);
  905. return MAX(max1, max2);
  906. }
  907. void graph_articulation_points(graph_t graph, linked_list_t articulation_points)
  908. {
  909. unsigned int i, n, *parent, *low, *start;
  910. int *color, *cut_vertex;
  911. LOGGER("[graph articulation points] graph %p, articulation points\n",
  912. graph, articulation_points);
  913. _ASSERT(graph, ==, NULL, NULL_POINTER,);
  914. _ASSERT(articulation_points, ==, NULL, NULL_POINTER,);
  915. n = vector_get_size(graph->vertices);
  916. parent = (unsigned int *) _new(n * sizeof(unsigned int));
  917. low = (unsigned int *) _new(n * sizeof(unsigned int));
  918. start = (unsigned int *) _new(n * sizeof(unsigned int));
  919. color = (int *) _new(n * sizeof(int));
  920. cut_vertex = (int *) _new(n * sizeof(int));
  921. for (i = 0; i < n; i++)
  922. {
  923. parent[i] = (unsigned int) -1;
  924. low[i] = 0;
  925. start[i] = 0;
  926. cut_vertex[i] = 0;
  927. color[i] = WHITE;
  928. }
  929. for (i = 0; i < n; i++)
  930. {
  931. if (color[i] == WHITE)
  932. {
  933. if (_articulation_points_travel(graph, i, color, start, low,
  934. parent, cut_vertex) > 1)
  935. cut_vertex[i] = 1;
  936. else
  937. cut_vertex[i] = 0;
  938. }
  939. }
  940. for (i = 0; i < n; i++)
  941. if (cut_vertex[i])
  942. linked_list_push_back(articulation_points, (void *) i);
  943. _delete(parent);
  944. _delete(low);
  945. _delete(start);
  946. _delete(color);
  947. _delete(cut_vertex);
  948. }
  949. static void _graph_bridges_edges_handler(edge_t edge, void *context)
  950. {
  951. int **_bridges = (int **) context;
  952. _bridges[vertex_get_identifier(edge_get_vertex1(edge))][vertex_get_identifier(
  953. edge_get_vertex2(edge))] = 1;
  954. }
  955. void graph_bridges(graph_t graph, linked_list_t bridges)
  956. {
  957. /*
  958. * This algorithm is based on observation : an edge is a bridge if and only if
  959. * it's not part of a simple cycle in given graph_t.
  960. */
  961. linked_list_t cycles;
  962. linked_list_iterator_t it_list, it;
  963. unsigned int i, j, n;
  964. int **_bridges;
  965. LOGGER("[graph bridges] graph %p, bridges %p\n", graph, bridges);
  966. _ASSERT(graph, ==, NULL, NULL_POINTER,);
  967. _ASSERT(bridges, ==, NULL, NULL_POINTER,);
  968. cycles = linked_list_new();
  969. n = vector_get_size(graph->vertices);
  970. _bridges = (int **) _new(n * sizeof(int *));
  971. for (i = 0; i < n; i++)
  972. {
  973. _bridges[i] = (int *) _new(n * sizeof(int));
  974. for (j = 0; j < n; j++)
  975. _bridges[i][j] = 0;
  976. }
  977. // This function guarantees O(E) complexity
  978. graph->implementation->iterate_edges(graph->graph,
  979. _graph_bridges_edges_handler, _bridges);
  980. graph_cycles(graph, cycles);
  981. /*
  982. * 1. For-each cycle execute :
  983. * 2. For-each edge (u, v) from current cycle remove (u, v) from bridges list.
  984. */
  985. for (it_list = linked_list_get_begin(cycles); it_list != NULL; it_list
  986. = linked_list_iterator_get_next(it_list))
  987. {
  988. i = (unsigned int) linked_list_iterator_get_key(linked_list_get_begin(
  989. ((linked_list_t) linked_list_iterator_get_key(it_list))));
  990. j = (unsigned int) linked_list_iterator_get_key(linked_list_get_end(
  991. ((linked_list_t) linked_list_iterator_get_key(it_list))));
  992. _bridges[i][j] = _bridges[j][i] = 0;
  993. for (it = linked_list_get_begin(
  994. ((linked_list_t) linked_list_iterator_get_key(it_list))); linked_list_iterator_get_next(
  995. it) != NULL;)
  996. {
  997. i = (unsigned int) linked_list_iterator_get_key(it);
  998. it = linked_list_iterator_get_next(it);
  999. j = (unsigned int) linked_list_iterator_get_key(it);
  1000. _bridges[i][j] = _bridges[j][i] = 0;
  1001. }
  1002. linked_list_delete(linked_list_iterator_get_key(it_list));
  1003. }
  1004. linked_list_delete(cycles);
  1005. for (i = 0; i < n - 1; i++)
  1006. {
  1007. for (j = i + 1; j < n; j++)
  1008. {
  1009. if (_bridges[i][j])
  1010. linked_list_push_back(bridges, pair_new((void *) i, (void *) j));
  1011. }
  1012. _delete(_bridges[i]);
  1013. }
  1014. _delete(_bridges[n - 1]);
  1015. _delete(_bridges);
  1016. }
  1017. void graph_biconex_components(graph_t graph, linked_list_t biconex_components)
  1018. {
  1019. /*
  1020. * The algorithm chosen for finding the biconex components is:
  1021. * 1. Find the articulation points.
  1022. * 2. Remove the articulation points from the graph.
  1023. * 3. Find the connected components of the graph_t and put them into the given variable.
  1024. * 4. Build the biconex components by adding the articulation points to the
  1025. * connected components calculated above. Also, between two articulation points there is
  1026. * a biconex component.
  1027. */
  1028. linked_list_t cut_vertex, connected_components;
  1029. linked_list_iterator_t it, it_cc, it_cv;
  1030. vertex_t vertex;
  1031. void *copy, *context;
  1032. LOGGER("[graph biconex components] graph %p, biconex components %p\n",
  1033. graph, biconex_components);
  1034. _ASSERT(graph, ==, NULL, NULL_POINTER,);
  1035. _ASSERT(biconex_components, ==, NULL, NULL_POINTER,);
  1036. cut_vertex = linked_list_new();
  1037. graph_articulation_points(graph, cut_vertex);
  1038. // Make a safe copy of initial adjacency matrix.
  1039. copy = graph->implementation->store(graph->graph);
  1040. // Remove cut vertices from graph_t.
  1041. for (it = linked_list_get_begin(cut_vertex); it != NULL; it
  1042. = linked_list_iterator_get_next(it))
  1043. {
  1044. vertex = graph->implementation->first_vertex(graph->graph,
  1045. (unsigned int) linked_list_iterator_get_key(it), &context);
  1046. while (1)
  1047. {
  1048. if (vertex == NULL)
  1049. break;
  1050. graph_remove_edge(graph,
  1051. (unsigned int) linked_list_iterator_get_key(it),
  1052. vertex_get_identifier(vertex));
  1053. graph_remove_edge(graph, vertex_get_identifier(vertex),
  1054. (unsigned int) linked_list_iterator_get_key(it));
  1055. vertex = graph->implementation->next_vertex(graph->graph,
  1056. (unsigned int) linked_list_iterator_get_key(it), &context);
  1057. }
  1058. }
  1059. connected_components = linked_list_new();
  1060. graph_connected_components(graph, connected_components, 0);
  1061. for (it = linked_list_get_begin(connected_components); it != NULL; it
  1062. = linked_list_iterator_get_next(it))
  1063. {
  1064. // linked_list_iterator_get_key(NULL, it, 0) represents a connected component.
  1065. // it_cc = iterator on connected component nodes.
  1066. // it_cv = iterator on cut vertices.
  1067. // Add articulation points.
  1068. for (it_cc = linked_list_get_begin(
  1069. ((linked_list_t) linked_list_iterator_get_key(it))); it_cc
  1070. != NULL; it_cc = linked_list_iterator_get_next(it_cc))
  1071. {
  1072. for (it_cv = linked_list_get_begin(cut_vertex); it_cv != NULL; it_cv
  1073. = linked_list_iterator_get_next(it_cv))
  1074. if (graph->implementation->get_edge(copy,
  1075. (unsigned int) linked_list_iterator_get_key(it_cc),
  1076. (unsigned int) linked_list_iterator_get_key(it_cv))
  1077. && linked_list_iterator_get_key(it_cc)
  1078. != linked_list_iterator_get_key(it_cv)
  1079. && !linked_list_search_key(
  1080. linked_list_iterator_get_key(it),
  1081. linked_list_iterator_get_key(it_cv),
  1082. _compare_nodes_unsigned, NULL))
  1083. linked_list_push_front(linked_list_iterator_get_key(it),
  1084. linked_list_iterator_get_key(it_cv));
  1085. }
  1086. linked_list_push_back(biconex_components, linked_list_iterator_get_key(
  1087. it));
  1088. }
  1089. graph->implementation->delete_g(graph->graph);
  1090. graph->graph = copy;
  1091. linked_list_delete(connected_components);
  1092. linked_list_delete(cut_vertex);
  1093. }
  1094. void graph_cycles(graph_t graph, linked_list_t cycles)
  1095. {
  1096. unsigned int i, n, *parent, current_node = 0;
  1097. int *colour, *visited;
  1098. LOGGER("[graph cycles] graph %p, cycles %p\n", graph, cycles);
  1099. _ASSERT(graph, ==, NULL, NULL_POINTER,);
  1100. _ASSERT(cycles, ==, NULL, NULL_POINTER,);
  1101. n = vector_get_size(graph->vertices);
  1102. parent = (unsigned int *) _new(n * sizeof(unsigned int));
  1103. colour = (int *) _new(n * sizeof(int));
  1104. visited = (int *) _new(n * sizeof(int));
  1105. for (i = 0; i < n; i++)
  1106. {
  1107. parent[i] = (unsigned int) -1;
  1108. colour[i] = WHITE;
  1109. visited[i] = 0;
  1110. }
  1111. while (current_node != (unsigned int) -1)
  1112. {
  1113. _cycles_travel(graph, current_node, cycles, parent, colour, visited);
  1114. current_node = (unsigned int) -1;
  1115. // Find the first unvisited vertex and start new DFS travel from it.
  1116. for (i = 0; i < n; i++)
  1117. {
  1118. if (!visited[i])
  1119. {
  1120. current_node = i;
  1121. break;
  1122. }
  1123. }
  1124. }
  1125. _delete(parent);
  1126. _delete(colour);
  1127. _delete(visited);
  1128. }
  1129. void graph_dijkstra(graph_t graph, unsigned int source, vector_t distances,
  1130. vector_t parents)
  1131. {
  1132. heap_t heap;
  1133. unsigned int i, j, n;
  1134. int *visited;
  1135. double *edge1, *edge2, edge3;
  1136. edge_t m_edge;
  1137. void *context;
  1138. LOGGER("[graph dijkstra] graph %p, source %u, distances %p, parents %p\n",
  1139. graph, source, distances, parents);
  1140. _ASSERT(graph, ==, NULL, NULL_POINTER,);
  1141. _ASSERT(source, >= , graph->size, INVALID_INPUT,);
  1142. _ASSERT(distances, ==, NULL, NULL_POINTER,);
  1143. _ASSERT(parents, ==, NULL, NULL_POINTER,);
  1144. n = vector_get_size(graph->vertices);
  1145. visited = (int *) _new(n * sizeof(int));
  1146. for (i = 0; i < n; i++)
  1147. {
  1148. *(double *) vector_get_key_at(distances, i) = TEMELIA_INFINITY;
  1149. visited[i] = 0;
  1150. }
  1151. *(double *) vector_get_key_at(distances, source) = 0;
  1152. heap = heap_new(n);
  1153. for (i = 0; i < n; i++)
  1154. heap_insert(heap, (void *) i, _compare_dijkstra, distances);
  1155. while (!heap_is_empty(heap))
  1156. {
  1157. i = (unsigned int) heap_get_min_key(heap);
  1158. heap_remove_min_key(heap, _compare_dijkstra, distances);
  1159. visited[i] = 1;
  1160. m_edge = graph->implementation->first_edge(graph->graph, i, &context);
  1161. while (1)
  1162. {
  1163. if (m_edge == NULL)
  1164. break;
  1165. j = vertex_get_identifier(edge_get_vertex2(m_edge));
  1166. edge1 = vector_get_key_at(distances, j);
  1167. edge2 = vector_get_key_at(distances, i);
  1168. edge3 = edge_get_cost(m_edge);
  1169. if (i != j && (*edge1 > *edge2 + edge3))
  1170. {
  1171. *edge1 = *edge2 + edge3;
  1172. vector_set_key_at(parents, j, (void *) i);
  1173. heap_change_key_by_value(heap, (void *) j, (void *) j,
  1174. _compare_dijkstra, distances);
  1175. }
  1176. m_edge
  1177. = graph->implementation->next_edge(graph->graph, i,
  1178. &context);
  1179. }
  1180. }
  1181. heap_delete(heap);
  1182. _delete(visited);
  1183. }
  1184. int graph_bellman_ford(graph_t graph, unsigned int source, vector_t distances,
  1185. vector_t parents)
  1186. {
  1187. unsigned int i, j, k, n;
  1188. double *edge1, *edge2, edge3;
  1189. LOGGER(
  1190. "[graph bellman ford] graph %p, source %u, distances %p, parents %p\n",
  1191. graph, source, distances, parents);
  1192. _ASSERT(graph, ==, NULL, NULL_POINTER, -1);
  1193. _ASSERT(distances, ==, NULL, NULL_POINTER, -1);
  1194. _ASSERT(parents, ==, NULL, NULL_POINTER, -1);
  1195. n = vector_get_size(graph->vertices);
  1196. for (i = 0; i < n; i++)
  1197. {
  1198. vector_set_key_at(parents, i, (void *) -1);
  1199. *(double *) vector_get_key_at(distances, i) = TEMELIA_INFINITY;
  1200. }
  1201. *(double *) vector_get_key_at(distances, source) = 0;
  1202. for (i = 0; i < n; i++)
  1203. {
  1204. for (j = 0; j < n; j++)
  1205. {
  1206. for (k = 0; k < n; k++)
  1207. {
  1208. if (i == j)
  1209. continue;
  1210. edge1 = vector_get_key_at(distances, k);
  1211. edge2 = vector_get_key_at(distances, j);
  1212. edge3 = edge_get_cost(graph_get_edge(graph, j, k));
  1213. if (*edge1 > *edge2 + edge3)
  1214. {
  1215. *edge1 = *edge2 + edge3;
  1216. vector_set_key_at(parents, k, (void *) j);
  1217. }
  1218. }
  1219. }
  1220. }
  1221. // If there exists an edge (i, j) such that distances[j] > distances[i] + graph_t[i][j]
  1222. // then, in the graph_t, is a negative cycle.
  1223. for (i = 0; i < n; i++)
  1224. {
  1225. for (j = 0; j < n; j++)
  1226. {
  1227. if (graph_is_edge(graph, i, j))
  1228. {
  1229. if (*(double *) vector_get_key_at(distances, j)
  1230. > *(double *) vector_get_key_at(distances, i)
  1231. + edge_get_cost(graph_get_edge(graph, i, j)))
  1232. return -1;
  1233. }
  1234. }
  1235. }
  1236. return 0;
  1237. }
  1238. void graph_floyd_warshall(graph_t graph, matrix_t distances, matrix_t parents)
  1239. {
  1240. unsigned int i, j, k, n;
  1241. double *edge1, *edge2, *edge3;
  1242. LOGGER("[graph floyd warshall] graph %p, distances %p, parents %p\n",
  1243. graph, distances, parents);
  1244. _ASSERT(graph, ==, NULL, NULL_POINTER,);
  1245. _ASSERT(distances, ==, NULL, NULL_POINTER,);
  1246. _ASSERT(parents, ==, NULL, NULL_POINTER,);
  1247. n = vector_get_size(graph->vertices);
  1248. // The initial distance matrix is equal with the graph_t cost matrix.
  1249. for (i = 0; i < n; i++)
  1250. {
  1251. for (j = 0; j < n; j++)
  1252. {
  1253. if (i == j || !graph_is_edge(graph, i, j))
  1254. {
  1255. matrix_set_key_at(parents, i, j, (void *) -1);
  1256. if (i != j)
  1257. *(double *) matrix_get_key_at(distances, i, j)
  1258. = TEMELIA_INFINITY;
  1259. else
  1260. *(double *) matrix_get_key_at(distances, i, j) = 0;
  1261. }
  1262. else
  1263. {
  1264. matrix_set_key_at(parents, i, j, (void *) i);
  1265. *(double *) matrix_get_key_at(distances, i, j) = edge_get_cost(
  1266. graph_get_edge(graph, i, j));
  1267. }
  1268. }
  1269. }
  1270. // Dynamic programming over k.
  1271. for (k = 0; k < n; k++)
  1272. {
  1273. // For-each edge, relax it and adjust : distances and parents.
  1274. for (i = 0; i < n; i++)
  1275. {
  1276. for (j = 0; j < n; j++)
  1277. {
  1278. if (i != j)
  1279. {
  1280. edge1 = matrix_get_key_at(distances, i, j);
  1281. edge2 = matrix_get_key_at(distances, i, k);
  1282. edge3 = matrix_get_key_at(distances, k, j);
  1283. if (*edge2 != TEMELIA_INFINITY && *edge3
  1284. != TEMELIA_INFINITY)
  1285. {
  1286. if (*edge1 > *edge2 + *edge3)
  1287. {
  1288. *edge1 = *edge2 + *edge3;
  1289. matrix_set_key_at(parents, i, j, matrix_get_key_at(
  1290. parents, k, j));
  1291. }
  1292. }
  1293. }
  1294. }
  1295. }
  1296. }
  1297. }
  1298. int graph_johnson(graph_t graph, matrix_t distances, matrix_t parents)
  1299. {
  1300. /*
  1301. * The Johnson algorithm computes the minimum distances between all the vertices in the graph_t.
  1302. * 1. First, a new node Q is added to the graph_t, connected by zero-weight edge to each other node.
  1303. * 2. Second, the Bellman-Ford algorithm is used, starting from the new vertex Q, to find for-each
  1304. * vertex v the least weight h(v) of a path from Q to v. If this step detects a negative cycle, the
  1305. * algorithm is terminated.
  1306. * 3. The next edges of original graph_t are reweighted using the values computed by the Bellman-Ford
  1307. * algorithm : an edge from u to v, having length w(u,v), is given the new length w(u,v) + h(u) - h(v).
  1308. * (graph_t becomes normalized).
  1309. * 4. Finally, for each node s, Dijkstra's algorithm is used to find the shortest paths from s to
  1310. * each other vertex in reweighted graph_t.
  1311. * 5. For-each edge (u,v) add h(v) - h(u) to obtain the minimum distance.
  1312. * (graph_t becomes unnormalized).
  1313. */
  1314. unsigned int i, j, n, q;
  1315. vector_t bf_h, bf_p, v_distances, v_parents;
  1316. edge_t edge;
  1317. void *context;
  1318. LOGGER("[graph johnson] graph %p, distances %p, parents %p\n", graph,
  1319. distances, parents);
  1320. _ASSERT(graph, ==, NULL, NULL_POINTER, -1);
  1321. _ASSERT(distances, ==, NULL, NULL_POINTER, -1);
  1322. _ASSERT(matrix_get_rows_number(distances), !=, matrix_get_columns_number(distances), INVALID_INPUT, -1);
  1323. _ASSERT(parents, ==, NULL, NULL_POINTER, -1);
  1324. _ASSERT(matrix_get_rows_number(parents), !=, matrix_get_columns_number(parents), INVALID_INPUT, -1);
  1325. n = graph_get_size(graph);
  1326. q = graph_add_vertex(graph, NULL, NULL);
  1327. _ASSERT(q, ==, -1, FULL, -1);
  1328. for (i = 0; i < n; i++)
  1329. graph_add_edge(graph, q, i, 0, NULL, NULL);
  1330. bf_p = vector_new(n + 1);
  1331. bf_h = vector_new(n + 1);
  1332. for (i = 0; i < n + 1; i++)
  1333. vector_push_back(bf_h, _new(sizeof(double)));
  1334. _ASSERT(graph_bellman_ford(graph, q, bf_h, bf_p), ==, -1, INVALID_INPUT, -1);
  1335. // Normalize graph_t.
  1336. for (i = 0; i < n; i++)
  1337. {
  1338. edge = graph->implementation->first_edge(graph->graph, i, &context);
  1339. while (1)
  1340. {
  1341. if (edge == NULL)
  1342. break;
  1343. j = vertex_get_identifier(edge_get_vertex2(edge));
  1344. if (i != j)
  1345. edge_set_cost(edge, edge_get_cost(edge)
  1346. + *(double *) vector_get_key_at(bf_h, i)
  1347. - *(double *) vector_get_key_at(bf_h, j));
  1348. matrix_set_key_at(parents, i, j, (void *) -1);
  1349. *(double *) matrix_get_key_at(distances, i, j) = TEMELIA_INFINITY;
  1350. edge = graph->implementation->next_edge(graph->graph, i, &context);
  1351. }
  1352. }
  1353. v_distances = vector_new(n + 1);
  1354. v_parents = vector_new(n + 1);
  1355. for (i = 0; i < n + 1; i++)
  1356. {
  1357. vector_push_back(v_distances, _new(sizeof(double)));
  1358. vector_push_back(v_parents, (void *) -1);
  1359. }
  1360. // Apply Dijkstra's algorithm for each vertex in graph
  1361. for (i = 0; i < n; i++)
  1362. {
  1363. graph_dijkstra(graph, i, v_distances, v_parents);
  1364. for (j = 0; j < n; j++)
  1365. {
  1366. matrix_set_key_at(parents, i, j, (void *) vector_get_key_at(
  1367. v_parents, j));
  1368. *(double *) matrix_get_key_at(distances, i, j)
  1369. = *(double *) vector_get_key_at(v_distances, j)
  1370. + *(double *) vector_get_key_at(bf_h, j)
  1371. - *(double *) vector_get_key_at(bf_h, i);
  1372. }
  1373. }
  1374. // Re normalize
  1375. for (i = 0; i < n; i++)
  1376. {
  1377. edge = graph->implementation->first_edge(graph->graph, i, &context);
  1378. while (1)
  1379. {
  1380. if (edge == NULL)
  1381. break;
  1382. j = vertex_get_identifier(edge_get_vertex2(edge));
  1383. if (i != j)
  1384. edge_set_cost(edge, edge_get_cost(edge)
  1385. + *(double *) vector_get_key_at(bf_h, j)
  1386. - *(double *) vector_get_key_at(bf_h, i));
  1387. edge = graph->implementation->next_edge(graph->graph, i, &context);
  1388. }
  1389. }
  1390. for (i = 0; i < n + 1; i++)
  1391. {
  1392. _delete(vector_get_key_at(bf_h, i));
  1393. _delete(vector_get_key_at(v_distances, i));
  1394. }
  1395. vector_delete(bf_h);
  1396. vector_delete(bf_p);
  1397. vector_delete(v_distances);
  1398. vector_delete(v_parents);
  1399. return 0;
  1400. }
  1401. double graph_prim(graph_t graph, unsigned int start_vertex_identifier,
  1402. linked_list_t minimum_spanning_tree)
  1403. {
  1404. /*
  1405. * Prim's algorithm finds the minimum spanning tree for connected weighted graph_t.
  1406. * 1. Put all vertices in queue Q.
  1407. * 2. For-each vertex u in graph_t, make key[u] <- INFINITY.
  1408. * 3. key[root] <- 0, parent[root] <- NIL.
  1409. * 4. while queue Q is not empty execute :
  1410. * 5. extract the vertex with minimum key, let it be u.
  1411. * 6. for-each vertex v such that v is neighbor with u execute :
  1412. * 7. if v is in queue Q and weight(u, v) < key[v] execute :
  1413. * 8. parent[v] <- u, key[v] <- weight(u, v).
  1414. */
  1415. heap_t queue;
  1416. unsigned int i, j, n, *parents;
  1417. double *keys, cost;
  1418. int *visited;
  1419. edge_t m_edge;
  1420. void *context;
  1421. LOGGER(
  1422. "[graph prim] graph %p, start vertex %u, minimum spanning tree %p\n",
  1423. graph, start_vertex_identifier, minimum_spanning_tree);
  1424. _ASSERT(graph, ==, NULL, NULL_POINTER, -1);
  1425. _ASSERT(minimum_spanning_tree, ==, NULL, INVALID_INPUT, -1);
  1426. n = vector_get_size(graph->vertices);
  1427. _ASSERT(start_vertex_identifier, >=, n, INVALID_INPUT, -1);
  1428. queue = heap_new(n);
  1429. keys = (double *) _new(n * sizeof(double));
  1430. parents = (unsigned int *) _new(n * sizeof(unsigned int));
  1431. visited = (int *) _new(n * sizeof(int));
  1432. for (i = 0; i < n; i++)
  1433. {
  1434. keys[i] = TEMELIA_INFINITY;
  1435. visited[i] = 0;
  1436. parents[i] = (unsigned int) -1;
  1437. }
  1438. keys[start_vertex_identifier] = 0;
  1439. for (i = 0; i < n; i++)
  1440. heap_insert(queue, (void *) i, _compare_prim, keys);
  1441. while (!heap_is_empty(queue))
  1442. {
  1443. i = (unsigned int) heap_get_min_key(queue);
  1444. visited[i] = 1;
  1445. heap_remove_min_key(queue, _compare_prim, keys);
  1446. m_edge = graph->implementation->first_edge(graph->graph, i, &context);
  1447. while (1)
  1448. {
  1449. if (m_edge == NULL)
  1450. break;
  1451. j = vertex_get_identifier(edge_get_vertex2(m_edge));
  1452. if (!visited[j] && edge_get_cost(m_edge) < keys[j])
  1453. {
  1454. edge_debug(m_edge, NULL);
  1455. parents[j] = i;
  1456. keys[j] = edge_get_cost(m_edge);
  1457. heap_change_key_by_value(queue, (void *) j, (void *) j,
  1458. _compare_prim, keys);
  1459. }
  1460. m_edge
  1461. = graph->implementation->next_edge(graph->graph, i,
  1462. &context);
  1463. }
  1464. }
  1465. cost = 0;
  1466. for (i = 0; i < n; i++)
  1467. {
  1468. cost += keys[i];
  1469. linked_list_push_back(minimum_spanning_tree, pair_new((void *) i,
  1470. (void *) parents[i]));
  1471. }
  1472. heap_delete(queue);
  1473. _delete(keys);
  1474. _delete(parents);
  1475. _delete(visited);
  1476. return cost;
  1477. }
  1478. double graph_kruskal(graph_t graph, unsigned int start_vertex_identifier,
  1479. linked_list_t *minimum_spanning_tree)
  1480. {
  1481. /*
  1482. * Kruskal's algorithm finds a minimum spanning tree for a connected weighted graph_t.
  1483. * 1. create a forest F (a set of trees), where each vertex in the graph_t is a separate tree
  1484. * 2. create a set S containing all the edges in the graph
  1485. * 3. while S is nonempty
  1486. * 4. remove an edge with minimum weight from S
  1487. * 5. if that edge connects two different trees, then add it to the forest,
  1488. * combining two trees into a single tree
  1489. * 6. otherwise discard that edge
  1490. */
  1491. unsigned int i, j, k, n, k1, k2;
  1492. linked_list_t edges;
  1493. linked_list_iterator_t it;
  1494. linked_list_t *partial_trees;
  1495. int ok;
  1496. double cost;
  1497. edge_t m_edge;
  1498. void *context;
  1499. LOGGER(
  1500. "[graph kruskal] graph %p, start vertex %u, minimum spanning tree %p\n",
  1501. graph, start_vertex_identifier, minimum_spanning_tree);
  1502. _ASSERT(graph, ==, NULL, NULL_POINTER, -1);
  1503. _ASSERT(minimum_spanning_tree, ==, NULL, NULL_POINTER, -1);
  1504. n = vector_get_size(graph->vertices);
  1505. _ASSERT(start_vertex_identifier, >=, n, INVALID_INPUT, -1);
  1506. edges = linked_list_new();
  1507. partial_trees = (linked_list_t *) _new(n * sizeof(linked_list_t));
  1508. for (i = 0; i < n; i++)
  1509. partial_trees[i] = linked_list_new();
  1510. linked_list_push_back(partial_trees[0], NULL);
  1511. // Add all the graph_t's edges in the list and sort it.
  1512. for (i = 0; i < n - 1; i++)
  1513. {
  1514. m_edge = graph->implementation->first_edge(graph->graph, i, &context);
  1515. while (1)
  1516. {
  1517. if (m_edge == NULL)
  1518. break;
  1519. j = vertex_get_identifier(edge_get_vertex2(m_edge));
  1520. if (j > i)
  1521. {
  1522. if (edge_get_cost(m_edge) < TEMELIA_INFINITY)
  1523. linked_list_push_back(edges, m_edge);
  1524. }
  1525. m_edge
  1526. = graph->implementation->next_edge(graph->graph, i,
  1527. &context);
  1528. }
  1529. linked_list_push_back(partial_trees[i + 1], (void *) (i + 1));
  1530. }
  1531. // Sort edges by their cost.
  1532. linked_list_sort(edges, _compare_edges_kruskal, NULL);
  1533. cost = 0;
  1534. for (it = linked_list_get_begin(edges); it != NULL; it
  1535. = linked_list_iterator_get_next(it))
  1536. {
  1537. i = vertex_get_identifier(edge_get_vertex1(
  1538. linked_list_iterator_get_key(it)));
  1539. j = vertex_get_identifier(edge_get_vertex2(
  1540. linked_list_iterator_get_key(it)));
  1541. ok = 1;
  1542. k1 = k2 = -1;
  1543. for (k = 0; k < n; k++)
  1544. {
  1545. if (!partial_trees[k])
  1546. continue;
  1547. if (linked_list_search_key(partial_trees[k], (void *) i,
  1548. _compare_nodes_kruskal, NULL) == NULL
  1549. && linked_list_search_key(partial_trees[k], (void *) j,
  1550. _compare_nodes_kruskal, NULL) != NULL)
  1551. k1 = k;
  1552. if (linked_list_search_key(partial_trees[k], (void *) j,
  1553. _compare_nodes_kruskal, NULL) == NULL
  1554. && linked_list_search_key(partial_trees[k], (void *) i,
  1555. _compare_nodes_kruskal, NULL) != NULL)
  1556. k2 = k;
  1557. if (linked_list_search_key(partial_trees[k], (void *) i,
  1558. _compare_nodes_kruskal, NULL) != NULL
  1559. && linked_list_search_key(partial_trees[k], (void *) j,
  1560. _compare_nodes_kruskal, NULL) != NULL)
  1561. {
  1562. ok = 0;
  1563. break;
  1564. }
  1565. }
  1566. if (ok)
  1567. {
  1568. cost += edge_get_cost(graph_get_edge(graph, i, j));
  1569. linked_list_iterator_set_next(
  1570. linked_list_get_end(partial_trees[k1]),
  1571. linked_list_get_begin(partial_trees[k2]));
  1572. linked_list_set_end(partial_trees[k1], linked_list_get_end(
  1573. partial_trees[k2]));
  1574. _delete(partial_trees[k2]);
  1575. partial_trees[k2] = NULL;
  1576. }
  1577. }
  1578. for (i = 0; i < n; i++)
  1579. if (partial_trees[i] != NULL)
  1580. *minimum_spanning_tree = partial_trees[i];
  1581. _delete(partial_trees);
  1582. linked_list_delete(edges);
  1583. return cost;
  1584. }
  1585. double graph_ford_fulkerson(graph_t graph, unsigned int source,
  1586. unsigned int destination, matrix_t max_flow)
  1587. {
  1588. unsigned int n = vector_get_size(graph->vertices);
  1589. linked_list_t path;
  1590. double _max_flow, _min_flow;
  1591. LOGGER(
  1592. "[graph ford fulkerson] graph %u, source %u, destination %u, flow matrix %p\n",
  1593. graph, source, destination, max_flow);
  1594. _ASSERT(graph, ==, NULL, NULL_POINTER, 0);
  1595. _ASSERT(source, >=, n, INVALID_INPUT, 0);
  1596. _ASSERT(destination, >=, n, INVALID_INPUT, 0);
  1597. _ASSERT(max_flow, ==, NULL, NULL_POINTER, 0);
  1598. _ASSERT(matrix_get_columns_number(max_flow), !=, matrix_get_rows_number(max_flow), INVALID_INPUT, 0);
  1599. // Initialize the flow matrix with 0 value.
  1600. _init_flow(max_flow);
  1601. // Initial max flow is 0.
  1602. _max_flow = 0;
  1603. /*
  1604. * The Ford Fulkerson algorithm is :
  1605. * 1. while there is a path from source to destination,
  1606. * such that the flow on that path may increase execute :
  1607. * 2. increase the flow on computed path at step 1.
  1608. * For finding a "good" path, i use DFS search.
  1609. */
  1610. while (1)
  1611. {
  1612. // Initialization for DFS.
  1613. path = linked_list_new();
  1614. _graph_reset_vertices(graph);
  1615. // Find a valid path from source to destination.
  1616. _flow_dfs(graph, source, destination, path, max_flow);
  1617. // End the algorithm if no path is found.
  1618. if (linked_list_get_size(path) == 0)
  1619. {
  1620. linked_list_delete(path);
  1621. break;
  1622. }
  1623. // Compute the min flow on this path
  1624. _min_flow = _min_flow_path(graph, max_flow, path);
  1625. // Add the min flow calculated above to the max_flow matrix
  1626. _add_flow_on_path(max_flow, path, _min_flow);
  1627. // Reset variables: vertices and path list
  1628. _graph_reset_vertices(graph);
  1629. linked_list_delete(path);
  1630. // Add the min-flow to max-flow, in order to return the desired result
  1631. _max_flow += _min_flow;
  1632. }
  1633. return _max_flow;
  1634. }
  1635. double graph_edmonds_karp(graph_t graph, unsigned int source,
  1636. unsigned int destination, matrix_t max_flow)
  1637. {
  1638. unsigned int n = vector_get_size(graph->vertices);
  1639. linked_list_t path;
  1640. double _max_flow, _min_flow;
  1641. LOGGER(
  1642. "[graph ford fulkerson] graph %u, source %u, destination %u, flow matrix %p\n",
  1643. graph, source, destination, max_flow);
  1644. _ASSERT(graph, ==, NULL, NULL_POINTER, 0);
  1645. _ASSERT(source, >=, n, INVALID_INPUT, 0);
  1646. _ASSERT(destination, >=, n, INVALID_INPUT, 0);
  1647. _ASSERT(max_flow, ==, NULL, NULL_POINTER, 0);
  1648. _ASSERT(matrix_get_columns_number(max_flow), !=, matrix_get_rows_number(max_flow), INVALID_INPUT, 0);
  1649. // Initialize the flow matrix with 0 value.
  1650. _init_flow(max_flow);
  1651. // Initial max flow is 0.
  1652. _max_flow = 0;
  1653. /*
  1654. * The Edmonds-Karp algorithm is :
  1655. * 1. while there is a path from source to destination,
  1656. * such that the flow on that path may increase execute :
  1657. * 2. increase the flow on computed path at step 1.
  1658. * For finding a "good" path, i use BFS search.
  1659. */
  1660. while (1)
  1661. {
  1662. // Initialization for BFS.
  1663. path = linked_list_new();
  1664. _graph_reset_vertices(graph);
  1665. // Find a valid path from source to destination.
  1666. _flow_bfs(graph, source, destination, path, max_flow);
  1667. // End the algorithm if no path is found : path contains only
  1668. // the destination vertex.
  1669. if (linked_list_get_size(path) <= 1)
  1670. {
  1671. linked_list_delete(path);
  1672. break;
  1673. }
  1674. // Compute the min flow on this path
  1675. _min_flow = _min_flow_path(graph, max_flow, path);
  1676. // If there is no flow, return.
  1677. // Actually, the algorithm should never execute this break,
  1678. // because _flow_BFS guarantees a "good" path; I wrote this
  1679. // statement "just in case"
  1680. if (_min_flow == 0)
  1681. break;
  1682. // Add the min flow calculated above to the max_flow matrix
  1683. _add_flow_on_path(max_flow, path, _min_flow);
  1684. // Reset variables: vertices and path list
  1685. _graph_reset_vertices(graph);
  1686. linked_list_delete(path);
  1687. // Add the min-flow to max-flow, in order to return the desired result
  1688. _max_flow += _min_flow;
  1689. }
  1690. return _max_flow;
  1691. }
  1692. // === Private functions implementation ===
  1693. static void _graph_dfs(graph_t graph, unsigned int node)
  1694. {
  1695. unsigned int node_next, nodes_number;
  1696. vertex_t vertex = vector_get_key_at(graph->vertices, node), vertex_next;
  1697. void *context;
  1698. // Return is the current node is not white or visited
  1699. if (vertex_get_color(vertex) != WHITE || vertex_get_visited(vertex))
  1700. return;
  1701. // Change vertex color to GRAY.
  1702. vertex_set_color(vertex, GRAY);
  1703. // Visit the node by setting visited variable accordingly
  1704. vertex_set_visited(vertex, 1);
  1705. // Set the time current node was discovered.
  1706. vertex_set_time_start(vertex, current_time++);
  1707. nodes_number = vector_get_size(graph->vertices);
  1708. vertex_next = graph->implementation->first_vertex(graph->graph, node,
  1709. &context);
  1710. while (1)
  1711. {
  1712. // No more neighbors
  1713. if (vertex_next == NULL)
  1714. break;
  1715. node_next = vertex_get_identifier(vertex_next);
  1716. // If 1, 2, 3 and 4 are true then next_node is a valid neighbor, from DFS point of view,
  1717. // I continue the travel from it.
  1718. // 1. node_next is a valid node in graph
  1719. // 2. it's color is white
  1720. // 3. it's not visited yet
  1721. // 4. there is an edge between node and node next
  1722. if (vertex_get_color(vertex_next) == WHITE && !vertex_get_visited(
  1723. vertex_next))
  1724. {
  1725. vertex_set_parent_identifier(vertex_next, node);
  1726. _graph_dfs(graph, node_next);
  1727. }
  1728. vertex_next = graph->implementation->next_vertex(graph->graph, node,
  1729. &context);
  1730. }
  1731. // Finished traveling this node, set it's time stop and it's color to black
  1732. vertex_set_time_stop(vertex, current_time++);
  1733. // Set it's color to black (DFS finished visiting this node)
  1734. vertex_set_color(vertex, BLACK);
  1735. }
  1736. static void _graph_bfs(graph_t graph, unsigned int node)
  1737. {
  1738. unsigned int nodes_number;
  1739. void *context;
  1740. queue_t queue;
  1741. vertex_t vertex, vertex_next;
  1742. vertex = vector_get_key_at(graph->vertices, node);
  1743. // Returns if current node isn't white or visited
  1744. if (vertex_get_color(vertex) != WHITE || vertex_get_visited(vertex))
  1745. return;
  1746. nodes_number = vector_get_size(graph->vertices);
  1747. // Vertices queue can have maximum of nodes_number keys
  1748. queue = queue_new(nodes_number);
  1749. // In BFS cost represents the distance from root to current vertex
  1750. // Root vertex has 0 cost and parent -1
  1751. vertex_set_color(vertex, GRAY);
  1752. vertex_set_cost(vertex, 0);
  1753. vertex_set_parent_identifier(vertex, -1);
  1754. vertex_set_visited(vertex, 1);
  1755. // Put the first vertex in the queue.
  1756. queue_push_back(queue, vertex);
  1757. // 0. while queue is not empty execute
  1758. // 1. extract a node from queue
  1759. // 2. for each unvisited node, adjacent with extracted node, do :
  1760. // 3. set new vertex parameters
  1761. // 4. insert neighbor in queue
  1762. while (!queue_is_empty(queue))
  1763. {
  1764. vertex = queue_get_front(queue);
  1765. node = vertex_get_identifier(vertex);
  1766. queue_pop_front(queue);
  1767. vertex_set_time_start(vertex, current_time++);
  1768. vertex_next = graph->implementation->first_vertex(graph->graph, node,
  1769. &context);
  1770. while (1)
  1771. {
  1772. if (vertex_next == NULL)
  1773. break;
  1774. // If the vertex exists, there is an edge from current node to it,
  1775. // it's color is white and was not visited, then is eligible
  1776. // to pushing back in the bfs travel queue.
  1777. if (vertex_get_color(vertex_next) == WHITE && !vertex_get_visited(
  1778. vertex_next))
  1779. {
  1780. // Push back in queue the next vertex
  1781. queue_push_back(queue, vertex_next);
  1782. // Set next vertex color to gray
  1783. vertex_set_color(vertex_next, GRAY);
  1784. // Set cost as 1 + cost(parent).
  1785. vertex_set_cost(vertex_next, 1 + vertex_get_cost(vertex));
  1786. // Set a link between vertex_next and vertex, by setting
  1787. // vertex_next parent's identifier
  1788. vertex_set_parent_identifier(vertex_next,
  1789. vertex_get_identifier(vertex));
  1790. // Set vertex as visited.
  1791. vertex_set_visited(vertex_next, 1);
  1792. }
  1793. vertex_next = graph->implementation->next_vertex(graph->graph,
  1794. node, &context);
  1795. }
  1796. // Finish BFS travel on this node.
  1797. vertex_set_color(vertex, BLACK);
  1798. vertex_set_time_stop(vertex, current_time++);
  1799. }
  1800. // Free the queue used by BFS.
  1801. queue_delete(queue);
  1802. }
  1803. static void _graph_reset_vertices(graph_t graph)
  1804. {
  1805. unsigned int node, nodes_number;
  1806. vertex_t vertex;
  1807. nodes_number = vector_get_size(graph->vertices);
  1808. for (node = 0; node < nodes_number; node++)
  1809. {
  1810. // For-each vertex in graph_t set their parameters to default value.
  1811. vertex = vector_get_key_at(graph->vertices, node);
  1812. vertex_set_color(vertex, WHITE);
  1813. vertex_set_parent_identifier(vertex, -1);
  1814. vertex_set_time_start(vertex, 0);
  1815. vertex_set_time_stop(vertex, 0);
  1816. vertex_set_visited(vertex, 0);
  1817. }
  1818. }
  1819. unsigned int _articulation_points_travel(graph_t graph, unsigned int u,
  1820. int *color, unsigned int *start, unsigned int *low,
  1821. unsigned int *parent, int *cut_vertex)
  1822. {
  1823. unsigned int subtrees = 0, v;
  1824. vertex_t vertex;
  1825. void *context;
  1826. color[u] = GRAY;
  1827. start[u] = ++current_time;
  1828. low[u] = start[u];
  1829. vertex = graph->implementation->first_vertex(graph->graph, u, &context);
  1830. while (1)
  1831. {
  1832. if (vertex == NULL)
  1833. break;
  1834. v = vertex_get_identifier(vertex);
  1835. if (color[v] == WHITE)
  1836. {
  1837. parent[v] = u;
  1838. _articulation_points_travel(graph, v, color, start, low, parent,
  1839. cut_vertex);
  1840. subtrees++;
  1841. if (low[v] < low[u])
  1842. low[u] = low[v];
  1843. if (low[v] >= start[u])
  1844. cut_vertex[u] = 1;
  1845. }
  1846. else if (color[v] == GRAY)
  1847. {
  1848. if (start[v] < low[u])
  1849. low[u] = start[v];
  1850. }
  1851. vertex = graph->implementation->next_vertex(graph->graph, u, &context);
  1852. }
  1853. color[u] = BLACK;
  1854. return subtrees;
  1855. }
  1856. static void _cycles_travel(graph_t graph, unsigned int current_node,
  1857. linked_list_t current_cycles, unsigned int *parent, int *color,
  1858. int *visited)
  1859. {
  1860. unsigned int next_node, n;
  1861. linked_list_t small_cycle;
  1862. vertex_t vertex;
  1863. void *context;
  1864. color[current_node] = GRAY;
  1865. visited[current_node] = 1;
  1866. n = vector_get_size(graph->vertices);
  1867. vertex = graph->implementation->first_vertex(graph->graph, current_node,
  1868. &context);
  1869. while (1)
  1870. {
  1871. if (vertex == NULL)
  1872. break;
  1873. next_node = vertex_get_identifier(vertex);
  1874. /*
  1875. * If there are two vertices u and v such that :
  1876. * 1. u and v are neighbors.
  1877. * 2. u isn't the parent of v
  1878. * 3. v is the next node in DFS travel, after visiting u.
  1879. * 4. v is already visited.
  1880. * Then u and v close a cycles.
  1881. * Rebuild the path and add the new cycle to cycles list.
  1882. */
  1883. if (visited[next_node] && color[next_node] == GRAY && parent[next_node]
  1884. != current_node)
  1885. {
  1886. small_cycle = linked_list_new();
  1887. _rebuild_cycle(current_node, next_node, parent, small_cycle);
  1888. if (linked_list_get_size(small_cycle) > 2)
  1889. linked_list_push_back(current_cycles, small_cycle);
  1890. else
  1891. linked_list_delete(small_cycle);
  1892. }
  1893. vertex = graph->implementation->next_vertex(graph->graph, current_node,
  1894. &context);
  1895. }
  1896. vertex = graph->implementation->first_vertex(graph->graph, current_node,
  1897. &context);
  1898. while (1)
  1899. {
  1900. if (vertex == NULL)
  1901. break;
  1902. next_node = vertex_get_identifier(vertex);
  1903. if (color[next_node] == WHITE && !visited[next_node])
  1904. {
  1905. parent[next_node] = current_node;
  1906. _cycles_travel(graph, next_node, current_cycles, parent, color,
  1907. visited);
  1908. }
  1909. vertex = graph->implementation->next_vertex(graph->graph, current_node,
  1910. &context);
  1911. }
  1912. color[current_node] = BLACK;
  1913. }
  1914. static void _rebuild_cycle(unsigned int current_node, unsigned int next_node,
  1915. unsigned int *parent, linked_list_t small_cycle)
  1916. {
  1917. if (current_node == next_node)
  1918. {
  1919. linked_list_push_back(small_cycle, (void *) current_node);
  1920. return;
  1921. }
  1922. _rebuild_cycle(parent[current_node], next_node, parent, small_cycle);
  1923. linked_list_push_back(small_cycle, (void *) current_node);
  1924. }
  1925. static int _compare_nodes_unsigned(void *x, void *y, void *context)
  1926. {
  1927. return (int) ((unsigned long) x - (unsigned long) y);
  1928. }
  1929. static int _int_compare(void *x, void *y, void *context)
  1930. {
  1931. return (unsigned int) x - (unsigned int) y;
  1932. }
  1933. static int _compare_nodes_strongly_connected_components(void *x, void *y,
  1934. void *context)
  1935. {
  1936. // Compare the two vertices after their t_stop parameter.
  1937. // The context (vector of vertices) is stored in the global variable.
  1938. return vertex_get_time_stop(vector_get_key_at((vector_t) context,
  1939. (unsigned int) y)) - vertex_get_time_stop(vector_get_key_at(
  1940. (vector_t) context, (unsigned int) x));
  1941. }
  1942. static int _compare_dijkstra(void *x, void *y, void *context)
  1943. {
  1944. vector_t distances = context;
  1945. double *a = (double *) vector_get_key_at(distances, (unsigned int) x);
  1946. double *b = (double *) vector_get_key_at(distances, (unsigned int) y);
  1947. if (*a < *b)
  1948. return -1;
  1949. else if (*a > *b)
  1950. return +1;
  1951. // If the vertices have the same distance from source then
  1952. // i compare them after their identifiers.
  1953. return (unsigned int) x - (unsigned int) y;
  1954. }
  1955. static int _compare_prim(void *x, void *y, void *context)
  1956. {
  1957. double *distances = context;
  1958. unsigned int v1, v2;
  1959. v1 = (unsigned int) x;
  1960. v2 = (unsigned int) y;
  1961. if (distances[v1] < distances[v2])
  1962. return -1;
  1963. else if (distances[v1] > distances[v2])
  1964. return 1;
  1965. // If the vertices have the same distance from source then
  1966. // i compare them after their identifiers.
  1967. return v1 - v2;
  1968. }
  1969. static int _compare_edges_kruskal(void *x, void *y, void *context)
  1970. {
  1971. edge_t edge1, edge2;
  1972. double a, b;
  1973. edge1 = x;
  1974. edge2 = y;
  1975. a = edge_get_cost(edge1);
  1976. b = edge_get_cost(edge2);
  1977. if (a < b)
  1978. return -1;
  1979. if (a > b)
  1980. return 1;
  1981. return 0;
  1982. }
  1983. static int _compare_nodes_kruskal(void *x, void *y, void *context)
  1984. {
  1985. return (int) ((unsigned long) x - (unsigned long) y);
  1986. }
  1987. static void _init_flow(matrix_t flow)
  1988. {
  1989. unsigned int i, j, n;
  1990. n = matrix_get_columns_number(flow);
  1991. // For-each key in the matrix, set it's value to 0.
  1992. for (i = 0; i < n; i++)
  1993. for (j = 0; j < n; j++)
  1994. *(double *) matrix_get_key_at(flow, i, j) = 0;
  1995. }
  1996. static void _flow_dfs(graph_t graph, unsigned int current_node,
  1997. unsigned int destination, linked_list_t path, matrix_t max_flow)
  1998. {
  1999. /*
  2000. * Basically, the current function has the same idea as ordinary DFS travel.
  2001. * The main difference is that this method adds flow constrains on links
  2002. * between vertices.
  2003. * For example, if an edge is saturated (flow = capacity) then the vertices
  2004. * aren't neighbors; in ordinary DFS they are.
  2005. * With other words, _flow_dfs works with function cost equals to edge_capacity - edge_flow;
  2006. * and DFS works with edge_flow as 0 identity function.
  2007. */
  2008. vertex_t u = vector_get_key_at(graph->vertices, current_node);
  2009. unsigned int next_node, nodes_number;
  2010. double capacity;
  2011. nodes_number = vector_get_size(graph->vertices);
  2012. if (vertex_get_visited(u))
  2013. return;
  2014. vertex_set_visited(u, 1);
  2015. linked_list_push_back(path, (void *) current_node);
  2016. if (current_node == destination)
  2017. return;
  2018. for (next_node = 0; next_node < nodes_number; next_node++)
  2019. /* Travel the next_node only if :
  2020. * 1. destination isn't visited
  2021. * 2. next_node isn't visited.
  2022. */
  2023. if (!vertex_get_visited(vector_get_key_at(graph->vertices, destination))
  2024. && !vertex_get_visited(vector_get_key_at(graph->vertices,
  2025. next_node)))
  2026. {
  2027. /*
  2028. * 1. If there is an edge between current_node and next_node
  2029. * then continue only if the flow is smaller then the cost (capacity).
  2030. *
  2031. * 2. If there isn't an edge between current_node and next_node
  2032. * then consider the capacity 0 and go on if the flow is negative.
  2033. */
  2034. if (graph_is_edge(graph, current_node, next_node))
  2035. capacity = edge_get_cost(graph_get_edge(graph, current_node,
  2036. next_node));
  2037. else
  2038. capacity = 0;
  2039. if (*(double *) matrix_get_key_at(max_flow, current_node, next_node)
  2040. < capacity)
  2041. _flow_dfs(graph, next_node, destination, path, max_flow);
  2042. }
  2043. if (!vertex_get_visited(vector_get_key_at(graph->vertices, destination)))
  2044. {
  2045. linked_list_remove_key(path, (void *) current_node, _int_compare, NULL,
  2046. 1);
  2047. vertex_set_visited(vector_get_key_at(graph->vertices, current_node), 0);
  2048. }
  2049. }
  2050. static void _flow_bfs(graph_t graph, unsigned int source,
  2051. unsigned int destination, linked_list_t path, matrix_t max_flow)
  2052. {
  2053. queue_t queue;
  2054. vertex_t vertex, current_vertex;
  2055. unsigned int next_node, current_node, nodes_number;
  2056. void *context;
  2057. /*
  2058. * Basically, this function has the same idea as ordinary BFS function.
  2059. * The main difference is that this method adds flow constrains on links
  2060. * between vertices.
  2061. * See _flow_dfs for more details about the last statement.
  2062. */
  2063. nodes_number = vector_get_size(graph->vertices);
  2064. vertex = vector_get_key_at(graph->vertices, source);
  2065. vertex_set_visited(vertex, 1);
  2066. vertex_set_parent_identifier(vertex, (unsigned int) -1);
  2067. queue = queue_new(nodes_number);
  2068. queue_push_back(queue, vertex);
  2069. while (!queue_is_empty(queue))
  2070. {
  2071. current_vertex = queue_get_front(queue);
  2072. current_node = vertex_get_identifier(current_vertex);
  2073. queue_pop_front(queue);
  2074. vertex = graph->implementation->first_vertex(graph->graph,
  2075. current_node, &context);
  2076. while (1)
  2077. {
  2078. if (vertex == NULL)
  2079. break;
  2080. next_node = vertex_get_identifier(vertex);
  2081. if ((CAPACITY(graph, current_node, next_node)) > (FLOW(max_flow,
  2082. current_node, next_node)) && !vertex_get_visited(vertex))
  2083. {
  2084. vertex_set_visited(vertex, 1);
  2085. vertex_set_parent_identifier(vertex, current_node);
  2086. queue_push_back(queue, vertex);
  2087. }
  2088. vertex = graph->implementation->next_vertex(graph->graph,
  2089. current_node, &context);
  2090. }
  2091. }
  2092. // After the BFS modified travel ended, i compute the path between
  2093. // destination and source, analyzing each vertex parent.
  2094. current_node = destination;
  2095. while (current_node != (unsigned int) -1)
  2096. {
  2097. linked_list_push_front(path, (void *) current_node);
  2098. current_node = vertex_get_parent_identifier(vector_get_key_at(
  2099. graph->vertices, current_node));
  2100. }
  2101. // Free the queue used.
  2102. queue_delete(queue);
  2103. }
  2104. static double _min_flow_path(graph_t graph, matrix_t max_flow,
  2105. linked_list_t path)
  2106. {
  2107. double min_flow, aux;
  2108. unsigned i, j, k, n;
  2109. linked_list_iterator_t it;
  2110. /*
  2111. * Finds the minimum flow for a given path : a(0), a(1) .... a(N).
  2112. * a - list of vertices.
  2113. * The algorithm is trivial :
  2114. * 1. for-each a(K) and a(K+1), K from 0 to N-1 execute :
  2115. * 2. if the current min_flow is greater the flow from a(K) to a(K+1),
  2116. * then actualize current min_flow to the smaller flow value.
  2117. * 3. return the min_flow.
  2118. */
  2119. it = linked_list_get_begin(path);
  2120. i = (unsigned int) linked_list_iterator_get_key(it);
  2121. it = linked_list_iterator_get_next(it);
  2122. j = (unsigned int) linked_list_iterator_get_key(it);
  2123. it = linked_list_iterator_get_next(it);
  2124. min_flow = CAPACITY(graph, i, j) - FLOW(max_flow, i, j);
  2125. n = linked_list_get_size(path);
  2126. for (k = 1; k < n - 1; k++)
  2127. {
  2128. i = j;
  2129. j = (unsigned int) linked_list_iterator_get_key(it);
  2130. it = linked_list_iterator_get_next(it);
  2131. aux = CAPACITY(graph, i, j) - FLOW(max_flow, i, j);
  2132. if (aux < min_flow)
  2133. min_flow = aux;
  2134. }
  2135. return min_flow;
  2136. }
  2137. static void _add_flow_on_path(matrix_t max_flow, linked_list_t path,
  2138. double min_flow)
  2139. {
  2140. unsigned i, j, k, n;
  2141. linked_list_iterator_t it;
  2142. /*
  2143. * Increases the flow from a given path : a(0), a(1) .... a(N).
  2144. * a - list of vertices.
  2145. * The algorithm is trivial :
  2146. * 1.for-each a(K) and a(K+1), increase the flow with min_flow value.
  2147. * 2.for-each a(K+1) and a(K), decrease the flow with min_flow value.
  2148. * The second statement is used because flow(u,v) = -flow(v,u).
  2149. */
  2150. it = linked_list_get_begin(path);
  2151. i = (unsigned int) linked_list_iterator_get_key(it);
  2152. it = linked_list_iterator_get_next(it);
  2153. j = (unsigned int) linked_list_iterator_get_key(it);
  2154. it = linked_list_iterator_get_next(it);
  2155. (*(double *) matrix_get_key_at(max_flow, i, j)) += min_flow;
  2156. (*(double *) matrix_get_key_at(max_flow, j, i)) -= min_flow;
  2157. n = linked_list_get_size(path);
  2158. for (k = 1; k < n - 1; k++)
  2159. {
  2160. i = j;
  2161. j = (unsigned int) linked_list_iterator_get_key(it);
  2162. it = linked_list_iterator_get_next(it);
  2163. (*(double *) matrix_get_key_at(max_flow, i, j)) += min_flow;
  2164. (*(double *) matrix_get_key_at(max_flow, j, i)) -= min_flow;
  2165. }
  2166. }
  2167. INLINE static double CAPACITY(graph_t graph, unsigned int i, unsigned int j)
  2168. {
  2169. if (!graph_is_edge(graph, i, j))
  2170. return 0;
  2171. return edge_get_cost(graph_get_edge(graph, i, j));
  2172. }
  2173. INLINE static double FLOW(matrix_t max_flow, unsigned int i, unsigned int j)
  2174. {
  2175. return *(double *) matrix_get_key_at(max_flow, i, j);
  2176. }
  2177. // === End ===