首页 > 代码库 > 经典图算法Java代码实践:BFS,DFS以及几种最短路径算法

经典图算法Java代码实践:BFS,DFS以及几种最短路径算法



public class City 
{
	String name; 
	int id;
	static int idCounter = 0;
	public City(String name) 
	{
		this.name=name;
		id = idCounter++;
	}
}



import java.util.ArrayList;


public class Graph {

	public static void main(String[] args)
	{
		// TODO Auto-generated method stub
		Map M = new Map(12);
		City a = new City("a");
		City b = new City("b");
		City c = new City("c");
		City d = new City("d");
		City e = new City("e");
		City f = new City("f");
		City g = new City("g");
		City h = new City("h");
		City i = new City("i");
		City j = new City("j");
		City k = new City("k");
		City l = new City("l");
		
		M.createEdge(a,b,3);
		M.createEdge(a,c,5);
		M.createEdge(a,d,4);
		
		M.createEdge(b,f,6);
		
		M.createEdge(c,d,2);
		M.createEdge(c,g,4);
		
		M.createEdge(d,e,1);
		M.createEdge(d,h,5);
		
		M.createEdge(e,f,2);
		M.createEdge(e,i,4);
		
		M.createEdge(f,j,5);
		
		M.createEdge(g,h,3);
		M.createEdge(g,k,6);
		
		M.createEdge(h,i,6);
		M.createEdge(h,k,7);
		
		M.createEdge(i,j,3);
		M.createEdge(i,l,5);
		
		M.createEdge(j,l,9);
		
		M.createEdge(k,l,8);
		
		System.out.println("the graph is:\n");
		System.out.println(M);
		
	
		System.out.println();
		System.out.println("findPathByDFS:a to k");
		M.findPathByDFS(a,k);
		
		System.out.println();
		System.out.println("findPathByBFS:a to k");
		M.findPathByBFS(a,k);
		
		System.out.println();
		System.out.println("bellmanFord from a:");
		M.bellmanFord(a);
		
		System.out.println();
		System.out.println("dijkstra from a:");
		M.dijkstra(a);
		
		System.out.println();
		System.out.println("bellmanFord,print example from a:");
		M.floydWarshall();
		M.printFloydWarshallForOneCity(a);
	}

}



import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;




public class Map 
{
	double[][] A;
	public Map(int n)
	{
		A = new double[n][n];
	     for(int i = 0;i < A.length;i++)
	     {
	           for(int j = 0;j < A.length;j++)
	           {
	        	   if(i == j) A[i][j] = 0;
	        	   else A[i][j] = -1;
	           }
	     }
		
	}
	ArrayList<City> cities = new ArrayList<City>();
	
	private double[] D;
	private void relax(int u,int v)
	{
        if(D[v]>D[u]+A[v][u])  
        	D[v]=D[u]+A[v][u];
	}
	
	private double[][] DD = null;
	public void floydWarshall()
	{
		 DD = new double[A.length][A.length];
	     int i,j,k;
	     for(i = 0;i < A.length;i++)
	     {
	           for(j = 0;j < A.length;j++)
	           {
	        	   if(A[i][j]>0)
	                 DD[i][j] = A[i][j];
	        	   else if(i == j)  DD[i][j] = 0;
	        	   else DD[i][j] = 99999999;

	           }
	     }
	     for(k = 0;k < A.length;k++)
	     for(i = 0;i < A.length;i++)
	     for(j = 0;j < A.length;j++)
	     {
	      if(DD[i][j] > DD[i][k] + DD[k][j])
	      {
	          DD[i][j] = DD[i][k] + DD[k][j]; 
	      }
	     }
	}
	
	public void printFloydWarshallForOneCity(City city)
	{
		System.out.println("floydWarshall:");
		if(DD == null)
		{
			floydWarshall();
		}
		for(int i=0;i<A.length;i++)
		{
			System.out.printf("from %s to %s shortest path is:%f\n",city.name,cities.get(i).name,DD[city.id][i]);
		}
		
	}
	
	public void dijkstra(City city)
	{
		dijkstra(city.id);
		System.out.println("dijkstra:");
		for(int i=0;i<A.length;i++)
		{
			System.out.printf("from %s to %s shortest path is:%f\n", city.name,cities.get(i).name,D[i]);
		}
	}
	
	public void dijkstra(int  srcId)
	{
		D = new double[A.length];
        for(int i=0;i<A.length;i++)   
	    {
        	D[i]=999999999;    	
        }
        D[srcId]=0;
        int[] q = new int[A.length];
        int ql=0,qf=0; //队列
        
        for(int i=0;i<A.length;i++) q[ql++]=i;
        while(qf!=ql)
        {
               int min=qf;
               for(int i=qf;i<ql;i++) 
               {
            	   if(D[q[i]]<D[q[min]]) 
            	   {
            		   min=i;
            	   }
               }         
               int id = q[qf];
               q[qf] = q[min];
               q[min] = id; //q[qf] is the min
               int u=q[qf++];
               for(int i=0;i<A.length;i++)
               {
                  if(A[u][i]>0) 
                  {
                	  relax(u,i);
                  }
               }
        }
	}
	
	public void bellmanFord(City city)
	{
		bellmanFord(city.id);
		System.out.println("bellmanFord:");
		for(int i=0;i<A.length;i++)
		{
			System.out.printf("from %s to %s shortest path is:%f\n", city.name,cities.get(i).name,D[i]);
		}
	}
	

	public void bellmanFord(int srcId)
	{
		D = new double[A.length];
		for(int i=0;i<A.length;i++)
		{
			D[i] = 99999999;//无穷大
		}
		D[srcId] = 0;
		for(int i=0;i<A.length;i++)//外层循环次数
		{
			for(int j=0;j<A.length;j++)
			{
				for(int k=0;k<A.length;k++)
				{
					if(A[j][k]>0)
					{
						relax(j,k);
					}
				}
			}
			
		}
	}
	
	
	Queue<Integer> bfsQueue = new LinkedList<Integer>();
	boolean[] bfsFlag;
	int bsfPre[];
	public void findPathByBFS(City src,City dst)
	{
		System.out.printf("bfs find path between '%s' and '%s'!\n",src.name,dst.name);
		findPathByBFS( src.id, dst.id);
		printBFS(dst.id);
		
	}
	public void findPathByBFS(int srcId,int dstId)
	{
		bsfPre = new int[A.length];
		bfsQueue.clear();
		bfsFlag = new boolean[A.length];
		for(int i=0;i<A.length;i++)
		{
			bfsFlag[i] = false;
			bsfPre[i] = -1;
		}
		

		bfsQueue.offer(srcId);
		bfsFlag[srcId] = true;
		
		while(!bfsQueue.isEmpty())
		{
			int current = bfsQueue.poll();
			for(int index=0;index<A.length;index++)
			{
				if(current == index) continue;
				if(A[current][index]>0) //两者相连
				{
					if(index == dstId)//找到目标了
					{
						bfsFlag[index] = true;
						bsfPre[index] = current;
						return;//直接返回
					}
					if(bfsFlag[index] == false)//如果未访问过
					{
						bfsFlag[index] = true;
						bsfPre[index] = current;
						bfsQueue.offer(index);
					}
				}
				
			}
		}
		
	
		

		
	}
	
	private void printBFS(int dstId)
	{
		int index = dstId;
		
		do
		{
			System.out.printf("<-%s", cities.get(index).name);
			index = bsfPre[index];
		}while(index != -1);
		System.out.println();
	}
	
	ArrayList<Integer> dfsPath = new ArrayList<Integer>();
	boolean[] dfsFlag;
	private void printDFS()
	{
		for(Integer node:dfsPath)
		{
			System.out.printf("->%s", cities.get(node).name);
		}
		System.out.println();
	}
	public void findPathByDFS(City src,City dst)
	{
		System.out.printf("dfs find path between '%s' and '%s'!\n",src.name,dst.name);
		findPathByDFS(src.id, dst.id);
	}
	public void findPathByDFS(int srcId,int dstId)
	{
		dfsPath.clear();
		dfsFlag = new boolean[A.length];
		for(int i=0;i<A.length;i++)
		{
			dfsFlag[i] = false;
		}
		dfsPath.add(srcId);
		dfsFlag[srcId] = true;
		dfs( srcId, dstId);
		printDFS();
	}
	private void dfs(int srcId,int dstId)
	{
		for(int index=0;index<A[srcId].length;index++)
		{
			if(srcId == index) continue;
			if(A[srcId][index]>0)//两者连接
			{
				if(index == dstId)//找到目标了
				{
					dfsFlag[index] = true;
					dfsPath.add(index);
					return;
				}
				if(dfsFlag[index] == false)//如果该节点未访问过
				{
					dfsFlag[index] = true;
					dfsPath.add(index);
					dfs(index,dstId);
					if(dfsFlag[dstId] == false)//目标没找到
						dfsPath.remove(index);
					else return;
				}
				
			}
		}
	}
	
	public void createEdge(City a, City b, double w) 
	{
		A[a.id][b.id]=w;
		A[b.id][a.id]=w;//added by me!
		cities.add(a.id,a);
		cities.add(b.id,b);
	}
	
	public String toString()
	{
		String r = "I am a map of " + A.length + " cities."; 
		r += " My connections are:\n";
		for (int i=0;i<A.length;i++) 
		{
			for (int j=0;j<A[0].length;j++)
				r+=A[i][j]+"\t";
			r+="\n";
		}
		return r;
	}
}