00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "eg_dagsp.h"
00021
00022 int EGdagsp (EGdGraphNode_t * s,
00023 size_t * os,
00024 EGdGraph_t * G)
00025 {
00026
00027 int rval;
00028 EGmemPool_t *mem;
00029 EGlist_t *sort;
00030 EGlistNode_t *nit,
00031 *eit;
00032 EGdGraphNode_t *n;
00033 EGdGraphEdge_t *e;
00034
00035 mem = G->mem;
00036 sort = EGnewList (mem);
00037
00038 EGdagspInitialize (s, G, os);
00039
00040 rval = EGdagspTopologicSort (G, s, sort, os, mem);
00041 CHECKRVAL (rval);
00042
00043 for (nit = sort->begin; nit; nit = nit->next)
00044 {
00045 n = (EGdGraphNode_t *) (nit->this);
00046 for (eit = n->out_edges->begin; eit; eit = eit->next)
00047 {
00048 e = (EGdGraphEdge_t *) (eit->this);
00049 EGdagspRelax (e, os);
00050 }
00051 }
00052
00053 EGfreeList (sort);
00054
00055 return 0;
00056
00057 }
00058
00059 void EGdagspInitialize (EGdGraphNode_t * s,
00060 EGdGraph_t * G,
00061 size_t * os)
00062 {
00063
00064 EGlistNode_t *it;
00065
00066 for (it = G->nodes->begin; it; it = it->next)
00067 {
00068 EGdijkstraSetDist (it->this, os, EG_DIJKSTRA_COST_MAX);
00069 EGdijkstraSetFather (it->this, os, 0);
00070 EGdijkstraSetMarker (it->this, os, 0);
00071 }
00072
00073 EGdijkstraSetDist (s, os, EGdijkstraToCost (0.0));
00074
00075 return;
00076
00077 }
00078
00079 void EGdagspRelax (EGdGraphEdge_t * e,
00080 size_t * os)
00081 {
00082
00083 EGdijkstraCost_t relax =
00084 EGdijkstraGetDist (e->tail, os) + EGdijkstraGetEdgeLength (e, os);
00085
00086 if (EGdijkstraCostIsLess (relax, EGdijkstraGetDist (e->head, os)))
00087 {
00088 EGdijkstraSetDist (e->head, os, relax);
00089 EGdijkstraSetFather (e->head, os, e);
00090 }
00091
00092 return;
00093
00094 }
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104 int EGdagspTopologicSort (EGdGraph_t * G,
00105 EGdGraphNode_t * s,
00106 EGlist_t * sort,
00107 size_t * os,
00108 EGmemPool_t * mem)
00109 {
00110 int rval = 0;
00111 EGlist_t *dfs_list;
00112 EGlistNode_t **it,
00113 *eit;
00114 EGdGraphNode_t *current_node;
00115 EGdGraphEdge_t *e;
00116 TEST (sort->size, "sort not empty");
00117 it = EGmemPoolSMalloc (mem, EGlistNode_t *, G->node_id_max);
00118 dfs_list = EGnewList (mem);
00119 current_node = s;
00120 EGlistPushBack (dfs_list, current_node);
00121 it[current_node->id] = current_node->out_edges->begin;
00122
00123 while (dfs_list->size)
00124 {
00125 current_node = (EGdGraphNode_t *) (dfs_list->end->this);
00126 eit = it[current_node->id];
00127
00128
00129 while (eit)
00130 {
00131 e = (EGdGraphEdge_t *) (eit->this);
00132 if (EGdijkstraGetMarker (e->head, os) == 1)
00133 {
00134 rval = 1;
00135 goto CLEANUP;
00136 }
00137 if (EGdijkstraGetMarker (e->head, os) == 0)
00138 break;
00139 eit = eit->next;
00140 }
00141
00142
00143 if (!eit)
00144 {
00145 EGlistPushHead (sort, current_node);
00146 EGdijkstraSetMarker (current_node, os, 2);
00147 EGlistErase (dfs_list, dfs_list->end, nullFree);
00148 continue;
00149 }
00150
00151
00152 EGdijkstraSetMarker (current_node, os, 1);
00153 EGlistPushBack (dfs_list, e->head);
00154 it[e->head->id] = e->head->out_edges->begin;
00155 it[current_node->id] = it[current_node->id]->next;
00156 }
00157
00158 CLEANUP:
00159 EGmemPoolSFree (it, EGlistNode_t *, G->node_id_max, mem);
00160 EGfreeList (dfs_list);
00161 return rval;
00162 }