一、有向线段,存储开始点与结束点

/**
* 有方向的线段
*
* @author Gm
*
*/
public class DirectionLine implements Cloneable { private String beginNode;
private String endNode; public DirectionLine(String beginNode, String endNode) {
this.beginNode = beginNode;
this.endNode = endNode;
} public String toString() {
return beginNode + "->" + endNode;
} public String getBeginNode() {
return beginNode;
} public void setBeginNode(String beginNode) {
this.beginNode = beginNode;
} public String getEndNode() {
return endNode;
} public void setEndNode(String endNode) {
this.endNode = endNode;
} public boolean equals(Object obj) {
DirectionLine dl = (DirectionLine) obj;
if (this.getBeginNode().equals(dl.getBeginNode()) && this.getEndNode().equals(dl.getEndNode())) {
return true;
}
return false;
} public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return null;
}
}

三、过滤无效节点

public class Graph {

	List<DirectionLine> directionLines = null; // 已知的路径(有向线,包含:开始点、结束点)
List<String> visitedList = new ArrayList<String>(); // 存放已经访问过点的节点
Set<String> resultSet = new HashSet<String>(); // 目的访问路径(点的集合)
Set<DirectionLine> loopList = new HashSet<DirectionLine>(); // 已知的回路(有向线,包含:开始点、结束点) public Graph(List<DirectionLine> directionLines) {
this.directionLines = directionLines;
} public List<DirectionLine> getDirectionLines() {
return directionLines;
} public void setDirectionLines(List<DirectionLine> directionLines) {
this.directionLines = directionLines;
} public List<String> getVisitedList() {
return visitedList;
} public void setVisitedList(List<String> visitedList) {
this.visitedList = visitedList;
} public Set<String> getResultSet() {
return resultSet;
} public void setResultSet(Set<String> resultSet) {
this.resultSet = resultSet;
} public Set<DirectionLine> getLoopList() {
return loopList;
} public void setLoopList(Set<DirectionLine> loopList) {
this.loopList = loopList;
} /**
* 路径遍历的核心算法
*
* @param startNode
* @param endNode
*/
public void getAllPaths(String startNode, String endNode) {
visitedList.add(startNode);
// System.out.println("访问的起点->终点:" + startNode + "->" + endNode);
for (int z = 0; z < directionLines.size(); z++) {
// System.out.println("遍历次数:" + z + ",路径:" + directionLines.get(z).toString());
if (directionLines.get(z).getBeginNode().equals(startNode)) { // 寻找找以startNode开始的路径
if (directionLines.get(z).getEndNode().equals(endNode)) { // 如果以endNode结尾,则为一条有效路径
resultSet.add(visitedList.toString().substring(0, visitedList.toString().lastIndexOf("]")) + "," + endNode + "]");
continue;
}
// System.out.println("已访问过的节点:" + visitedList.toString());
if (!visitedList.contains(directionLines.get(z).getEndNode())) {// 此节点仍未遍历,则继续迭代
getAllPaths(directionLines.get(z).getEndNode(), endNode);
} else {// 证明存在回路
loopList.add(directionLines.get(z));
}
}
}
visitedList.remove(startNode);
}
}
public class MapVisit {
/**
* 构造初始化路径--已知
*
*/
public List<DirectionLine> init() {
List<DirectionLine> directionLines = new ArrayList<DirectionLine>();
String str = CommonUtil.readToString("room_layout2.json");
JSONObject jsonObject = JSONObject.parseObject(str);
for (Entry<String, Object> entry : jsonObject.entrySet()) {
String startNode = "node" + entry.getKey();
JSONObject child_nodes = JSONObject.parseObject(entry.getValue().toString());
for (Entry<String, Object> child_entry : child_nodes.entrySet()) {
String endNode = "node" + child_entry.getKey();
// System.out.println(startNode + ":" + endNode);
directionLines.add(new DirectionLine(startNode, endNode));
}
}
return directionLines;
} /**
* 判断所有路径中是否有以beginNode节点为起点的基本路径
*
* @param beginNode
* @param directionLines
* @return
*/
public boolean existBeginNode(String beginNode, List<DirectionLine> directionLines) {
boolean result = false;
for (DirectionLine dl : directionLines) {
if (dl.getBeginNode().equals(beginNode)) {
result = true;
break;
}
}
return result;
} /**
* 判断所有路径中是否有以end节点为终点的基本路径
*
* @param endNode
* @param directionLines
* @return
*/
public boolean existEndNode(String endNode, List<DirectionLine> directionLines) {
boolean result = false;
for (DirectionLine dl : directionLines) {
if (dl.getEndNode().equals(endNode)) {
result = true;
break;
}
}
return result;
} /**
* 根据路径获取到所有的节点
*
* @param directionLines
* @return
*/
public Set<String> getAllNodes(List<DirectionLine> directionLines) {
Set<String> nodes = new HashSet<String>();
for (DirectionLine r : directionLines) {
nodes.add(r.getBeginNode());
nodes.add(r.getEndNode());
}
return nodes;
} /**
* 获取到需要删除的路径
*
* @param beginNodes
* 无效起始节点
* @param endNodes
* 无效终结点
* @param directionLines
*/
public Set<DirectionLine> deleteDirectionLines(Set<String> beginNodes, Set<String> endNodes, List<DirectionLine> directionLines) {
Set<DirectionLine> set = new HashSet<DirectionLine>();
for (String str : beginNodes) {
for (DirectionLine dl : directionLines) {
if (dl.getBeginNode().equals(str)) {
set.add(dl);
}
if (dl.getBeginNode().equals(str)) {
set.add(dl);
}
}
}
return set;
} /**
* 过滤掉无用的节点 获取到无效开始节点和无效结束点
*
* @param all
* @param directionLines
* @param beginNodes
* @param endNodes
* @return
*/
public Set<String> filterInvalidNode(Set<String> allNodes, List<DirectionLine> directionLines, Set<String> beginNodes, Set<String> endNodes) {
Set<String> result = new HashSet<String>();
boolean isBegin = true;
boolean isEnd = true;
for (String node : allNodes) {
if (!existEndNode(node, directionLines)) { // 没有以此节点结尾的路径,则证明此节点为无用节点
isBegin = false;
beginNodes.add(node);
} else if (!existBeginNode(node, directionLines)) {// 没有以此节点开头的路径,则证明此节点为无用节点
isEnd = false;
endNodes.add(node);
} else {
result.add(node); // 有用的节点
}
}
if (isBegin == true && isEnd == true) {
return result;
} else {
return filterInvalidNode(result, directionLines, beginNodes, endNodes);
}
} /**
* @param args
*/
public static void main(String[] args) {
MapVisit visit = new MapVisit();
List<DirectionLine> directionLines = visit.init();
// 构造基本路径--为已知条件
Set<String> invalidBeginNodes = new HashSet<String>(); // 无效的起始节点
Set<String> invalidEndNodes = new HashSet<String>(); // 无效的结束节点
Set<String> allNodes = visit.getAllNodes(directionLines);
visit.filterInvalidNode(allNodes, directionLines, invalidBeginNodes, invalidEndNodes); // 获取到无效开始节点和无效结束点
Set<DirectionLine> invalidRoads = visit.deleteDirectionLines(invalidBeginNodes, invalidEndNodes, directionLines); // 获取需要删除的路径
directionLines.removeAll(invalidRoads); // 删除无效的路径 // System.out.println(directionLines.toString()); Graph pra = new Graph(directionLines);
String begin = "node12"; // 起始点
String end = "node1"; // 终结点
// 获取所有有效路径
pra.getAllPaths(begin, end); Iterator<String> it = pra.getResultSet().iterator();
System.out.println("-----------------从" + begin + "至" + end + "的有效路径如下-----------------");
while (it.hasNext()) {
System.out.println(it.next());
}
}
}

四、数据集

{"1":{"2":1},"2":{"1":1,"3":1,"19":1},"3":{"2":1,"4":1,"9":1},"4":{"3":1,"5":1},"5":{"4":1},"6":{"9":1},"7":{"10":1},"8":{"11":1},"9":{"3":1,"6":1,"10":1},"10":{"7":1,"9":1,"11":1,"12":1},"11":{"8":1,"10":1},"12":{"10":1,"13":1,"17":1},"13":{"12":1,"14":1,"15":1},"14":{"13":1,"16":1},"15":{"13":1},"16":{"14":1},"17":{"12":1,"18":1},"18":{"17":1,"19":1,"20":1},"19":{"2":1,"18":1},"20":{"18":1}}

五、效果展示

-----------------从node12至node1的有效路径如下-----------------

[node12, node17, node18, node19, node2,node1]

[node12, node10, node9, node3, node2,node1]

Java 计算两点间的全部路径(二)的更多相关文章

  1. Java 计算两点间的全部路径(一)

    算法要求: 在一个无向连通图中求出两个给定点之间的所有路径: 在所得路径上不能含有环路或重复的点: 算法思想描述: 整理节点间的关系,为每个节点建立一个集合,该集合中保存所有与该节点直接相连的节点(不 ...

  2. HDOJ2001计算两点间的距离

    计算两点间的距离 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Su ...

  3. hdu2001 计算两点间的距离【C++】

    计算两点间的距离 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Su ...

  4. 计算两点间的距离,hdu-2001

    计算两点间的距离 Problem Description 输入两点坐标(X1,Y1),(X2,Y2),计算并输出两点间的距离.   Input 输入数据有多组,每组占一行,由4个实数组成,分别表示x1 ...

  5. TSQL 根据经纬度计算两点间的距离;返回米(m)

    -- ============================================= -- Author:Forrest -- Create date: 2013-07-16 -- Des ...

  6. 转:Math: Math.atan() 与 Math.atan2() 计算两点间连线的夹角

    我们可以使用正切操作将角度转变为斜率,那么怎样利用斜率来转换为角度呢?可以利用斜率的反正切函数将他转换为相应的角度.as中有两个函数可以计算反正切,我们来看一下. 1.Math.atan() Math ...

  7. 经纬度计算两点间的距离,根据距离排序SQL

    #java的Utilspublic class DistanceUtil { // 地球平均半径 private static final double EARTH_RADIUS = 6378137; ...

  8. J - 计算两点间的距离

      Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u   Description 输入两 ...

  9. 计算两点间的距离-hdu2001

    Problem Description 输入两点坐标(X1,Y1),(X2,Y2),计算并输出两点间的距离.   Input 输入数据有多组,每组占一行,由4个实数组成,分别表示x1,y1,x2,y2 ...

随机推荐

  1. 自定义一个数组对象工具demo

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  2. 发布nuget包

    首先在nuget(www.nuget.org)注册账号,这里可以使用微软账号直接登录 一般有两种方式 1:在工程上右键打包然后直接在网站上上传就可以 2:通过获取key,然后使用控制台提交 登录后在右 ...

  3. 提升键盘可访问性和AT可访问性

    概述 很多地方比如官网中需要提升 html 的可访问性,我参考 element-ui,总结了一套提升可访问性的方案,记录下来,供以后开发时参考,相信对其他人也有用. 可访问性 可访问性基本上分为 2 ...

  4. oracle 查看表空间使用比

    select b.file_name 物理文件名, b.tablespace_name 表空间, b.bytes / / 大小M, (b.bytes - sum(nvl(a.bytes, ))) / ...

  5. net.sf.json.JSONObject处理 "null" 字符串的一些坑

    转: net.sf.json.JSONObject处理 "null" 字符串的一些坑 2018年05月02日 16:41:25 大白能 阅读数:7026   版权声明:本文为博主原 ...

  6. git备份代码

    仓库备份位置: /huawei-bak vim /huawei-bak/huawei-bak.sh #!/bin/bash#项目克隆下来后将其注释即可PROJECT="git@codehub ...

  7. 小D课堂 - 新版本微服务springcloud+Docker教程_1_01课程简介

    笔记 ============================================= SpringCloud课程笔记.txt 第一章 课程介绍和学习路线 1.微服务架构SpringClou ...

  8. 运行python manage.py 出现mportError: No module named django.core.management when using manage.py

    1 . linux下用virtualenv 创建虚拟空间环境没有安装djang,即使主机装了,否则运行python manage.py 出现mportError: No module named dj ...

  9. 【HANA系列】SAP HANA SQL条件判断是NULL的写法

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[HANA系列]SAP HANA SQL条件判断 ...

  10. C#编程 socket编程之unity聊天室

    上面我们创建了tcp的客户端和服务端,但是只能进行消息的一次收发.这次我们做一个unity的简易聊天室,使用了线程,可以使用多个客户端连接服务器,并且一个客户端给服务器发消息后,服务器会将消息群发给所 ...