2
2
3
3
import com .alipay .kepler .util .SerDeHelper ;
4
4
import com .antfin .arc .arch .message .graph .Edge ;
5
+ import com .antfin .arc .arch .message .graph .Vertex ;
5
6
import com .antfin .arch .cstore .benchmark .RandomWord ;
7
+ import com .antfin .graph .Graph ;
8
+ import com .antfin .graph .refObj .Graph_Map_CSR ;
6
9
import java .io .BufferedReader ;
7
10
import java .io .File ;
8
11
import java .io .FileOutputStream ;
9
12
import java .io .IOException ;
10
13
import java .nio .charset .Charset ;
11
14
import java .nio .file .Files ;
12
15
import java .util .ArrayList ;
16
+ import java .util .Comparator ;
13
17
import java .util .HashMap ;
14
18
import java .util .List ;
15
19
import java .util .Map ;
20
+ import java .util .PriorityQueue ;
21
+ import java .util .Queue ;
16
22
import javafx .util .Pair ;
17
23
18
24
public class GraphHelper {
@@ -111,7 +117,7 @@ public static Object loadObject(File file) throws IOException {
111
117
}
112
118
113
119
public static void writeObject (Object object , File file ) throws IOException {
114
- if (!file .getParentFile ().exists ()){
120
+ if (!file .getParentFile ().exists ()) {
115
121
file .getParentFile ().mkdirs ();
116
122
}
117
123
file .createNewFile ();
@@ -122,15 +128,15 @@ public static void writeObject(Object object, File file) throws IOException {
122
128
opStream .close ();
123
129
}
124
130
125
- public static List <Edge <String , String >> loadEdges (String path ){
131
+ public static List <Edge <String , String >> loadEdges (String path ) {
126
132
List <Edge <String , String >> edges = new ArrayList <>();
127
- readKVFile (path ).forEach (pair -> {
133
+ readKVFile (path ).forEach (pair -> {
128
134
edges .add (new Edge <>(pair .getKey (), pair .getValue (), RandomWord .getWords (100 )));
129
135
});
130
136
return edges ;
131
137
}
132
138
133
- public static List <Pair <String , String >> readKVFile (String path ){
139
+ public static List <Pair <String , String >> readKVFile (String path ) {
134
140
File file = new File (path );
135
141
if (!file .exists ()) {
136
142
System .err .println (path + " is not exist!" );
@@ -140,11 +146,11 @@ public static List<Pair<String, String>> readKVFile(String path){
140
146
String line = null ;
141
147
while ((line = reader .readLine ()) != null ) {
142
148
line = line .trim ();
143
- if (line .length () == 0 )
149
+ if (line .length () == 0 ) {
144
150
continue ;
151
+ }
145
152
String [] vid = line .split (" " );
146
- if (vid .length != 2 )
147
- {
153
+ if (vid .length != 2 ) {
148
154
System .err .println (line + " must include source and sink!" );
149
155
}
150
156
pairs .add (new Pair <>(vid [0 ], vid [1 ]));
@@ -154,4 +160,83 @@ public static List<Pair<String, String>> readKVFile(String path){
154
160
}
155
161
return pairs ;
156
162
}
163
+
164
+ /**
165
+ * return the closest distance from source to target by A* search algorithm.
166
+ */
167
+ public static <K > double getClosestDistance (Vertex source , Vertex target , Graph graph , Map <K , List <Double >> embedding , DistanceFunction disFun ) {
168
+ return getClosestDistance ((K ) source .getId (), (K ) target .getId (), graph , embedding , disFun );
169
+ }
170
+
171
+ public static <K > double getClosestDistance (K source , K target , Graph graph , Map <K , List <Double >> embedding , DistanceFunction disFun ) {
172
+ if (source .equals (target )){
173
+ return 0.0 ;
174
+ }
175
+ double distanceBetweenNodes = 0 ;
176
+ Map <K , Integer > dictV ;
177
+ // build Adjacency Matrix
178
+ if (graph instanceof Graph_Map_CSR ) {
179
+ dictV = ((Graph_Map_CSR ) graph ).getDictV ();
180
+ } else {
181
+ dictV = new HashMap <>();
182
+ System .err .format ("The type of graph is not Graph_Map_CSR!" );
183
+ }
184
+ // [H,G,F]
185
+ double [][] distance = new double [dictV .size ()][2 ];
186
+ Queue <K > candidate = new PriorityQueue <K >(new Comparator <K >() {
187
+ public int compare (K c1 , K c2 ) {
188
+ if (distance [dictV .get (c1 )][2 ] > distance [dictV .get (c2 )][2 ]) {
189
+ return 1 ;
190
+ } else if (distance [dictV .get (c1 )][2 ] == distance [dictV .get (c2 )][2 ]) {
191
+ return 0 ;
192
+ } else {
193
+ return -1 ;
194
+ }
195
+ }
196
+ });
197
+ boolean [] closed = new boolean [dictV .size ()];
198
+ // record the path <node, parent>
199
+ Map <K , K > shortestPath = new HashMap <>();
200
+ // init
201
+ distance [dictV .get (target )][1 ] = Double .MIN_VALUE ;
202
+ distance [dictV .get (source )][0 ] = disFun .calcDistance (embedding .get (source ), embedding .get (target ));
203
+ distance [dictV .get (source )][1 ] = 0.0 ;
204
+ distance [dictV .get (source )][2 ] = distance [dictV .get (source )][0 ] + distance [dictV .get (source )][1 ];
205
+ candidate .add (source );
206
+ while (!candidate .isEmpty ()) {
207
+ K cur = candidate .poll ();
208
+ closed [dictV .get (cur )] = true ;
209
+ for (Object e : ((List ) graph .getEdge (cur ))){
210
+ K nbr = (K ) ((Edge )e ).getTargetId ();
211
+ if (!closed [dictV .get (nbr )]) {
212
+ double h = disFun .calcDistance (embedding .get (nbr ), embedding .get (target ));
213
+ double g = distance [dictV .get (cur )][1 ] + distanceBetweenNodes ;
214
+ double f = h + g ;
215
+
216
+ if (!candidate .contains (nbr )) {
217
+ shortestPath .put (nbr , cur );
218
+ candidate .add (nbr );
219
+ distance [dictV .get (nbr )][0 ] = h ;
220
+ distance [dictV .get (nbr )][1 ] = g ;
221
+ distance [dictV .get (nbr )][2 ] = f ;
222
+ } else if (f < distance [dictV .get (nbr )][2 ]) {
223
+ shortestPath .put (nbr , cur );
224
+ distance [dictV .get (nbr )][1 ] = g ;
225
+ distance [dictV .get (nbr )][2 ] = f ;
226
+ }
227
+ }
228
+ }
229
+ if (cur .equals (target )) {
230
+ StringBuilder sb = new StringBuilder ();
231
+ while (!shortestPath .get (target ).equals (source )) {
232
+ sb .append (target ).append (" <- " );
233
+ target = shortestPath .get (target );
234
+ }
235
+ sb .append (source );
236
+ System .out .println ("The path is: " + sb .reverse ().toString ());
237
+ return distance [dictV .get (target )][1 ];
238
+ }
239
+ }
240
+ return distance [dictV .get (target )][1 ];
241
+ }
157
242
}
0 commit comments