def test_collapse_degree_2_vtxs(): g = igraph.Graph(directed=True) # a square with a diagonal + tail g.add_vertices(5) # the square g.add_edges([ (0, 1), (1, 2), (2, 3), (3, 0), ]) # the diagonal g.add_edges([(0, 2)]) # the tail g.add_edges([(1, 4)]) g.es["weight"] = range(6) # so now vertex 3 is just a thru-node eq_(len(g.vs), 5) eq_(len(g.es), 6) eq_(len(g.vs.select(_degree_eq=1)), 1) eq_(len(g.vs.select(_degree_eq=2)), 1) eq_(len(g.vs.select(_degree_eq=3)), 3) ret = gt.collapse_degree_2_vtxs(g) eq_(ret, 1) # Now it is clean eq_(len(g.vs), 4) eq_(len(g.es), 5) eq_(len(g.vs.select(_degree_eq=1)), 1) eq_(len(g.vs.select(_degree_eq=2)), 0) eq_(len(g.vs.select(_degree_eq=3)), 3)
def test_collapse_degree_2_vtxs_bollard(): # We should not remove nodes are source/sink only. g = igraph.Graph(directed=True) # two boxes g.add_vertices(6) # the outer rectange g.add_edges([ (1, 0), (0, 5), (2, 1), (2, 3), (3, 4), (4, 5), ]) # the center line g.add_edges([(4, 1)]) eq_(g.vs[0].indegree(), 1) eq_(g.vs[0].outdegree(), 1) eq_(g.vs[5].indegree(), 2) eq_(g.vs[5].outdegree(), 0) eq_(g.vs[1].indegree(), 2) eq_(g.vs[1].outdegree(), 1) eq_(g.vs[2].indegree(), 0) eq_(g.vs[2].outdegree(), 2) eq_(g.vs[3].indegree(), 1) eq_(g.vs[3].outdegree(), 1) eq_(g.vs[4].indegree(), 1) eq_(g.vs[4].outdegree(), 2) # so now vertex 0 and 3 are thru-ways # vertex 5 and 2 are bollards eq_(len(g.vs), 6) eq_(len(g.es), 7) g.es["weight"] = range(7) assert(gt.is_bollard(g.vs[2])) assert(gt.is_bollard(g.vs[5])) assert(not gt.is_bollard(g.vs[1])) assert(not gt.is_bollard(g.vs[3])) ret = gt.collapse_degree_2_vtxs(g) # deleted 4 eq_(ret, 2) # Now it is clean eq_(len(g.vs), 4) print [es.tuple for es in g.es] eq_(len(g.es), 5) eq_(len(g.vs.select(_degree_eq=2, _indegree_gt=0, _outdegree_gt=0)), 0)
def test_collapse_degree_2_vtxs_bollard(): # We should not remove nodes are source/sink only. g = igraph.Graph(directed=True) # two boxes g.add_vertices(6) # the outer rectange g.add_edges([ (1, 0), (0, 5), (2, 1), (2, 3), (3, 4), (4, 5), ]) # the center line g.add_edges([(4, 1)]) eq_(g.vs[0].indegree(), 1) eq_(g.vs[0].outdegree(), 1) eq_(g.vs[5].indegree(), 2) eq_(g.vs[5].outdegree(), 0) eq_(g.vs[1].indegree(), 2) eq_(g.vs[1].outdegree(), 1) eq_(g.vs[2].indegree(), 0) eq_(g.vs[2].outdegree(), 2) eq_(g.vs[3].indegree(), 1) eq_(g.vs[3].outdegree(), 1) eq_(g.vs[4].indegree(), 1) eq_(g.vs[4].outdegree(), 2) # so now vertex 0 and 3 are thru-ways # vertex 5 and 2 are bollards eq_(len(g.vs), 6) eq_(len(g.es), 7) g.es["weight"] = range(7) assert(gt.is_bollard(g.vs[2])) assert(gt.is_bollard(g.vs[5])) assert(not gt.is_bollard(g.vs[1])) assert(not gt.is_bollard(g.vs[3])) ret = gt.collapse_degree_2_vtxs(g) # deleted 4 eq_(ret, 2) # Now it is clean eq_(len(g.vs), 4) print [es.tuple for es in g.es]
def main(args): parser = argparse.ArgumentParser() parser.add_argument('output', metavar='graph.pickle', help='Ouput graph file') parser.add_argument( '--connection', default='postgresql://*****:*****@localhost/osrm', help='Postgres connection string. Default %(default)s') parser.add_argument('--prune', action='store_true', help='Collapse redundant edges, prune tails') parser.add_argument('--verbose', action='store_true', help='Increase logging level') args = parser.parse_args() logging.basicConfig( level=logging.INFO if args.verbose else logging.WARNING) log.info("Creating DB engine") engine = create_engine(args.connection, echo=False) log.info("Creating DB session") Session = sessionmaker(bind=engine) session = Session() g = build_graph(session) if args.prune: log.info("Collapsing unidirectional strings") pruned = graphtools.collapse_degree_2_vtxs(g) log.info("Removed %i thru-nodes", pruned) log.info("Collapsing bidirectional strings") pruned = graphtools.collapse_bidirectional_streets(g) log.info("Removed %i thru-nodes", pruned) log.info("Snipping tails") snipped = graphtools.delete_degree_1_vtxs(g) log.info("Removed %i tails", snipped) loners = graphtools.delete_degree_0_vtxs(g) log.info("Removed %i loner-nodes (should be zero)", loners) redundancies = graphtools.identify_rendudant_nodes(g) log.info("Marked %i nodes as redundant", redundancies) log.info("Saving graph to %s", args.output) g.save(args.output)
def test_collapse_degree_2_vtxs_complex(): g = igraph.Graph(directed=True) # two boxes g.add_vertices(6) # the outer rectange g.add_edges([ (0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 0), ]) # the center line g.add_edges([(1, 4)]) # This makes it so all collapsed edges # have conserved flow. g.es["weight"] = [ 3, 4, 4, 4, 3, 3, 2 ] eq_(g.es[g.get_eid(1, 4)]["weight"], 2) eq_(g.es[g.get_eid(0, 1)]["weight"], 3) eq_(g.es[g.get_eid(1, 2)]["weight"], 4) # so now vertex 5-0 and 2-3 are thru-ways eq_(len(g.vs), 6) eq_(len(g.es), 7) ret = gt.collapse_degree_2_vtxs(g) # deleted 4 eq_(ret, 4) # Now it is clean eq_(len(g.vs), 2) eq_(len(g.es), 3) eq_(len(g.vs.select(_degree_eq=2)), 0) # Edge weights should be respected eq_(g.es["weight"], [2, 3, 4])
def main(args): parser = argparse.ArgumentParser() parser.add_argument('output', metavar='graph.pickle', help='Ouput graph file') parser.add_argument( '--connection', default='postgresql://*****:*****@localhost/osrm', help='Postgres connection string. Default %(default)s' ) parser.add_argument('--prune', action='store_true', help='Collapse redundant edges, prune tails') parser.add_argument('--verbose', action='store_true', help='Increase logging level') args = parser.parse_args() logging.basicConfig( level=logging.INFO if args.verbose else logging.WARNING) log.info("Creating DB engine") engine = create_engine(args.connection, echo=False) log.info("Creating DB session") Session = sessionmaker(bind=engine) session = Session() g = build_graph(session) if args.prune: log.info("Collapsing unidirectional strings") pruned = graphtools.collapse_degree_2_vtxs(g) log.info("Removed %i thru-nodes", pruned) log.info("Collapsing bidirectional strings") pruned = graphtools.collapse_bidirectional_streets(g) log.info("Removed %i thru-nodes", pruned) log.info("Snipping tails") snipped = graphtools.delete_degree_1_vtxs(g) log.info("Removed %i tails", snipped) loners = graphtools.delete_degree_0_vtxs(g) log.info("Removed %i loner-nodes (should be zero)", loners) redundancies = graphtools.identify_rendudant_nodes(g) log.info("Marked %i nodes as redundant", redundancies) log.info("Saving graph to %s", args.output) g.save(args.output)