eg_bellford.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_bellford.h"
00021 
00022 int EGbellFord (EGdGraphNode_t * s,
00023                 size_t * os,
00024                 EGdGraph_t * G)
00025 {
00026 
00027   unsigned int i;
00028   EGlistNode_t *nit,
00029    *eit;
00030   EGdGraphNode_t *n;
00031   EGdGraphEdge_t *e;
00032 
00033   EGbellFordInitialize (s, G, os);
00034 
00035   for (i = 0; i < G->nodes->size; i++)
00036     for (nit = G->nodes->begin; nit; nit = nit->next)
00037     {
00038       n = (EGdGraphNode_t *) (nit->this);
00039       for (eit = n->out_edges->begin; eit; eit = eit->next)
00040       {
00041         e = (EGdGraphEdge_t *) (eit->this);
00042         EGbellFordRelax (e, os);
00043       }
00044     }
00045 
00046   return EGbellFordIsNegativeCycle (G, os);
00047 
00048 }
00049 
00050 int EGbellFordFast (EGdGraphNode_t * s,
00051                     EGdijkstraCost_t ubound,
00052                     size_t * os,
00053                     EGdGraph_t * G)
00054 {
00055 
00056   unsigned int i;
00057   EGlistNode_t *nit,
00058    *eit;
00059   EGdGraphNode_t *n;
00060   EGdGraphEdge_t *e;
00061 
00062   EGbellFordInitialize (s, G, os);
00063 
00064   for (i = 0; i < G->nodes->size; i++)
00065     for (nit = G->nodes->begin; nit; nit = nit->next)
00066     {
00067       n = (EGdGraphNode_t *) (nit->this);
00068       for (eit = n->out_edges->begin; eit; eit = eit->next)
00069       {
00070         e = (EGdGraphEdge_t *) (eit->this);
00071         EGbellFordRelax (e, os);
00072       }
00073     }
00074 
00075   return EGbellFordIsNegativeCycle (G, os);
00076 
00077 }
00078 
00079 void EGbellFordInitialize (EGdGraphNode_t * s,
00080                            EGdGraph_t * G,
00081                            size_t * os)
00082 {
00083 
00084   EGlistNode_t *it;
00085 
00086   for (it = G->nodes->begin; it; it = it->next)
00087   {
00088     EGdijkstraSetDist (it->this, os, EG_DIJKSTRA_COST_MAX);
00089     EGdijkstraSetNdist (it->this, os, INT_MAX);
00090     EGdijkstraSetFather (it->this, os, 0);
00091   }
00092 
00093   EGdijkstraSetDist (s, os, EGdijkstraToCost (0.0));
00094   EGdijkstraSetNdist (s, os, 0);
00095 
00096   return;
00097 
00098 }
00099 
00100 void EGbellFordRelax (EGdGraphEdge_t * e,
00101                       size_t * os)
00102 {
00103 
00104   EGdijkstraCost_t relax =
00105     EGdijkstraGetDist (e->tail, os) + EGdijkstraGetEdgeLength (e, os);
00106   int ndist = EGdijkstraGetNdist (e->tail, os) + 1;
00107 
00108   if (EGdijkstraCostIsLess (relax, EGdijkstraGetDist (e->head, os)))
00109   {
00110     EGdijkstraSetNdist (e->head, os, ndist);
00111     EGdijkstraSetDist (e->head, os, relax);
00112     EGdijkstraSetFather (e->head, os, e);
00113   }
00114 
00115   return;
00116 
00117 }
00118 
00119 int EGbellFordIsNegativeCycle (EGdGraph_t * G,
00120                                size_t * os)
00121 {
00122 
00123   EGdGraphNode_t *n;
00124   EGdGraphEdge_t *e;
00125   EGlistNode_t *nit,
00126    *eit;
00127 
00128   for (nit = G->nodes->begin; nit; nit = nit->next)
00129   {
00130     n = (EGdGraphNode_t *) (nit->this);
00131     for (eit = n->out_edges->begin; eit; eit = eit->next)
00132     {
00133       e = (EGdGraphEdge_t *) (eit->this);
00134 
00135       EGdijkstraCost_t lhs =
00136         EGdijkstraGetDist (e->tail, os) + EGdijkstraGetEdgeLength (e, os);
00137 
00138       if (EGdijkstraCostIsLess (lhs, EGdijkstraGetDist (e->head, os)))
00139         return 1;
00140     }
00141   }
00142 
00143   return 0;
00144 
00145 }

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