<br><br><div class="gmail_quote">On Wed, May 25, 2011 at 8:47 AM, Stephen Woodbridge <span dir="ltr">&lt;<a href="mailto:woodbri@swoodbridge.com">woodbri@swoodbridge.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
<div class="im">On 5/24/2011 7:06 PM, Jay Mahadeokar wrote:<br>
</div><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;"><div class="im">
<br>
<br>
On Mon, May 23, 2011 at 8:03 PM, Stephen Woodbridge<br></div><div class="im">
&lt;<a href="mailto:woodbri@swoodbridge.com" target="_blank">woodbri@swoodbridge.com</a> &lt;mailto:<a href="mailto:woodbri@swoodbridge.com" target="_blank">woodbri@swoodbridge.com</a>&gt;&gt; wrote:<br>
<br></div><div><div></div><div class="h5">
    I&#39;m not a C++ programmer, but from what I have read on the boost<br>
    list, it seems that the path to writing generic templates is to<br>
    write the code first in regular C++ so it works and then refactor it<br>
    to be more generic. So step 1 is to do as you proposed.<br>
<br>
    Also since this project is to implement a &quot;time dependent dijkstra<br>
    algorithm&quot; in pgRouting, the generic templates seems to be out of<br>
    scope. It would be fine to do if you had the time and skill, but I<br>
    think your approach makes sense, use the tools that make your job<br>
    easier and allow you to achieve success.<br>
<br>
    Any contrary opinions to this?<br>
<br>
    -Steve<br>
<br>
<br>
    On 5/23/2011 10:20 AM, Jay Mahadeokar wrote:<br>
<br>
        Hi,<br>
<br>
        As initially discussed, I was trying to reuse the boost&#39;s<br>
        dijkstra code<br>
        to write the core time dependent dijkstra algorithm.<br>
        Since Boost makes extensive use of generic programming, and I<br>
        have no<br>
        prior experience with such deep generic programming concepts, I was<br>
        wondering if we really need all these features that boost provides.<br>
<br>
        Another option would be to write the time-dependent dijkstra on<br>
        our own.<br>
<br>
        This will be a light-weight code without extensive use of generic<br>
        programming like boost.<br>
        So, i was thinking of using following:<br>
<br>
        *1. *Boost::AdjecencyList - for storing graph.<br>
        *2. *Std::Map - for storing distanceMap, predecessorMap.<br>
<br>
        *3. *For weightMap:<br>
<br>
        typedef struct weight_map_element<br>
        {<br>
                 pair&lt;int,double&gt; edge;<br>
                 double travel_time;<br>
        }<br>
        weight_map_element_t;<br>
<br>
        class weight_map<br>
        {<br>
<br>
             vector&lt;weight_map_element_t&gt; weight_map_set;<br>
<br>
             public:<br>
             void insert(weight_map_element_t element);<br>
             double get_travel_time(int edge_id, double start_time);<br>
<br>
        };<br>
<br>
<br>
        *4. *std::priority_queue  for the priority queue that will be<br>
        used for<br>
        dijkstra search.<br>
<br>
<br>
Well,<br>
The std::prority_queue does not support the decrease_key operation which<br>
will be needed for the dijkstra search. I dont think stl provides a heap<br>
data structure with decrease_key, delete_min and insert operations.<br>
<br>
The make_heap, and sort_heap would be too costly to maintain for dijkstra.<br>
<br>
Do you have any idea of open-source library that provides the heap<br>
datastructure with above functionality?<br>
<br>
I am thinking of implementing binary heap myself to support the required<br>
functionality.<br>
Thoughts?<br>
</div></div></blockquote>
<br>
Jay,<br>
<br>
What about looking at the code in Booost Graph that does this. There is probably some generic template code, but maybe you can just reuse the algorithms and recode your own specific to this problem implementation.<br>
<br>
<br>
Ashraf,<br>
<br>
You implemented your own Dijkstra algorithm in OpenGraphRouter, can you point Jay to your code there so that he can assess reusing some of that fore this project. I think the following might do the trick<br>
<br>
<a href="http://sourceforge.net/projects/opengraphrouter/" target="_blank">http://sourceforge.net/projects/opengraphrouter/</a><br>
<br>
Look here at ShortestPathDikjstra.cpp, it looks like Ashraf is using a Boost Mutable Queue:<br>
<a href="http://opengraphrouter.svn.sourceforge.net/viewvc/opengraphrouter/tags/Newstructure/tags/gsoc2009/src/?pathrev=111" target="_blank">http://opengraphrouter.svn.sourceforge.net/viewvc/opengraphrouter/tags/Newstructure/tags/gsoc2009/src/?pathrev=111</a><br>

<br>
<br></blockquote><div><br><br>Thanks Steve for the suggestion. I actually implemented a BinaryHeap class for exact requirements, and it seems to be solving the purpose. <br><br>The basic functions in class are:<br><br><br>
class binary_heap<br>{<br>    vector&lt;Vertex&gt; heap;<br>    <br>    void heapify(int index);<br>    <br>    public:<br>    <br>    void insert(Vertex v);  //inserts v into heap and rebalances it so that heap property is maintained.<br>
    double decrease_key(int index, double delta); // Decreases key of vertex with id = index, by delta.<br>    Vertex delete_min();  //deletes the min key vertex and rebalances heap.<br>    <br>};<br><br>Note that in binary heap all above operations need O(log n) time. <br>
<br>I will complete the initial draft of the algorithm soon and update it on github in next few days. <br>We can see what else is needed then.<br><br></div><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">

-Steve<br>
<br>
<blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;"><div class="im">
        Will this be sufficient for our implementation?  If yes, I will<br>
        come up<br>
        with the detailed internal function prototypes soon.<br>
<br>
<br>
        On Wed, May 18, 2011 at 8:09 PM, Stephen Woodbridge<br>
        &lt;<a href="mailto:woodbri@swoodbridge.com" target="_blank">woodbri@swoodbridge.com</a> &lt;mailto:<a href="mailto:woodbri@swoodbridge.com" target="_blank">woodbri@swoodbridge.com</a>&gt;<br></div><div><div></div>
<div class="h5">
        &lt;mailto:<a href="mailto:woodbri@swoodbridge.com" target="_blank">woodbri@swoodbridge.com</a><br>
        &lt;mailto:<a href="mailto:woodbri@swoodbridge.com" target="_blank">woodbri@swoodbridge.com</a>&gt;&gt;&gt; wrote:<br>
<br>
            On 5/18/2011 8:08 AM, Jay Mahadeokar wrote:<br>
<br>
                Hi,<br>
<br>
                I think what we need is a function on following lines:<br>
<br>
                Given a query_start_time, it should query the TimeDepCosts<br>
                table, and<br>
                return the set of entries which have their start_time within<br>
                query_start_time + delta. This delta might be x hours,<br>
        depending<br>
                on the<br>
                upper bound of the expected journey time.<br>
<br>
                We need following things handled in our model:<br>
<br>
                If query_start_time is 11PM Sunday and delta is 10 hours, we<br>
                will need<br>
                to query entries with start time between 11PM Sunday and 9AM<br>
                Monday. So,<br>
                basically the function needs to be periodic in terms of<br>
                time_of_day and<br>
                day_of_week.<br>
<br>
                As Steve suggested, we can maintain conventions for<br>
        day_of_week<br>
                like:<br>
<br>
                -3   - holidays<br>
                -2   - weekend days<br>
                -1   - week days<br>
                0    - all days<br>
                1-7 Mon - Sun.<br>
<br>
                If we just assume entries for -3,-2,-1,0 and ignore each<br>
        entry<br>
                for Sun -<br>
                Sat, that would reduce the space required assuming that the<br>
                entries for<br>
                weekdays is same. If times for different weekdays is<br>
        different<br>
                then we<br>
                would have separate entries for each day.<br>
<br>
                So, the query should properly examine the<br>
        query_day_of_week and<br>
                select<br>
                the proper entries. Ex: For above query, if it is<br>
        sunday, then after<br>
                12AM, next entries will be queried with time_of_day as<br>
        -1, but<br>
                if it was<br>
                Saturday, next entries will be queried with time_of_day<br>
        as -2.<br>
<br>
                We can have a boolean parameter like *isHoliday* in query<br>
                itself, which<br>
                will tell if a given day (may be weekday) is holiday or<br>
        not.Then<br>
                again<br>
                the query will have to be modified accordingly (query<br>
        for -3).<br>
                This will<br>
                take care of query for local holiday etc and we do not<br>
        have to worry<br>
                about calenders. The user will have to worry about<br>
        that.. :-)<br>
<br>
<br>
            This (isHoliday) might work for a single day, but will not<br>
        work if<br>
            the query crosses into the next day(s). Holidays are an input<br>
            convenience to describe recurring events. So say we have a<br>
            convenient way to input that data and store it into tables as we<br>
            have described, then the query for costs would need to<br>
        decide is a<br>
            given day is a holiday or not and then select the correct<br>
        entries to<br>
            return based on that. For ease of implementation, we could just<br>
            start with a stub function the returns false and later<br>
        implement a<br>
            table lookup based on the date or day of year that determines if<br>
            isHoliday=t/f for any given start_time+offset.<br>
<br>
            Then when querying schedules, for example, we would select<br>
        holiday<br>
            schedules if they exist and its a holiday otherwise search the<br>
            regular tables.<br>
<br>
<br>
                There can be time_from and time_to entries as well. But,<br>
        if we<br>
                just have<br>
                entries like:<br>
<br>
                  day_of_week: -1, time_of_day: 00:01, 55mph<br>
                  day_of_week: -1, time_of_day: 07:00, 30mph<br>
                  day_of_week: -1, time_of_day: 10:01, 55mph<br>
                  day_of_week: -1, time_of_day: 16:31, 30mph<br>
<br>
                we can assume that the entry with time_of_day 00:01 is<br>
        valid upto<br>
                07:00.  And if query_start_time is 02:00 and delta is 10<br>
        hours,<br>
                we can<br>
                query entries which have time_of_day &lt; query_start_time<br>
        + delta<br>
                (taking<br>
                care of change of day).<br>
<br>
                Is this assumption reasonable?<br>
<br>
<br>
            This sounds reasonable if the response is in units of time<br>
        (offset)<br>
            from query_start_time. Assuming we use a resolution of<br>
        seconds, then<br>
            the response would be in seconds from start time.<br>
<br>
                *weightMap Abstraction*<br>
<br>
<br>
                I think the design would be more modular if we keep the<br>
        weightMap<br>
                independent of the underlying time conventions. Since as<br>
        Daniel<br>
                pointed<br>
                out, this algorithm can also be used for non-road networks.<br>
<br>
                So, whatever the underlying time conventions, we can<br>
        assume that<br>
                in the<br>
                end the query should return pairs like:<br>
<br>
        &lt; &lt;edgeId, offset_time&gt; , travel_time/speed &gt;<br>
<br>
                We will assume that query_start_time is 0, i.e we offset<br>
        every<br>
                thing by<br>
                query_start_time.<br>
                The offset_time will be as follows:<br>
<br>
                As in above example,<br>
                If start_tme is 02:00 and day_of_week is -1, and delta<br>
        as 10 hours.<br>
<br>
                Then, edge entries for edgeId 1 will be:<br>
        &lt; &lt;1, 05:00 &gt; , 30 mph&gt;<br>
        &lt; &lt;1, 08:01 &gt; , 55 mph&gt;<br>
        &lt; &lt;1, 14:31 &gt; , 30 mph&gt;<br>
<br>
                Basically, the offset_time will abstract out any<br>
        internal details of<br>
                weekdays, change of days etc and it will just contain<br>
        the offset<br>
                from<br>
                start_time.<br>
<br>
<br>
            I suggested seconds above, but if someone is modeling events<br>
        in say<br>
            glacier flow, geological times or the big bang, they might need<br>
            other units of time. I would say that because we are talking<br>
        about<br>
            time based schedules and need to deal with days, hours<br>
        minutes we<br>
            should probably not worry about these other timeframes as<br>
        the solver<br>
            will be offset based it will work with any units and then<br>
        only the<br>
            wrappers for extracting the costs from the schedules would<br>
        need to<br>
            change to deal with other timeframes. So lets not get hung up on<br>
            this, I think this is a sound plan.<br>
<br>
            -Steve<br>
<br>
                This will greatly simplify the core time dependent dijkstra<br>
                implementation.<br>
<br>
                Thoughts?<br>
<br>
                On Wed, May 18, 2011 at 10:46 AM, Stephen Woodbridge<br>
        &lt;<a href="mailto:woodbri@swoodbridge.com" target="_blank">woodbri@swoodbridge.com</a> &lt;mailto:<a href="mailto:woodbri@swoodbridge.com" target="_blank">woodbri@swoodbridge.com</a>&gt;<br>
        &lt;mailto:<a href="mailto:woodbri@swoodbridge.com" target="_blank">woodbri@swoodbridge.com</a> &lt;mailto:<a href="mailto:woodbri@swoodbridge.com" target="_blank">woodbri@swoodbridge.com</a>&gt;&gt;<br>
        &lt;mailto:<a href="mailto:woodbri@swoodbridge.com" target="_blank">woodbri@swoodbridge.com</a> &lt;mailto:<a href="mailto:woodbri@swoodbridge.com" target="_blank">woodbri@swoodbridge.com</a>&gt;<br>
<br>
        &lt;mailto:<a href="mailto:woodbri@swoodbridge.com" target="_blank">woodbri@swoodbridge.com</a><br>
        &lt;mailto:<a href="mailto:woodbri@swoodbridge.com" target="_blank">woodbri@swoodbridge.com</a>&gt;&gt;&gt;&gt; wrote:<br>
<br>
                    Hi Daniel,<br>
<br>
                    These are good points.<br>
<br>
                    I agree that turn restrictions should be thought<br>
        about but only<br>
                    implemented if there is time. I think we should take the<br>
                discussion<br>
                    of turn restriction into a separate thread. I&#39;m<br>
        interested<br>
                in what<br>
                    you think is a limitation that can&#39;t be modeled in<br>
        Dijkstra<br>
                or A*.<br>
<br>
                    Regarding the time modeling, my point was just that we<br>
                needed more<br>
                    thought there and a richer model developed. The crontab<br>
                model is a<br>
                    good idea. I&#39;m not opposed to modeling monthly or yearly<br>
                events, but<br>
                    they rarely exist other than holidays which I tried to<br>
                capture. I<br>
                    suppose you could model something like the Boston<br>
        Marathon<br>
                and model<br>
                    all the road closures and restrictions, but it seems<br>
        to be a<br>
                lot of<br>
                    work for a one day event, but I can see city<br>
        government&#39;s<br>
                deploying<br>
                    the resources to model something like this.<br>
<br>
                    Regarding timezones: Times need to be entered with<br>
        zones for<br>
                models<br>
                    that cross zones but all the data should be<br>
        converted to UTC<br>
                    internally so it runs in a consistent time model.<br>
        Timezones<br>
                are for<br>
                    input and output, but the solver should be ignorant<br>
        of them,<br>
                in my<br>
                    opinion.<br>
<br>
                    I have carried my GPS from the Eastern to central<br>
        time zone,<br>
                and it<br>
                    knew the local time when I powered it up. So my<br>
        guess is that it<br>
                    would auto correct when crossing the time zone.<br>
<br>
                    -Steve<br>
<br>
<br>
                    On 5/17/2011 10:42 PM, Daniel Kastl wrote:<br>
<br>
                        Hi Jay and Steve,<br>
<br>
                        This looks really nice, but let me give some<br>
        comments<br>
                regarding<br>
                        how to<br>
                        model time, because this is really tricky in my<br>
        opinion.<br>
                        Especially when<br>
                        thinking about an abstract network that isn&#39;t a road<br>
                network.<br>
<br>
<br>
<br>
                            Would it be possible to support turn<br>
        restrictions in<br>
                the static<br>
                            Dijkstra also? I&#39;m thinking just use all the<br>
        same<br>
                structures but<br>
                            ignore the the time components to keep things<br>
                simple. So if<br>
                        the the<br>
                            turn restrictions table is present we use<br>
        it, otherwise<br>
                        assume no<br>
                            restrictions. If doing static shortest path<br>
        with turn<br>
                        restrictions<br>
                            then ignore the time components otherwise we use<br>
                them. And<br>
                        it is up<br>
                            to the user to make sure the turn<br>
        restriction table<br>
                is valid<br>
                        for the<br>
                            analysis being requested.<br>
<br>
<br>
                        Currently in pgRouting Dijkstra and A* don&#39;t<br>
        support turn<br>
                        restrictions<br>
                        modelling. What I actually like on Shooting Star<br>
        is, that it<br>
                        routes from<br>
                        edge to edge instead of node to node. So it<br>
        allows to model<br>
                        relations<br>
                        between edges rather than nodes, which I think<br>
        is more<br>
                close to how<br>
                        humans would think of this.<br>
                        Dijkstra can only visit one node one times (as<br>
        Shooting star<br>
                        only visits<br>
                        an edge once). Well, there can be turn<br>
        restriction cases<br>
                where a<br>
                        node is<br>
                        passed twice and which can&#39;t be done correctly with<br>
                Dijkstra as<br>
                        far as I<br>
                        know.<br>
<br>
                        In the beginning I wouldn&#39;t think about the turn<br>
                restrictions<br>
                        too much.<br>
                        Let&#39;s take it as an extra when we see we still have<br>
                enough time.<br>
                        Of course if you have a good idea to implement<br>
        it all at<br>
                once<br>
                        with only<br>
                        little extra work, then that&#39;s fine.<br>
<br>
<br>
                            For time definitions in your tables I think<br>
        you need<br>
                to probably<br>
                            define some common structure for handling a<br>
        time entry.<br>
<br>
<br>
                        Another problem might be time zones. Plain day<br>
        field + time<br>
                        field might<br>
                        not be able to allow driving from one time zone to<br>
                another (or just<br>
                        think about a flight network). I never went from one<br>
                timezone to<br>
                        another<br>
                        by car or train, but Steve and Anton, you might<br>
        have this<br>
                        experience.<br>
                        How does car navigation software handle this<br>
        when you<br>
                cross the<br>
                        timezone<br>
                        border? ;-)<br>
<br>
                        So taking &quot;timestamp with timezone&quot; for those fields<br>
                might be a good<br>
                        idea to be able to support such a functionality.<br>
<br>
<br>
                            For example time_from and time_to might need<br>
        to be<br>
                defined as a<br>
                            structure that includes day_of_week. day_of week<br>
                might take<br>
                        values like:<br>
<br>
                            -3   - holidays<br>
                            -2   - weekend days<br>
                            -1   - week days<br>
                            0    - all days<br>
                            1..7 - Sun,...,Sat<br>
<br>
<br>
                        I think the problem here is how to model<br>
        recurring time<br>
                        dependent costs,<br>
                        right?<br>
                        If you think about weekdays, then you can&#39;t for<br>
        example<br>
                model<br>
                        monthly or<br>
                        yearly events.<br>
<br>
                        I&#39;m not really sure this is useful information<br>
        here, but<br>
                I once saw<br>
                        about how the &quot;iCal&quot; format models recurring<br>
        calendar<br>
                events:<br>
        <a href="http://ext.ensible.com/deploy/dev/examples/calendar/recurrence-widget.html" target="_blank">http://ext.ensible.com/deploy/dev/examples/calendar/recurrence-widget.html</a><br>
<br>
                        Maybe we can learn something from there. The example<br>
                needed to be<br>
                        extended with some duration probably. But<br>
        looking about<br>
                calendar<br>
                        formats<br>
                        might be a good idea to model holidays etc.<br>
<br>
                        Or another (stupid) example would be cron job<br>
        syntax.<br>
                Something<br>
                        I always<br>
                        need to google for as I can&#39;t remember it ;-)<br>
<br>
                        All this time dependent stuff, events and<br>
        schedules is<br>
                also an<br>
                        issue in<br>
                        Darp solver.<br>
                        And it probably is important also for the<br>
        multi-modal<br>
                routing,<br>
                        so if we<br>
                        can find some clever way how to model this and<br>
        can share<br>
                it between<br>
                        algorihtms, that would be great.<br>
<br>
                        Daniel<br>
<br>
</div></div></blockquote><div><div></div><div class="h5">
_______________________________________________<br>
pgrouting-dev mailing list<br>
<a href="mailto:pgrouting-dev@lists.osgeo.org" target="_blank">pgrouting-dev@lists.osgeo.org</a><br>
<a href="http://lists.osgeo.org/mailman/listinfo/pgrouting-dev" target="_blank">http://lists.osgeo.org/mailman/listinfo/pgrouting-dev</a><br>
</div></div></blockquote></div><br><br clear="all"><br>-- <br>Regards,<br>-Jay Mahadeokar<br><br>