限制:
1. 权值为正
2. 无向
算法思想:
1. 三个结构:open集合,closed集合,dist和ps。open保存还没有被的处理节点,closed保存已经处理的节点,dist保持各个节点到目标节点的最短距离,ps保持所有的边。
初始:只有目标节点到目标节点的距离是0,其余是无穷大。
2. 从open集合里面找到距离最短的节点v,放到closed
3. 找到这个节点v的所有到邻居的邻接边,并且从ps去掉这些边
4. 根据这些邻接边,更新dist。更新方法是:如果通过v到达邻居n的距离更短,则更新邻居n的距离为:dist[n]=dist[v]+p(v,n).cost
5. 重复2-4步,直到open集合为空
public class SFP {
private class Path{
int n1;
int n2;
int cost;
public Path(int n1, int n2, int cost){
this.n1 = n1;
this.n2 = n2;
this.cost = cost;
}
}
private Path[] paths={new Path(1,2,6),
new Path(1,3,3),
new Path(2,3,2),
new Path(2,4,5),
new Path(3,4,3),
new Path(3,5,4),
new Path(4,5,2),
new Path(4,6,3),
new Path(5,6,5),
};
int findMinDistNode(Map<Integer,Path> dist, Set<Integer> open){
int nid=Integer.MAX_VALUE;
int cost=Integer.MAX_VALUE;
for(Integer i:open){
if(cost>dist.get(i).cost){
nid = i;
cost = dist.get(nid).cost;
}
}
return nid;
}
void start(){
int start=1; //start point
Set<Path> ps = new HashSet<>();
Set<Path> nb = new HashSet<>();
Set<Integer> closed = new HashSet<Integer>();
Set<Integer> open = new HashSet<Integer>(); //
Map<Integer,Path> dist = new HashMap<Integer,Path>();
for(int i=0;i<paths.length;i++){
dist.put(paths[i].n1,null);
dist.put(paths[i].n2,null);
ps.add(paths[i]);
}
for(Map.Entry<Integer, Path> d:dist.entrySet()){
d.setValue(new Path(Integer.MAX_VALUE,Integer.MAX_VALUE,Integer.MAX_VALUE));
open.add(d.getKey());
}
dist.get(start).cost = 0;
while(!open.isEmpty()){
int v = findMinDistNode(dist, open);
nb.clear();
open.remove(v);
closed.add(v);
//find all paths to v's neighbor, and remove the paths from ps
Iterator<Path> iter = ps.iterator();
for(int i=0;i<ps.size();i++){
Path p=iter.next();
if(p.n1==v || p.n2==v){
iter.remove();
nb.add(p);
i--;
}
}
//recaculate dist
for(Path p:nb){
int nn=p.n1;
if(nn==v) nn=p.n2;
int cost = p.cost+dist.get(v).cost;
if(cost < dist.get(nn).cost){
dist.get(nn).cost = cost;
dist.get(nn).n1 = v;
}
}//for
}//while
//print
for(Map.Entry<Integer, Path> d:dist.entrySet()){
System.out.println(String.format("node=%d last=%d spf=%d",d.getKey(),d.getValue().n1,d.getValue().cost));
}
}
public static void main(String args[]){
SFP sfp=new SFP();
sfp.start();
}
}