大三上学期,使用Java不完整实现Lee寻址算法。

来源:互联网 发布:电脑视频剪辑小软件 编辑:程序博客网 时间:2024/06/02 08:54

大三上学期,上了一门Data Structure and Algorithms 也就是数据结构与算法,当时刚来到国外,上课听讲也是半懂半晕的,基本都是靠课下自己重新看讲义,自己实践。

作为最后的结课项目,要求实现在电路设计中经常用的寻找路径算法,Lee算法虽然是一项比较早的技术,但是老师认为可以反映一下我们的学习情况。写下来用了一个星期多些,虽然代码短但是经常要在debug模式里跟着程序过着看问题,浪费了很多时间和脑子。


算法分析

Lee算法是在一个一定大小的表格中,从某点向外延展波形,当波形遇到目标点后停止,再根据波形backtracking到起点,画出路径。

这个算法的实现有很多衍生的改进方案,最基本的是单波寻址,波形只从出发点扩散,然后backtracking。

第一个改进方案是从起点与目的地两点同时扩散波形,当波形相遇后从中间点扩散。


这个解决两点扩散很容易,但当时遇到的问题其实并不在这里,问题在波形相遇后的backtracking问题上。在寻找路径中,转向次数是算进路径评分中的,具体如下图,两图都是用了5个单位,但是左图转向两次,右图转向一次,右图最优。这里需要对循环条件进行特殊判断。


第二个改进方案是每次波形扩大一圈,从新的一圈展开新波形,这个能很好的减少资源浪费,可以避免没有意义的点同时减少程序内的循环判断。这个从图上很难看出来,但是从代码上会发现他的益处。


实现及代码

具体的实现方法是利用int二维数组作为grid,并根据读取的文件初始化数组,如resize与赋值。可以通过的格子都会被赋值为0,芯片覆盖的以及其他路线经过的格子被赋值为固定数值来予以区分,因为老师还要求有对输入文件中规定的参数进行检测,还需检测芯片是否重合,给出的路线是否最短,最优,同时做一个基于grid大小变化的性能图。

最后的文件有4个,Lee, function, verification以及measurement。分别用来实现lee算法,提供定义grid功能,检验错误,测试性能。

Lee的实现方法如下:

package Test;import static Test.functions.*;import java.util.ArrayList;public class Lee {ArrayList<int[]> wave = new ArrayList<int[]>();/* * Start: x1,y1 are the coordinate of goal point; i,j is one point of the * current wave front. grid[i][j] will tell the expandWave the current k * value. */void Start(int x0,int y0,int x1, int y1) {int[] q = {x0,y0};wave.add(q);for (int m = 0; m < 10000; m++) {int[] p = (int[]) wave.get(m);int i = p[0];int j = p[1];if (expandWave(grid[i][j], i, j, x1, y1) == 1)return;}}/* * expandWave will expand from the current point grid[i][j]. For every * successful expand on each direction, the ArrayList wave will store a * small array q which contains the coordinate. If the goal was found, then * return 1 and end the loop; */int expandWave(int k, int i, int j, int x1, int y1) {if (i + 1 < gridW && grid[i + 1][j] == 0) {grid[i + 1][j] = k + 1;int[] q = { i + 1, j };wave.add(q);//Store WaveFrontif (i + 1 == x1 && j == y1)return 1;}if (j + 1 < gridH && grid[i][j + 1] == 0) {grid[i][j + 1] = k + 1;int[] q = { i, j + 1 };wave.add(q);if (i == x1 && j + 1 == y1)return 1;}if (i - 1 >= 0 && grid[i - 1][j] == 0) {grid[i - 1][j] = k + 1;int[] q = { i - 1, j };wave.add(q);if (i - 1 == x1 && j == y1)return 1;}if (j - 1 >=0 && grid[i][j - 1] == 0) {grid[i][j - 1] = k + 1;int[] q = { i, j - 1 };wave.add(q);if (i == x1 && j - 1 == y1)return 1;}return 0;}/* * backtracking will start from the goal point and back to the start point */void backtracking(int x1, int y1, int n) {int k = grid[x1][y1];while (k > 1) {while (x1 + 1 < gridW && grid[x1 + 1][y1] == k - 1 && k!=1) {x1++;k--;grid[x1][y1] = T + n;}while (x1 > 0 && grid[x1 - 1][y1] == k - 1 && k!=1) {x1--;k--;grid[x1][y1] = T + n;}while (y1 + 1 < gridH && grid[x1][y1 + 1] == k - 1 && k!=1) {y1++;k--;grid[x1][y1] = T + n;}while (y1 > 0 && grid[x1][y1 - 1] == k - 1 && k!=1) {y1--;k--;grid[x1][y1] = T + n;}}}}


另外单独写了一个function类来方便测试,如下:

package Test;public class functions {static int gridW=77, gridH=77;static int [][] grid;final static int O = 1000; //Occupied;final static int T = 1500; //Tracks,Only for the backtracking;final static int J = 1200; //The start value of Joints;//This will reset the gridstatic int[][] createGrid(int W,int H){int[][] grid = new int[H][];for (int i=0;i<grid.length;i++)grid[i] = new int[W];return grid;}//This will clean the search numbersstatic void cleanGrid(){for (int x = 0; x < gridH; x++) {for (int z = 0; z < gridW; z++) {if (grid[z][x] <1000){grid[z][x] = 0;}}}}//This will print out the current grid.//0,print the current grid without clean//1,clean the gridstatic void printgrid(int i){for (int x = 0; x < gridH; x++) {for (int z = 0; z < gridW; z++) {if (grid[z][x] <1000){if (i == 1){grid[z][x]=0;System.out.print("-");}if (i == 0){if (grid[z][x] > 9)System.out.print((char)(grid[z][x]-10+'A'));else{if (grid[z][x]==0)System.out.print("-");if (grid[z][x]>0)System.out.print(grid[z][x]);}}}//print other kind of valuesif (grid[z][x] == O)System.out.print("*");if (grid[z][x] > T)System.out.print((char)(grid[z][x]-T+'A'-1));if (grid[z][x] > J && grid[z][x] < T)System.out.print((char)(grid[z][x]-J+'a'-1));}System.out.println(" "); }}}

使用例子:

if (w[0].equals("J")) {int x0 = Integer.parseInt(w[1]);int y0 = Integer.parseInt(w[2]);int x1 = Integer.parseInt(w[3]);int y1 = Integer.parseInt(w[4]);grid[x0][y0] = 1; // Set the start point as 1;n++;// The n helps to distinguish different Tracks and joints;long startTime = System.nanoTime();Lee lee = new Lee(); // Initialize Lee and pass the start point;lee.Start(x0, y0, x1, y1); // Pass the goal point;lee.backtracking(x1, y1, n);long timeCost = (System.nanoTime() - startTime);time += timeCost;grid[x0][y0] = J + n;grid[x1][y1] = J + n;cleanGrid();}



另外两个文件与实现算法无关就不放了,给几张图吧。

图上不上来,有空再放吧。。

0 0
原创粉丝点击