<math xmlns="http://www.w3.org/1998/Math/MathML"> <mi>x</mi> <mo>,</mo> <mi>y</mi> <mo>∈<!-- ∈ --></mo> <mi>X</mi> </math>
准备研究一下Dijkstra最短路径算法Hadoop上用MapReduce实现的过程。首先温习一下普通Dijkstra算法。
1) 数据结构准备:Graph,包括顶点类Vex,优先队列PQ:
package com.wlu.graph;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class Graph {
private Map<Vex, Map<Vex, Integer>> Vlist;
public Graph(Map<Vex, Map<Vex, Integer>> vvv) {
Vlist = vvv;
}
public static Graph CreateFromFile(String fileName) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(
new FileInputStream(fileName)));
Map<Vex, Map<Vex, Integer>> _Vlist = new HashMap<Vex, Map<Vex, Integer>>();
Map<String, Vex> name2Vex = new HashMap<String, Vex>();
for (String line = br.readLine(); line != null; line = br.readLine()) {
String[] vs = line.split(" ");
// 3 parts in the line
String vsrc = vs[0];
String vdes = vs[1];
int wsd = Integer.parseInt(vs[2]);
// add to the look up table
Vex src = null;
Vex dest = null;
if (name2Vex.containsKey(vsrc)) {
src = name2Vex.get(vsrc);
} else {
src = new Vex(vsrc);
name2Vex.put(vsrc, src);
}
if (name2Vex.containsKey(vdes)) {
dest = name2Vex.get(vdes);
} else {
dest = new Vex(vdes);
name2Vex.put(vdes, dest);
}
// add the new dest node information
// System.err.println(src.getName() + " " + dest.getName() + " " +
// wsd);
if (_Vlist.get(src) == null) {
HashMap<Vex, Integer> DestMap = new HashMap<Vex, Integer>();
DestMap.put(dest, wsd);
_Vlist.put(src, DestMap);
} else {
_Vlist.get(src).put(dest, wsd);
}
}
br.close();
return new Graph(_Vlist);
}
public String toString() {
String s = "";
for (Vex src : Vlist.keySet()) {
s += src.getName() + ": {";
for (Vex des : Vlist.get(src).keySet()) {
s += des.getName() + " (" + getw(src, des) + ")} {";
}
s = s.substring(0, s.length() - 1) + "\n";
}
return s;
}
public int getw(Vex u, Vex v) {
return Vlist.get(u).get(v);
}
public int getVexNum() {
return Vlist.keySet().size();
}
public Set<Vex> getVexs() {
return Vlist.keySet();
}
// get AdjacencyList of Vex u
public Map<Vex, Integer> AdjacencyList(Vex u) {
return Vlist.get(u);
}
public static void main(String args[]) throws IOException {
Graph g = Graph.CreateFromFile("C:/tmp/test.txt");
System.out.print(g.getVexNum() + "\n" + g);
}
}
package com.wlu.graph;
public class Vex {
private String name;
private int value;
public Vex(String n, int v) {
name = n;
value = v;
}
public Vex(String n) {
name = n;
value = 0;
}
@Override
public int hashCode(){
return name.hashCode();
}
@Override
public boolean equals(Object v){
return name.compareTo(((Vex)v).name) == 0;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
}
package com.wlu.graph;
import java.util.ArrayList;
import java.util.List;
public class PQ {
List<Vex> vlist = new ArrayList<Vex>();
public void add(Vex v) {
// remove the Vex if has exit
for(int i = 0; i < vlist.size(); i++){
if(vlist.get(i).getName().compareTo(v.getName()) == 0){
vlist.remove(i);
break;
}
}
int i = 0;
for (; i < vlist.size(); i++) {
if (v.getValue() < vlist.get(i).getValue()) {
break;
}
}
// insert v to ith position
List<Vex> vlist2 = new ArrayList<Vex>();
int j = 0;
for (; j < i; j++) {
vlist2.add(vlist.get(j));
}
vlist2.add(v);
for (int k = i; k < vlist.size(); k++) {
vlist2.add(vlist.get(k));
}
vlist = vlist2;
}
public Vex pop() {
if (vlist.size() == 0) {
return null;
}
Vex v = vlist.get(0);
vlist.remove(0);
return v;
}
public boolean empty() {
return vlist.size() == 0;
}
public void printPQ() {
for (Vex v : vlist) {
System.out.print(v.getName() + " (" + v.getValue() + ") ");
}
System.out.println();
}
public static void main(String args[]) {
PQ pq = new PQ();
pq.add(new Vex("a", 12));
pq.add(new Vex("b", 2));
pq.add(new Vex("c", 1));
pq.add(new Vex("d", 123));
pq.add(new Vex("e", 33));
pq.add(new Vex("f", 4));
pq.add(new Vex("g", 0));
pq.add(new Vex("h", 21));
pq.add(new Vex("i", 5));
pq.add(new Vex("j", 3));
pq.printPQ();
System.out.println(pq.pop().getName());
pq.printPQ();
}
}
2) Dijkstra算法
package com.wlu.dijkstra;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import com.wlu.graph.Graph;
import com.wlu.graph.PQ;
import com.wlu.graph.Vex;
public class DijkstraSeq {
public Graph MST(Graph G, Vex s) {
Map<Vex, Integer> d = new HashMap<Vex, Integer>();
d.put(s, 0);
PQ pq = new PQ();
pq.add(s);
for (Vex v : G.getVexs()) {
if (!v.equals(s)) {
d.put(v, Integer.MAX_VALUE);
}
}
while(!pq.empty()){
Vex u = pq.pop(); // ExtractMin
for(Vex v : G.AdjacencyList(u).keySet()){
if(d.get(v) > d.get(u) + G.getw(u, v)){
d.put(v, d.get(u) + G.getw(u, v));
v.setValue(d.get(u) + G.getw(u, v));
pq.add(v);
}
}
}
for(Vex vv : d.keySet()){
System.out.println(vv.getName() + " " + vv.getValue());
}
return null;
}
public static void main(String args[]) throws IOException{
Graph g = Graph.CreateFromFile("C:/tmp/test.txt");
DijkstraSeq dijk = new DijkstraSeq();
dijk.MST(g, new Vex("1"));
}
}