人员定位轨迹之递归算法

这篇微博是2018-9-28日写的,当时虽然实现递归,但是有许多缺陷,可以说很烂;
前言:
每个算法都有它的优势和缺点,我的这个算法的缺点就是不适用路线复杂的!
现在是2018-10-03日,我终于把这个递归算法实现了;于是把之前的博客内容删了;免得误人子弟。
项目名称:矿山定位系统之人员运动轨迹的绘制;
第一步:有基站的图纸显示在jsp页面
1.DWG图纸在jsp页面显示
2.利用position=absolute,将一个透明的div(和图纸大小)放在图纸上显示的部位;
3.用屏幕取点法绘制基站的位置,再利用java的Graphic绘制直线
我做的效果如下:
人员定位轨迹之递归算法_第1张图片
第二步:
把实际相邻基站的路线绘制出来;

我说的是实际情况,例如,这里的基站20相邻基站是基站12、基站21和基站17、基站22、基站24,;
在基站20那里有一个分叉口,是基站12和基站21,基站21要想到基站12必须经过基站20;所以基站21不能直接到达基站12,他们不是相邻的基站;
你要搞清楚这些基站实际的关系,基站和基站是不是相邻的,是不是可以直接到达的;
第三步:
递归算法运用的背景:
**在理想情况下,**每个矿工经过基站时,基站都会把手卡数据发送到程序上;这样的话,我们第二步绘制的相邻基站之间的路线就可以了;
但是实际情况是下井时30多个人同时进入,一个基站不能同时与多个手卡相连,耗时,数据丢失,会导致,某个人明明从基站20过来,但是数据库里采集的数据,没有基站20,路线就不是通顺的;
从基站30到基站20,理想路线时30-22-20,只有这样才能绘制出运动轨迹,但是如果数据库只采集到了30-20,那么我们就需要寻找30-20的可能路线;这是简单的;
如果是基站22-基站27呢?路线有千万种,起点不一样,终点不一样,如果靠一步步的分类,绘制路线,浪费时间,而且如果增加基站和减少基站的话,修改的路线更是繁杂,不利于后期维护;
我在负责矿山定位系统的时候就遇到了这个问题。历时7天终于解决了;
算法的前提是,相邻基站之间的路线准确,基站坐标正确;
实验步骤:
我的实验的基站范围是基站30、基站22、基站20、基站12、基站21和基站15
基站30相邻的基站是:基站22
基站22相邻的基站是:基站20、基站30
基站20的相邻基站是:基站12、基站21和基站22
基站12的相邻基站是:基站20
基站21的相邻基站是:基站15、基站20
基站15的相邻基站是:基站21
人员定位轨迹之递归算法_第2张图片
思路:
1、根据条件(某个时间段,某人)在数据库里查询出经过的基站,把基站放在一个list集合里面
当然前期可以自己给定list集合数据,因为查询数据库步骤麻烦;
2、取第一个基站和第二个基站,是否存在第一个基站直达第二个基站,如果存在,路线就是第一个基站到第二个基站;
如果不能直达,就寻找以第一个基站为起点的相邻基站的路线集合,循环这个集合里面的数据;
假设集合里面的数据是(第一基站,相邻基站);
判断这个相邻基站能否直达第二个基站,能的话,路线图是第一基站-相邻基站-第二基站;
如果不能,再获取这个相邻基站下面的与之相邻基站的路线集合,循环遍历这个新的路线集合, 判断这个新的路线集合的(相邻基站,相邻基站1),这个相邻基站1不能与第一基站一样,不然就会陷入死循环;
图示如下:
人员定位轨迹之递归算法_第3张图片
第一个基站是30,第二个基站是15
首先在相邻基站路线图的方法里面判断是否存在基站30直达基站15;存在的话,路线图就是基站30-基站15;
不存在的话;获取30为起点的所有相邻路线的集合(30-22)
循环遍历这个集合,把判断22是否能直达基站15,能的话,路线图就是基站30-基站22-基站15.
不存在的话,就获取以基站22为起点的所有相邻路线的集合(22-30、22-20)
循环遍历这个新的集合,这里有一个判断,判断22下面和上面是否一样,30遍历到了22,如果22再遍历30,整个程序就会陷入死循环,堆栈溢出;
整个递归的过程就是判断,获取集合,遍历集合,判断集合里的元素是否能直达第二基站,再获取集合,遍历集合…
但是注意的是递归的时候,基站,路线层层添加进去;

package cn.com.day01;

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
import cn.com.project.Point;
import cn.com.project.Route;
public class WW {
	public static List point = new ArrayList();
	public static Point pp;
	public static Point pa;
	public static List ll = new ArrayList();// 最终的路线轨迹
	public static List list = new ArrayList();
	public static int m=0;
	public static void main(String[] args) {
		// 1.模拟一个数据库,目的是不用老是重启tomcat,假设数据库里存储了30,20号基站,不相邻的
		list.add("015");
		list.add("012");
		// 2.筛选出运动轨迹出来
		BufferedImage bi = new BufferedImage(500, 500,
				BufferedImage.TYPE_INT_BGR);
		Graphics2D gh = bi.createGraphics();
		int sa = 0;
		int sb = 0;
		int ea = 0;
		int eb = 0;
		int sz[] = null;
		int zz[] = null;
		for (int j = 0; j < list.size() - 1; j++) {
			sz = case1(list.get(j), sa, sb);// #30的x y左边
			zz = case1(list.get(j + 1), ea, eb);// #20的x y左边
			List result= drawline(gh, sz[0], sz[1], zz[0], zz[1]);
	        List lr=RouteLine(sz[0],sz[1]);
			if (result.get(0) != null) {
				// 第一次寻找中介集合
				// 查看添加的元素是不是最后一位
				pp = new Point(sz[0], sz[1]);
				point.add(pp);
				pp = new Point(zz[0], zz[1]);
				point.add(pp);
				for (int i = 0; i < point.size() - 1; i++) {
					Route re = new Route(point.get(i).getX(), point.get(i)
							.getY(), point.get(i + 1).getX(), point.get(i + 1)
							.getY());
					ll.add(re);
				}
			} else {
				pp = new Point(sz[0], sz[1]);
				Route rrs=null;
				Plan(gh, sz, zz,lr,rrs,pp,pa);
			}

		}
		for (Route rr2 : ll) {
			System.out.println(rr2.getStarta() + ":" + rr2.getEnda() + ":"
					+ rr2.getStartb() + ":" + rr2.getEndb());
		}
		
		
	}

	// 递归函数

	public static void  Plan(Graphics gh, int sz[], int zz[],List lr,Route rrs,Point pd,Point pa) {
		// 把每一个要经过的点都放在一个集合里
		//不把初始值放两次进去
		int sa0=0;
		int sb0=0;
		m++;
		if(m==1){
			sa0=0;
			sb0=0;
		}
		Point p0=null;
		for (Route rr : lr) {	//#22 #12 #21
			if(rrs!=null){
				sa0 = rrs.getStarta();//72
				sb0 = rrs.getEnda();//281
				p0= new Point(rrs.getStartb(), rrs.getEndb());
			}
			sz[0] = rr.getStartb();//72#22
			sz[1] = rr.getEndb();//281
			if (sz[0] != sa0 || sz[1] != sb0) {
			List result0=drawline(gh, sz[0], sz[1], zz[0], zz[1]);
			List lrr=RouteLine(sz[0],sz[1]);
			if (result0.get(0) != null) {
				// 第一次寻找中介集合
				// 查看添加的元素是不是最后一位
				if(rrs!=null){
					point.add(pa);
				}
				point.add(pd);
				if(rrs!=null){
					point.add(p0);
				}
				pp = new Point(sz[0], sz[1]);
				point.add(pp);
				pp = new Point(zz[0], zz[1]);
				point.add(pp);
				for (int i = 0; i < point.size() - 1; i++) {
					Route re = new Route(point.get(i).getX(), point.get(i)
							.getY(), point.get(i + 1).getX(), point.get(i + 1)
							.getY());
					ll.add(re);
				} // for结束
				// 1.由于集合无论是否添加一个数组,大小都是1,所以需要判断第一个是不是空的就可以了
				return ;
				
			} // if
			else {
			for (Route rr2 : lrr) {
				Point p1 = new Point(rr.getStartb(), rr.getEndb());
				int sa1 = rr.getStarta();//337
				int sb1 = rr.getEnda();	//	281	
					sz[0] = rr2.getStartb();//71
					sz[1] = rr2.getEndb();//96
					if (sz[0] != sa1 || sz[1] != sb1) {						
						List l3 = drawline(gh, sz[0], sz[1], zz[0], zz[1]);
						List lrr1 =RouteLine(sz[0],sz[1]);
						if (l3.get(0) != null) {
							// 第一次寻找中介集合
							// 查看添加的元素是不是最后一位
							if(rrs!=null){
								point.add(pa);
							}
							point.add(pd);
							point.add(p1);
							pp = new Point(sz[0], sz[1]);
							point.add(pp);
							pp = new Point(zz[0], zz[1]);
							point.add(pp);
							for (int i = 0; i < point.size() - 1; i++) {
								Route re = new Route(point.get(i).getX(), point
										.get(i).getY(),
										point.get(i + 1).getX(), point.get(
												i + 1).getY());
								ll.add(re);
							}
							// 1.由于集合无论是否添加一个数组,大小都是1,所以需要判断第一个是不是空的就可以了
							return ;
						} // if
						else {
							//point.add(pd);
							Plan(gh, sz, zz,lrr1,rr2, p1,pd);
						}

					}
					}
				}
			}
		}

	}
	
	
	

	public static List drawline(Graphics gh, int sa, int sb, int ea,
			int eb) {
		List result = new ArrayList();
		// 1.1#30
		Route rr = null;
		if (sa == 71 && sb == 96) {
			// @22
			if (ea == 72 && eb == 281) {
				gh.drawLine(71, 96, 72, 281);
				rr = new Route(sa, sb, ea, eb);
			}
		}
		// #22
		if (sa == 72 && sb == 281) {
			if (ea == 71 && eb == 96) {
				gh.drawLine(72, 281, 71, 96);
				rr = new Route(sa, sb, ea, eb);
			}
			// @22
			else if (ea == 337 && eb == 281) {
				gh.drawLine(72, 281, 337, 281);
				rr = new Route(sa, sb, ea, eb);
			}
		}
		// #20
		if (sa == 337 && sb == 281) {
			// 20==22
			if (ea == 72 && eb == 281) {
				gh.drawLine(337, 281, 72, 281);
				rr = new Route(sa, sb, ea, eb);
			}
			// 20#--12#(1)
			else if (ea == 396 && eb == 282) {
				gh.drawLine(337, 281, 396, 282);
				rr = new Route(sa, sb, ea, eb);
			}
			// #20--#21
			else if (ea == 507 && eb == 286) {
				gh.drawLine(337, 281, 507, 286);
				rr = new Route(sa, sb, ea, eb);
			}
		}
		// #12
		if (sa == 396 && sb == 282) {
			// 20==12
			Route r = null;
			if (ea == 337 && eb == 281) {
				gh.drawLine(396, 282, 337, 281);// 20#--12#(1)
				rr = new Route(sa, sb, ea, eb);
			}
		}
		// #21
		if (sa == 507 && sb == 286) {
			Route r = null;
			if (ea == 580 && eb == 286) {
				gh.drawLine(507, 286, 580, 286);// 21--15
				rr = new Route(sa, sb, ea, eb);
			}

			// #20
			if (ea == 337 && eb == 281) {
				gh.drawLine(507, 286, 337, 281);// 21--15
				rr = new Route(sa, sb, ea, eb);
			}
		}
		// 端点15
		if (sa == 580 && sb == 286) {
			// 15-21
			if (ea == 507 && eb == 286) {
				gh.drawLine(580, 286, 507, 286);
				rr = new Route(sa, sb, ea, eb);
			}
		}
		result.add(rr);
		return result;
	}
public static List RouteLine(int sa, int sb){
	List lr = new ArrayList();
	//#22
			if( sa== 72 && sb == 281){
				//@30
				Route r = null;
				r=new Route(72,281,337,281);
				 lr.add(r);
				r=new Route(72,281,71,96);
				lr.add(r);
			}
	// 1.1#30
	if (sa == 71 && sb == 96) {
		Route r = null;
		lr = new ArrayList();
		r = new Route( 71,96,72, 281);
		lr.add(r);
	}
	// #20
	if (sa == 337 && sb == 281) {
		Route r = null;
		r = new Route(337, 281, 72, 281);
		lr.add(r);
		r = new Route(337, 281, 396, 282);
		lr.add(r);
		r = new Route(337, 281, 507, 286);
		lr.add(r);
	}
	// #12
	if (sa == 396 && sb == 282) {
		// 20==12
		Route r = null;
		r = new Route(396, 282, 337, 281);
		lr.add(r);
	}
	// #21
	if (sa == 507 && sb == 286) {
		Route r = null;
		r = new Route(507, 286, 580, 286);
		lr.add(r);
		r = new Route(507, 286, 337, 281);
		lr.add(r);
	}
	// 端点15
	if (sa == 580 && sb == 286) {
		// 15-21
		Route r = null;
		r = new Route(580, 286, 507, 286);
		lr.add(r);
	}
	return lr;
}
	// 知道#30 #20基站的坐标
	private static int[] case1(String a, int x, int y) {
		switch (a) {
		case "030":
			x = 71;
			y = 96;
			break;
		case "017":
			x = 145;
			y = 86;
			break;
		case "022":
			x = 72;
			y = 281;
			break;
		case "020":
			x = 337;
			y = 281;
			break;
		case "028":
			x = 352;
			y = 80;
			break;
		case "012":
			x = 396;
			y = 282;
			break;
		case "014":
			x = 420;
			y = 71;
			break;
		case "023":
			x = 441;
			y = 70;
			break;
		case "029":
			x = 509;
			y = 58;
			break;
		case "013":
			x = 441;
			y = 326;
			break;
		case "019":
			x = 503;
			y = 378;
			break;
		case "027":
			x = 600;
			y = 463;
			break;
		case "024":
			x = 149;
			y = 462;
			break;
		case "040":
			x = 149;
			y = 560;
			break;
		case "038":
			x = 736;
			y = 561;
			break;
		case "033":
			x = 690;
			y = 575;
			break;
		case "015":
			x = 580;
			y = 286;
			break;
		case "039":
			x = 446;
			y = 547;
			break;
		case "037":
			x = 446;
			y = 596;
			break;
		case "031":
			x = 656;
			y = 564;
			break;
		case "034":
			x = 656;
			y = 564;
			break;
		case "036":
			x = 549;
			y = 642;
			break;
		case "026":
			x = 549;
			y = 642;
			break;
		case "011":
			x = 694;
			y = 678;
			break;
		case "016":
			x = 444;
			y = 649;
			break;
		case "032":
			x = 690;
			y = 626;
			break;
		case "021":
			x = 507;
			y = 286;
			break;
		case "035":
			x = 650;
			y = 657;
			break;
		case "025":
			x = 650;
			y = 601;
			break;
		}
		int[] sz = { x, y };
		return sz;
	}
}

亲们,我将会在2018-10-03日的博客里面,附上实现这个图纸的递归寻找路线的代码人员定位轨迹之递归算法_第4张图片

你可能感兴趣的:(java编程专栏)