2

I am currently developing an application to create tours for motorbikes. At the current stage of development there is a start/endpoint and several points which outline the tour. Between these points the pgr_dijkstra function is used (with a customized cost function). The problem is best described by the picture attached.

Problem

Is there a way to avoid an edge getting traveled twice? I have tried to use the reverse cost column with a high cost but as the graph is not directed I get odd results. At least the pgrouting documentation states that the graph has to be directed to use the reverse cost if I understood that correctly.

sql := 'SELECT DISTINCT ON (seq) 
        seq, id, the_geom, id1 AS node, id2 AS edge, cost, km 
            FROM pgr_dijkstra(''
                 SELECT id,
                 source::integer,
                 target::integer,
                 my_cost::double precision AS cost,
                     FROM network 
                     WHERE network.the_geom && bbox
            '',' || source || ',' || target || ', false, false), 
            network WHERE id2 = network.id';

This is the statement to create a part of the route. It is nested inside a loop which passes new source and target in every iteration as long as there are some. This code is executed and returned record-wise.

1

First thing I see is (folowing documentation) if you want to include rewerse_cost in your function you have to include it in select, so:

sql := 'SELECT DISTINCT ON (seq) 
        seq, id, the_geom, id1 AS node, id2 AS edge, cost, km 
            FROM pgr_dijkstra(''
                 SELECT id,
                 source::integer,
                 target::integer,
                 my_cost::double precision AS cost,
                 my_reverse_cost::double precision AS reverse_cost 
                     FROM network 
                     WHERE network.the_geom && bbox
            '',' || source || ',' || target || ', false, false), 
            network WHERE id2 = network.id';

But I think It's not the resolution. Maybe you should try to create stored procedure as (pseudo-code):

  1. Create tmp table tmp_network as select * from network n where n.way && st_expand(st_envelope(st_union(search_points)))
  2. create tmp table tmp_resolution as select 1 as segment, * from first part of route using tmp_network
  3. update tmp_network set cost = cost*2(4,8,100??) where exists (select 1 from tmp_resolution where id=id and segment = 1)
  4. insert into tmp_resolution select 2 as segment, * from second part of route using tmp_network.
    ....

This (after tuning) will prevent routing via once selected edge if another way is possible and resonable.

If you need hardcore version just delete edges instead updating cost.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.