11use super :: * ;
2+ use as_slice:: AsSlice ;
23use :: io;
34use std:: io:: Result ;
45use std:: path:: Path ;
56
67#[ derive( Debug , Clone ) ]
7- pub struct FirstOutGraph {
8+ pub struct FirstOutGraph < FirstOutContainer , HeadContainer , WeightContainer > where
9+ FirstOutContainer : AsSlice < u32 > ,
10+ HeadContainer : AsSlice < NodeId > ,
11+ WeightContainer : AsSlice < Weight > ,
12+ {
813 // index of first edge of each node +1 entry in the end
9- first_out : Vec < u32 > ,
14+ first_out : FirstOutContainer ,
1015 // the node ids to which each edge points
11- head : Vec < NodeId > ,
16+ head : HeadContainer ,
1217 // the weight of each edge
13- weight : Vec < Weight >
18+ weight : WeightContainer ,
1419}
1520
16- impl FirstOutGraph {
17- pub fn new ( first_out : Vec < u32 > , head : Vec < NodeId > , weight : Vec < Weight > ) -> FirstOutGraph {
18- assert_eq ! ( * first_out. first( ) . unwrap( ) , 0 ) ;
19- assert_eq ! ( * first_out. last( ) . unwrap( ) as usize , head. len( ) ) ;
20- assert_eq ! ( weight. len( ) , head. len( ) ) ;
21+ pub type OwnedGraph = FirstOutGraph < Vec < u32 > , Vec < NodeId > , Vec < Weight > > ;
2122
22- FirstOutGraph {
23- first_out, head, weight
24- }
23+ impl < FirstOutContainer , HeadContainer , WeightContainer > FirstOutGraph < FirstOutContainer , HeadContainer , WeightContainer > where
24+ FirstOutContainer : AsSlice < u32 > ,
25+ HeadContainer : AsSlice < NodeId > ,
26+ WeightContainer : AsSlice < Weight > ,
27+ {
28+ fn first_out ( & self ) -> & [ u32 ] { self . first_out . as_slice ( ) }
29+ fn head ( & self ) -> & [ u32 ] { self . head . as_slice ( ) }
30+ fn weight ( & self ) -> & [ u32 ] { self . weight . as_slice ( ) }
31+
32+ pub fn new ( first_out : FirstOutContainer , head : HeadContainer , weight : WeightContainer ) -> FirstOutGraph < FirstOutContainer , HeadContainer , WeightContainer > {
33+ assert_eq ! ( * first_out. as_slice( ) . first( ) . unwrap( ) , 0 ) ;
34+ assert_eq ! ( * first_out. as_slice( ) . last( ) . unwrap( ) as usize , head. as_slice( ) . len( ) ) ;
35+ assert_eq ! ( weight. as_slice( ) . len( ) , head. as_slice( ) . len( ) ) ;
36+
37+ FirstOutGraph { first_out, head, weight }
38+ }
39+
40+ pub fn write_to_dir ( & self , dir : & str ) -> Result < ( ) > {
41+ let path = Path :: new ( dir) ;
42+ let res1 = io:: write_vector_to_file ( path. join ( "first_out" ) . to_str ( ) . unwrap ( ) , self . first_out ( ) ) ;
43+ let res2 = io:: write_vector_to_file ( path. join ( "head" ) . to_str ( ) . unwrap ( ) , self . head ( ) ) ;
44+ let res3 = io:: write_vector_to_file ( path. join ( "weights" ) . to_str ( ) . unwrap ( ) , self . weight ( ) ) ;
45+ res1. and ( res2) . and ( res3)
2546 }
2647
27- pub fn from_adjancecy_lists ( adjancecy_lists : Vec < Vec < Link > > ) -> FirstOutGraph {
48+ pub fn decompose ( self ) -> ( FirstOutContainer , HeadContainer , WeightContainer ) {
49+ ( self . first_out , self . head , self . weight )
50+ }
51+ }
52+
53+ impl OwnedGraph {
54+ pub fn from_adjancecy_lists ( adjancecy_lists : Vec < Vec < Link > > ) -> OwnedGraph {
2855 // create first_out array for reversed by doing a prefix sum over the adjancecy list sizes
2956 let first_out = std:: iter:: once ( 0 ) . chain ( adjancecy_lists. iter ( ) . scan ( 0 , |state, incoming_links| {
3057 * state = * state + incoming_links. len ( ) as u32 ;
@@ -37,70 +64,43 @@ impl FirstOutGraph {
3764 . flat_map ( |neighbors| neighbors. into_iter ( ) . map ( |Link { node, weight } | ( node, weight) ) )
3865 . unzip ( ) ;
3966
40- FirstOutGraph :: new ( first_out, head, weight)
41- }
42-
43- pub fn neighbor_iter ( & self , node : NodeId ) -> std:: iter:: Map < std:: iter:: Zip < std:: slice:: Iter < NodeId > , std:: slice:: Iter < Weight > > , fn ( ( & NodeId , & Weight ) ) ->Link > {
44- let range = ( self . first_out [ node as usize ] as usize ) ..( self . first_out [ ( node + 1 ) as usize ] as usize ) ;
45- self . head [ range. clone ( ) ] . iter ( )
46- . zip ( self . weight [ range] . iter ( ) )
47- . map ( |( & neighbor, & weight) | Link { node : neighbor, weight : weight } )
48- }
49-
50- pub fn edge_index ( & self , from : NodeId , to : NodeId ) -> Option < usize > {
51- let first_out = self . first_out [ from as usize ] as usize ;
52- self . neighbor_iter ( from) . enumerate ( ) . find ( |& ( _, Link { node, .. } ) | node == to) . map ( |( i, _) | first_out + i )
53- }
54-
55- pub fn reverse ( & self ) -> FirstOutGraph {
56- // vector of adjacency lists for the reverse graph
57- let mut reversed: Vec < Vec < Link > > = ( 0 ..self . num_nodes ( ) ) . map ( |_| Vec :: < Link > :: new ( ) ) . collect ( ) ;
58-
59- // iterate over all edges and insert them in the reversed structure
60- for node in 0 ..( self . num_nodes ( ) as NodeId ) {
61- for Link { node : neighbor, weight } in self . neighbor_iter ( node) {
62- reversed[ neighbor as usize ] . push ( Link { node, weight } ) ;
63- }
64- }
65- FirstOutGraph :: from_adjancecy_lists ( reversed)
66- }
67-
68- pub fn ch_split ( self , node_ranks : & Vec < u32 > ) -> ( FirstOutGraph , FirstOutGraph ) {
69- let mut up: Vec < Vec < Link > > = ( 0 ..self . num_nodes ( ) ) . map ( |_| Vec :: < Link > :: new ( ) ) . collect ( ) ;
70- let mut down: Vec < Vec < Link > > = ( 0 ..self . num_nodes ( ) ) . map ( |_| Vec :: < Link > :: new ( ) ) . collect ( ) ;
71-
72- // iterate over all edges and insert them in the reversed structure
73- for node in 0 ..( self . num_nodes ( ) as NodeId ) {
74- for Link { node : neighbor, weight } in self . neighbor_iter ( node) {
75- if node_ranks[ node as usize ] < node_ranks[ neighbor as usize ] {
76- up[ node as usize ] . push ( Link { node : neighbor, weight } ) ;
77- } else {
78- down[ neighbor as usize ] . push ( Link { node, weight } ) ;
79- }
80- }
81- }
82-
83- ( FirstOutGraph :: from_adjancecy_lists ( up) , FirstOutGraph :: from_adjancecy_lists ( down) )
67+ OwnedGraph :: new ( first_out, head, weight)
8468 }
69+ }
8570
86- pub fn write_to_dir ( & self , dir : & str ) -> Result < ( ) > {
87- let path = Path :: new ( dir) ;
88- let res1 = io:: write_vector_to_file ( path. join ( "first_out" ) . to_str ( ) . unwrap ( ) , & self . first_out ) ;
89- let res2 = io:: write_vector_to_file ( path. join ( "head" ) . to_str ( ) . unwrap ( ) , & self . head ) ;
90- let res3 = io:: write_vector_to_file ( path. join ( "weights" ) . to_str ( ) . unwrap ( ) , & self . weight ) ;
91- res1. and ( res2) . and ( res3)
71+ impl < FirstOutContainer , HeadContainer , WeightContainer > Graph for FirstOutGraph < FirstOutContainer , HeadContainer , WeightContainer > where
72+ FirstOutContainer : AsSlice < u32 > ,
73+ HeadContainer : AsSlice < NodeId > ,
74+ WeightContainer : AsSlice < Weight > ,
75+ {
76+ fn num_nodes ( & self ) -> usize {
77+ self . first_out ( ) . len ( ) - 1
9278 }
9379}
9480
95- impl DijkstrableGraph for FirstOutGraph {
96- fn num_nodes ( & self ) -> usize {
97- self . first_out . len ( ) - 1
81+ impl < ' a , FirstOutContainer , HeadContainer , WeightContainer > LinkIterGraph < ' a > for FirstOutGraph < FirstOutContainer , HeadContainer , WeightContainer > where
82+ FirstOutContainer : AsSlice < u32 > ,
83+ HeadContainer : AsSlice < NodeId > ,
84+ WeightContainer : AsSlice < Weight > ,
85+ {
86+ type Iter = std:: iter:: Map < std:: iter:: Zip < std:: slice:: Iter < ' a , NodeId > , std:: slice:: Iter < ' a , Weight > > , fn ( ( & NodeId , & Weight ) ) ->Link > ;
87+
88+ fn neighbor_iter ( & ' a self , node : NodeId ) -> Self :: Iter {
89+ let range = ( self . first_out ( ) [ node as usize ] as usize ) ..( self . first_out ( ) [ ( node + 1 ) as usize ] as usize ) ;
90+ self . head ( ) [ range. clone ( ) ] . iter ( )
91+ . zip ( self . weight ( ) [ range] . iter ( ) )
92+ . map ( |( & neighbor, & weight) | Link { node : neighbor, weight : weight } )
9893 }
94+ }
9995
100- fn for_each_neighbor ( & self , node : NodeId , f : & mut FnMut ( Link ) ) {
101- for link in self . neighbor_iter ( node) {
102- f ( link) ;
103- }
96+ impl < FirstOutContainer , HeadContainer , WeightContainer > RandomLinkAccessGraph for FirstOutGraph < FirstOutContainer , HeadContainer , WeightContainer > where
97+ FirstOutContainer : AsSlice < u32 > ,
98+ HeadContainer : AsSlice < NodeId > ,
99+ WeightContainer : AsSlice < Weight > ,
100+ {
101+ fn edge_index ( & self , from : NodeId , to : NodeId ) -> Option < usize > {
102+ let first_out = self . first_out ( ) [ from as usize ] as usize ;
103+ self . neighbor_iter ( from) . enumerate ( ) . find ( |& ( _, Link { node, .. } ) | node == to) . map ( |( i, _) | first_out + i )
104104 }
105105}
106106
0 commit comments