eg_dagsp.c

Go to the documentation of this file.
00001 /* EGlib "Efficient General Library" provides some basic structures and
00002  * algorithms commons in many optimization algorithms.
00003  *
00004  * Copyright (C) 2005 Daniel Espinoza and Marcos Goycoolea.
00005  * 
00006  * This library is free software; you can redistribute it and/or modify it
00007  * under the terms of the GNU Lesser General Public License as published by the
00008  * Free Software Foundation; either version 2.1 of the License, or (at your
00009  * option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful, but 
00012  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
00013  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public 
00014  * License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public License
00017  * along with this library; if not, write to the Free Software Foundation,
00018  * Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA 
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 /* marks: 
00097    
00098    0 untouched
00099    1 in list
00100    2 done
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     /* skip terminated nodes and search for directed cycles */
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     /* if current node is 'finished' */
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     /* mark the node as 'incomplete' */
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 }

Generated on Mon Jan 30 08:48:52 2006 for EGlib by  doxygen 1.4.5