这篇微博是2018-9-28日写的,当时虽然实现递归,但是有许多缺陷,可以说很烂;
前言:
每个算法都有它的优势和缺点,我的这个算法的缺点就是不适用路线复杂的!
现在是2018-10-03日,我终于把这个递归算法实现了;于是把之前的博客内容删了;免得误人子弟。
项目名称:矿山定位系统之人员运动轨迹的绘制;
第一步:有基站的图纸显示在jsp页面
1.DWG图纸在jsp页面显示
2.利用position=absolute,将一个透明的div(和图纸大小)放在图纸上显示的部位;
3.用屏幕取点法绘制基站的位置,再利用java的Graphic绘制直线
我做的效果如下:
第二步:
把实际相邻基站的路线绘制出来;
我说的是实际情况,例如,这里的基站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
思路:
1、根据条件(某个时间段,某人)在数据库里查询出经过的基站,把基站放在一个list集合里面
当然前期可以自己给定list集合数据,因为查询数据库步骤麻烦;
2、取第一个基站和第二个基站,是否存在第一个基站直达第二个基站,如果存在,路线就是第一个基站到第二个基站;
如果不能直达,就寻找以第一个基站为起点的相邻基站的路线集合,循环这个集合里面的数据;
假设集合里面的数据是(第一基站,相邻基站);
判断这个相邻基站能否直达第二个基站,能的话,路线图是第一基站-相邻基站-第二基站;
如果不能,再获取这个相邻基站下面的与之相邻基站的路线集合,循环遍历这个新的路线集合, 判断这个新的路线集合的(相邻基站,相邻基站1),这个相邻基站1不能与第一基站一样,不然就会陷入死循环;
图示如下:
第一个基站是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;
}
}