二维地图的寻路算法2。
首先需要说明本算法得到的解不一定是最优解,但是比普通的回溯算法速度要快。
代码如下:
- import java.util.Stack;
- public class FindPath {
-
- private Stack stack = new Stack();
-
- private int wid = 8;
-
- public String find(byte[] map, int origin, int target) {
- if (origin == target) {
- return "";
- }
- int[] step = new int[10];
- step[1] = origin;
- judge(map, step, target);
- stack.push(step);
- if (!findPath(map, target)) {
- return null;
- }
- optimize(stack);
- StringBuffer sb = new StringBuffer();
- for (int i = 1; i < stack.size(); i++) {
- step = (int[]) stack.elementAt(i);
- sb.append((char) step[0]);
- }
- return sb.toString();
- }
-
- private void judge(byte[] map, int[] node, int target) {
- int origin = node[1];
- int x0 = origin % wid;
- int y0 = origin / wid;
- int x1 = target % wid;
- int y1 = target / wid;
- int distance = 0;
- distance = (x0 - 1 - x1) * (x0 - 1 - x1) + (y0 - y1) * (y0 - y1);
- node[2] = 'l';
- node[3] = distance;
- distance = (x0 + 1 - x1) * (x0 + 1 - x1) + (y0 - y1) * (y0 - y1);
- node[4] = 'r';
- node[5] = distance;
- distance = (x0 - x1) * (x0 - x1) + (y0 - 1 - y1) * (y0 - 1 - y1);
- node[6] = 'u';
- node[7] = distance;
- distance = (x0 - x1) * (x0 - x1) + (y0 + 1 - y1) * (y0 + 1 - y1);
- node[8] = 'd';
- node[9] = distance;
- int direct;
- for (int i = 2; i < node.length; i += 2) {
- for (int j = i + 2; j < node.length; j += 2) {
- if (node[j + 1] < node[i + 1]) {
- direct = node[j];
- distance = node[j + 1];
- node[j] = node[i];
- node[j + 1] = node[i + 1];
- node[i] = direct;
- node[i + 1] = distance;
- }
- }
- }
- }
-
- private boolean findPath(byte[] map, int target) {
- int[] node = (int[]) stack.peek();
- for (int i = 2; i < node.length; i += 2) {
- if (node[i + 1] >= 0) {
- if (canMoveTo(map, node, i, target)) {
- return true;
- } else {
- node[i + 1] = -1;
- }
- }
- }
- stack.pop();
- return false;
- }
-
- private boolean canMoveTo(byte[] map, int[] node, int index, int target) {
- int next = 0;
- switch (node[index]) {
- case 'l':
- next = node[1] - 1;
- break;
- case 'r':
- next = node[1] + 1;
- break;
- case 'u':
- next = node[1] - wid;
- break;
- case 'd':
- next = node[1] + wid;
- break;
- }
- if (map[next] == 0) {
- if (next == target) {
- int[] step = new int[10];
- step[0] = node[index];
- step[1] = next;
- stack.push(step);
- return true;
- }
- if (!inStack(next)) {
- int[] step = new int[10];
- step[0] = node[index];
- step[1] = next;
- this.judge(map, step, target);
- stack.push(step);
- if (findPath(map, target)) {
- return true;
- }
- }
- }
- return false;
- }
-
- private boolean inStack(int posi) {
- int[] temp;
- for (int i = stack.size() - 1; i >= 0; i--) {
- temp = (int[]) stack.elementAt(i);
- if (posi == temp[1]) {
- return true;
- }
- }
- return false;
- }
-
- private void optimize(Stack stack) {
- for (int i = 0; i < stack.size() - 3; i++) {
- int[] step1 = (int[]) stack.elementAt(i);
- int[] step2 = (int[]) stack.elementAt(i + 1);
- int[] step3 = (int[]) stack.elementAt(i + 2);
- if (step1[0] != step2[0] && step1[0] != step3[0]
- && step2[0] != step3[0]) {
- int[] step = new int[10];
- step[0] = step2[0];
- step[1] = step3[1];
- stack.removeElementAt(i + 2);
- stack.removeElementAt(i + 1);
- stack.removeElementAt(i);
- stack.insertElementAt(step, i);
- }
- }
- }
-
- public static void main(String[] args) {
- byte[] map = { 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 0, 0, 1, 1,
- 1, 0, 0, 0, 0, 0, 1, 1,
- 1, 0, 1, 1, 0, 0, 1, 1,
- 1, 0, 0, 0, 1, 0, 1, 1,
- 1, 0, 1, 0, 0, 0, 1, 1,
- 1, 0, 0, 0, 1, 0, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1 };
- FindPath ai = new FindPath();
- for (int i = 0; i < map.length; i++) {
- System.out.print(map[i] + " ");
- if (i % ai.wid == ai.wid - 1) {
- System.out.print("\n");
- }
- }
- System.out.print("\n");
- String s = ai.find(map, 13, 50);
- System.out.println(s);
- }
- }
The result as following:
1 1 1 1 1 1 1 1
1 1 1 1 0 0 1 1
1 0 0 0 0 0 1 1
1 0 1 1 0 0 1 1
1 0 0 0 1 0 1 1
1 0 1 0 0 0 1 1
1 0 0 0 1 0 1 1
1 1 1 1 1 1 1 1
dllllddddr
即,路径是:下,左,左,左,左,下,下,下,下,右。这个路径用了10步。
从地图中,我们可以看出有另一条路径:下,下,下,下,左,左,下,左。可以只用8步就完成。
所以,本算法不是一个最优解算法。
另外,评价值函数的影响很大,本文中简单的使用了距离的平方作为评价值,比较粗糙。
大家可以多想想,提出宝贵意见。
发表于 @ 2008年08月26日 11:47:00|评论(loading...)|编辑|收藏