您的位置:首页 > 其它

图论算法-求(有向)图中任意两点间所有路径

2013-11-19 00:46 459 查看
图论算法-求(有向)图中任意两点间所有路径
 

求(有向)图中任意两点间所有路径

1建图:

     图类中包括如下信息:顶点集合,邻接矩阵。

     节点类中包括如下信息:是否被访问过,节点的名称,从这个节点访问到下一个节点的集合

 



 <!--[endif]-->

图1



 <!--[endif]-->

图2

 

2 算法思路

  A 将始点设置为已访问,将其入栈

  B 查看栈顶节点V在图中,有没有可以到达、且没有入栈、且没有从这个节点V出发访问过的节点

  C 如果有,则将找到的这个节点入栈

  D 如果没有,则将节点V访问到下一个节点的集合中每个元素赋值为零,V出栈

  E 当栈顶元素为终点时,设置终点没有被访问过,打印栈中元素,弹出栈顶节点

  F 重复执行B – E,直到栈中元素为空

 

 

package util;public class Graph {	private Vertex vertexList[]; // list of vertices	private int adjMat[][]; // adjacency matrix	private int nVerts;	private static int MAX_VERTS = 7; // n个点	int i = 0;	int j = 0;	public Vertex[] getVertexList() {		return vertexList;	}	public int[][] getAdjMat() {		return adjMat;	}	public int getN() {		return MAX_VERTS;	}	public Graph(int index) {		adjMat = new int[MAX_VERTS][MAX_VERTS]; // 邻接矩阵		vertexList = new Vertex[MAX_VERTS]; // 顶点数组		nVerts = 0;		for (i = 0; i < MAX_VERTS; i++) {			for (j = 0; j < MAX_VERTS; j++) {				adjMat[i][j] = 0;			}		}		addVertex('A');		addVertex('B');		addVertex('C');		addVertex('D');		addVertex('E');		addVertex('F');		addVertex('G');		addEdge(0, 1);		addEdge(0, 2);		addEdge(1, 4);		addEdge(2, 0);		addEdge(2, 5);		addEdge(3, 0);		addEdge(3, 2);		addEdge(3, 3);		addEdge(4, 1);		addEdge(4, 2);		addEdge(5, 6);		addEdge(6, 3);		switch (index) {		case 0:			break;		case 1:			delEdge(4, 2);			break;		default:			break;		}	}	private void delEdge(int start, int end) {		adjMat[start][end] = 0;	}	private void addEdge(int start, int end) {// 有向图,添加边		adjMat[start][end] = 1;		// adjMat[end][start] = 1;	}	public void addVertex(char lab) {		vertexList[nVerts++] = new Vertex(lab);// 添加点	}	public char displayVertex(int i) {		return vertexList[i].getLabel();	}	public boolean displayVertexVisited(int i) {		return vertexList[i].WasVisited();	}	public void printGraph() {		for (i = 0; i < MAX_VERTS; i++) {			System.out.print("第" + displayVertex(i) + "个节点:" + " ");			for (j = 0; j < MAX_VERTS; j++) {				System.out.print(displayVertex(i) + "-" + displayVertex(j)						+ ":" + adjMat[i][j] + " ");			}			System.out.println();		}	}}

 package util;

import java.util.ArrayList;public class Vertex {	boolean wasVisited; // 是否遍历过	public char label; // 节点名称	ArrayList<Integer> allVisitedList;// 节点已访问过的顶点	public void setAllVisitedList(ArrayList<Integer> allVisitedList) {		this.allVisitedList = allVisitedList;	}	public ArrayList<Integer> getAllVisitedList() {		return allVisitedList;	}	public boolean WasVisited() {		return wasVisited;	}	public void setWasVisited(boolean wasVisited) {		this.wasVisited = wasVisited;	}	public char getLabel() {		return label;	}	public void setLabel(char label) {		this.label = label;	}	public Vertex(char lab) // constructor	{		label = lab;		wasVisited = false;	}	public void setVisited(int j) {		allVisitedList.set(j, 1);	}}

 package util;

import java.util.ArrayList;import java.util.Stack;public class AF {	boolean isAF = true;	Graph graph;	int n;	int start, end;	Stack<Integer> theStack;	private ArrayList<Integer> tempList;	private String counterexample;	public AF(Graph graph, int start, int end) {		this.graph = graph;		this.start = start;		this.end = end;	}	public boolean getResult() {		graph.printGraph();		n = graph.getN();		theStack = new Stack<Integer>();		if (!isConnectable(start, end)) {			isAF = false;			counterexample = "节点之间没有通路";		} else {			for (int j = 0; j < n; j++) {				tempList = new ArrayList<Integer>();				for (int i = 0; i < n; i++) {					tempList.add(0);				}				graph.getVertexList()[j].setAllVisitedList(tempList);			}			isAF = af(start, end);		}		return isAF;	}	private boolean af(int start, int end) {		graph.getVertexList()[start].setWasVisited(true); // mark it		theStack.push(start); // push it		while (!theStack.isEmpty()) {			int v = getAdjUnvisitedVertex(theStack.peek());			if (v == -1) // if no such vertex,			{				tempList = new ArrayList<Integer>();				for (int j = 0; j < n; j++) {					tempList.add(0);				}				graph.getVertexList()[theStack.peek()]						.setAllVisitedList(tempList);// 把栈顶节点访问过的节点链表清空				theStack.pop();			} else // if it exists,			{				theStack.push(v); // push it			}			if (!theStack.isEmpty() && end == theStack.peek()) {				graph.getVertexList()[end].setWasVisited(false); // mark it				printTheStack(theStack);				System.out.println();				theStack.pop();			}		}		return isAF;	}	// 判断连个节点是否能连通	private boolean isConnectable(int start, int end) {		ArrayList<Integer> queue = new ArrayList<Integer>();		ArrayList<Integer> visited = new ArrayList<Integer>();		queue.add(start);		while (!queue.isEmpty()) {			for (int j = 0; j < n; j++) {				if (graph.getAdjMat()[start][j] == 1 && !visited.contains(j)) {					queue.add(j);				}			}			if (queue.contains(end)) {				return true;			} else {				visited.add(queue.get(0));				queue.remove(0);				if (!queue.isEmpty()) {					start = queue.get(0);				}			}		}		return false;	}	public String counterexample() {		for (Integer integer : theStack) {			counterexample += graph.displayVertex(integer);			if (integer != theStack.peek()) {				counterexample += "-->";			}		}		return counterexample;	}	// 与节点v相邻,并且这个节点没有被访问到,并且这个节点不在栈中	public int getAdjUnvisitedVertex(int v) {		ArrayList<Integer> arrayList = graph.getVertexList()[v]				.getAllVisitedList();		for (int j = 0; j < n; j++) {			if (graph.getAdjMat()[v][j] == 1 && arrayList.get(j) == 0					&& !theStack.contains(j)) {				graph.getVertexList()[v].setVisited(j);				return j;			}		}		return -1;	} // end getAdjUnvisitedVertex()	public void printTheStack(Stack<Integer> theStack2) {		for (Integer integer : theStack2) {			System.out.print(graph.displayVertex(integer));			if (integer != theStack2.peek()) {				System.out.print("-->");			}		}	}}

 import util.AF;

import util.Graph;public class Main {	public static void main(String[] args) {        //第几张图,有两张(0,1),起点序号(0-6),终点序号(0-6)		AF operation = new AF(new Graph(0), 3, 6);		operation.getResult();	}}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: