Java:寻找两点之间所有路径

问题描述:

见下图,要求寻找A至Z的所有路径。

已知:两点之间的直接路径。例如:A-->B B-->C B-->E。。。。

 

 

 

 

解:

定义一个基本路径模型,属性:起始点和结束点。A-->B可抽象成new Road("A",'B');

package alogrim;
public class Road implements Cloneable {
	public Road(String begin,String end) {
		this.begin = begin;
		this.end = end;
	}
	private String begin;
	private String end;
	public String toString() {
		return begin + "->" + end;
	}
	public String getBegin() {
		return begin;
	}
	public void setBegin(String begin) {
		this.begin = begin;
	}
	public String getEnd() {
		return end;
	}
	public void setEnd(String end) {
		this.end = end;
	}
	
	public boolean equals(Object obj) {
		Road r = (Road)obj;
		if(this.getBegin().equals(r.getBegin()) && this.getEnd().equals(r.getEnd())) {
			return true;
		}
		return false;
	}
	
	public Object clone() {
		try {
			return super.clone();
		} catch (CloneNotSupportedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
}

 核心算法分两步:

1 过滤掉无用的路径。例如上图:G-->B G-->F D-->F都属于无效路径。

第一步:获取无效开始节点和无效结束点

	/**
	 * 过滤掉无用的节点
	 * 获取到无效开始节点和无效结束点
	 * @param all 所有节点
	 * @return
	 */
	public Set<String> filterInvalidNode(Set<String> all, List<Road> roads,
			Set<String> begins, Set<String> ends) {
		Set<String> result = new HashSet<String>();
		boolean isBegin = true;
		boolean isEnd = true;
		for (String str : all) {
			if (!existEnd(str, roads)) { // 没有以此节点结尾的路径,则证明此节点为无用节点
				isBegin = false;
				begins.add(str);
				// 删除以此节点为开始的路径
				// this.deleteBegin(str, roads);
			} else if (!existBegin(str, roads)) {// 没有以此节点开头的路径,则证明此节点为无用节点
				isEnd = false;
				ends.add(str);
				// this.deleteEnd(str, roads);
			} else {
				result.add(str); // 有用的节点
			}
		}
		if (isBegin == true && isEnd == true) {
			return result;
		} else {
			return filterInvalidNode(result, roads, begins, ends);
		}
	}

 第二步:删除无效路径

	/**
	 * 获取到需要删除的路径
	 * 
	 * @param begins
	 * ---无效起始节点
	 * @param ends
	 * ---无效终结点
	 * @param roads
	 */
	public Set<Road> deleteRoad(Set<String> begins, Set<String> ends,
			List<Road> roads) {
		Set<Road> set = new HashSet<Road>();
		for (String str : begins) {
			for (Road r : roads) {
				if (r.getBegin().equals(str)) {
					set.add(r);
				}
				if (r.getEnd().equals(str)) {
					set.add(r);
				}
			}
		}
		return set;
	}

 2 路径遍历,确保找到两点之间的所有可通过路径,需要确保每条基本路径都被访问过。本算法采用自上而下遍历方式。详细含义如下:

List<Road> roadList = null; //已知的路径
	List<String> backList = new ArrayList<String>(); //存放已经访问过的节点
	Set<String> resultSet = new HashSet<String>(); //目的路径--访问结果
	Set<Road> cirList = new HashSet<Road>(); 	//回路
	
	/**
	 * 路径遍历的核心算法
	 * @param start
	 * ---需要寻找的起始节点。本案例为A
	 * @param destination
	 * ---需要寻找的终结点。本案例为Z
	 */
	public void getAllRoad(String start, String destination) {
		backList.add(start);
		for (int z = 0; z < roadList.size(); z++) {
			if (roadList.get(z).getBegin().equals(start)) { //寻找找以start开始的路径
				if (roadList.get(z).getEnd().equals(destination)) { //如果以destination结尾,则为一条有效路径
					resultSet.add(backList.toString().substring(0, backList.toString().lastIndexOf("]")) + "," + destination + "]");
					continue;
				}
				if (!backList.contains(roadList.get(z).getEnd())) {//此节点仍未遍历,则继续迭代
					getAllRoad(roadList.get(z).getEnd(), destination);
				} else {//證明有回路
					cirList.add(roadList.get(z));
					//System.out.println("wwww");
				}
			}
		}
		backList.remove(start);
	}

 

至此已经完成‘两点之间所有路径’的核心算法。详细代码见附件,main方法在MapVisit里

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值