root/trunk/core/src/shooting_star_relax.hpp

Revision 72, 4.4 KB (checked in by anton, 3 years ago)

Shooting* restrictions fixed, crashes fixed

Line 
1//=======================================================================
2// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
3// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek,
4//
5// Copyright 2007 Orkney, Inc.
6// Author: Anton A. Patrushev
7//
8// Distributed under the Boost Software License, Version 1.0. (See
9// accompanying file LICENSE_1_0.txt or copy at
10// http://www.boost.org/LICENSE_1_0.txt)
11//=======================================================================
12#ifndef BOOST_GRAPH_SHOOTING_STAR_RELAX_HPP
13#define BOOST_GRAPH_SHOOTING_STAR_RELAX_HPP
14
15#include <functional>
16#include <boost/limits.hpp> // for numeric limits
17#include <boost/graph/graph_traits.hpp>
18#include <boost/property_map.hpp>
19
20#include <postgres.h>
21
22#define U_TURN_COST 100000
23
24bool is_equal ( int a[], int b[], int size )
25{
26  for ( int i = 0; i < size; i++ )
27  {
28    if ( a[i] != b[i] )
29    return false;
30  }
31             
32  return true;
33}
34
35namespace boost {
36
37    // The following version of the plus functor prevents
38    // problems due to overflow at positive infinity.
39
40    template <class T>
41    struct closed_plus
42    {
43      // std::abs just isn't portable :(
44      template <class X>
45      inline X my_abs(const X& x) const { return x < 0 ? -x : x; }
46
47      T operator()(const T& a, const T& b) const {
48        using namespace std;
49        T inf = (numeric_limits<T>::max)();
50        if (b > 0 && my_abs(inf - a) < b)
51          return inf;
52        return a + b;
53      }
54    };
55   
56    template <class Edge, class Graph, class WeightMap, class EdgeMap,
57            class PredecessorMap, class DistanceMap, class CostMap,
58            class BinaryFunction, class BinaryPredicate>
59    bool relax(Edge e,
60               Edge pe,
61               const Graph& g, const WeightMap& w, const EdgeMap& em,
62               PredecessorMap& p, DistanceMap& d, CostMap& c,
63               const BinaryFunction& combine, const BinaryPredicate& compare,
64               int e_max_id)
65    {
66      typedef typename graph_traits<Graph>::directed_category DirCat;
67      bool is_undirected = is_same<DirCat, undirected_tag>::value;
68
69      typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
70           
71      Vertex u = source(e, g), v = target(e, g), pu = source(pe, g);
72
73      typedef typename property_traits<DistanceMap>::value_type D;
74      typedef typename property_traits<WeightMap>::value_type W;
75     
76      typedef typename property_traits<EdgeMap>::value_type E;
77     
78      D d_e = get(d, e);
79      D d_pe = get(d, pe);
80     
81      W w_e = get(w, e);
82
83      //edge where we came from
84      bool edge_exists;
85     
86      W w_pe_e;
87
88      E w_pe = get(em, e);
89     
90      int contains = -1;
91       
92      Edge ce = pe;
93      int e_id;
94
95      std::vector<Edge> edge_h;
96      typedef typename std::vector<Edge>::iterator It;
97
98      for(int i=0; i< w_pe[g[e].id].size(); ++i)
99     
100      if(w_pe[g[e].id].at(i).second.size() < 1 || w_pe[g[e].id].at(i).second.back() > 0)
101      {
102     
103      for(int j=0; j<w_pe[g[e].id].at(i).second.size(); ++j)
104      {
105        e_id = g[ce].id;
106       
107        if(w_pe[g[e].id].at(i).second.at(j) == -1)
108          continue;
109       
110        if(w_pe[g[e].id].at(i).second.at(j) == e_id || w_pe[g[e].id].at(i).second.at(j)+e_max_id == e_id||
111           w_pe[g[e].id].at(i).second.at(j) == e_id+e_max_id || w_pe[g[e].id].at(i).second.at(j)+e_max_id == e_id+e_max_id)
112        {
113         contains = i;
114         edge_h.push_back(ce);
115        }
116        else if(i == contains)
117        {
118         contains = -1;
119        }
120       
121        ce = p[g[ce].id];
122      }
123     
124      }
125     
126      //calculate w_pe_e
127      if(contains >= 0)
128      {
129        w_pe_e = w_pe[g[e].id].at(contains).first;
130      }
131      else if(abs(g[e].id-g[pe].id) == e_max_id)
132      {
133        w_pe_e = U_TURN_COST;
134      }
135      else
136      {
137        w_pe_e = 0;
138      }
139
140      //Ugly combination with w_e_pe.
141
142      if ( compare(combine(combine(d_pe, get(w, pe)), w_pe_e), d_e))
143      {
144        put(d, e, combine(combine(d_pe, get(w, pe)), w_pe_e));
145        p[g[e].id] = pe;
146
147        return true;
148      }
149      else
150      {
151        return false;
152      }
153    }
154
155    template <class Graph, class WeightMap, class EdgeMap,
156      class PredecessorMap, class DistanceMap>
157    bool relax(typename graph_traits<Graph>::edge_descriptor e,
158               const Graph& g, WeightMap w, EdgeMap em, PredecessorMap p, DistanceMap d)
159    {
160      typedef typename property_traits<DistanceMap>::value_type D;
161      typedef closed_plus<D> Combine;
162      typedef std::less<D> Compare;
163      return relax(e, g, w, em, p, d, Combine(), Compare());
164    }
165
166} // namespace boost
167
168#endif
Note: See TracBrowser for help on using the browser.