Java实现算法导论中凸包问题Jarvis步进法
生活随笔
收集整理的這篇文章主要介紹了
Java实现算法导论中凸包问题Jarvis步进法
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
對于凸包的理解,參考http://www.cnblogs.com/Booble/archive/2011/02/28/1967179.html,說的還是比較深入淺出。
凸包問題的Jarvis步進法,其算法流程:
1.找橫坐標最小的點(有一樣的話縱坐標更小的)
2.從這點開始卷包裹 ?找最靠近外側的點(通過叉積比較)
3.找到的點為起點退出
代碼參考如下:
package cn.ansj;import static java.lang.Math.abs; import java.util.Iterator; import java.util.LinkedList; import java.util.List;public class JarvisMarch {private int count;public int getCount() {return count;}public void setCount(int count) {this.count = count;}private static int MAX_ANGLE = 4;private double currentMinAngle = 0;private List<Point> hullPointList;private List<Integer> indexList;private PointFactory pf;private Point[] ps;public Point[] getPs() {return ps;}private int firstIndex;public int getFirstIndex() {return firstIndex;}public JarvisMarch() {this(10);}public JarvisMarch(int count) {pf = PointFactory.getInstance(count);initialize();}public JarvisMarch(int[] x, int[] y) {pf = PointFactory.getInstance(x, y);initialize();}private void initialize() {hullPointList = new LinkedList<Point>();indexList = new LinkedList<Integer>();firstIndex = pf.getFirstIndex();ps = pf.getPoints();addToHull(firstIndex);}private void addToHull(int index) {indexList.add(index);hullPointList.add(ps[index]);}public int calculateHull() {for (int i = getNextIndex(firstIndex); i != firstIndex; i = getNextIndex(i)) {addToHull(i);}showHullPoints();return 0;}private void showHullPoints() {Iterator<Point> itPoint = hullPointList.iterator();Iterator<Integer> itIndex = indexList.iterator();Point p;int i;int index = 0;System.out.println("The hull points is: -> ");while (itPoint.hasNext()) {i = itIndex.next();p = itPoint.next();System.out.print(i + ":(" + p.getX() + "," + p.getY() + ") ");index++;if (index % 10 == 0)System.out.println();}System.out.println();System.out.println("****************************************************************");System.out.println("The count of all hull points is " + index);}public int getNextIndex(int currentIndex) {double minAngle = MAX_ANGLE;double pseudoAngle;int minIndex = 0;for (int i = 0; i < ps.length; i++) {if (i != currentIndex) {pseudoAngle = getPseudoAngle(ps[i].getX() - ps[currentIndex].getX(), ps[i].getY() - ps[currentIndex].getY());if (pseudoAngle >= currentMinAngle && pseudoAngle < minAngle) {minAngle = pseudoAngle;minIndex = i;} else if (pseudoAngle == minAngle){if((abs(ps[i].getX() - ps[currentIndex].getX()) > abs(ps[minIndex].getX() - ps[currentIndex].getX()))|| (abs(ps[i].getY() - ps[currentIndex].getY()) > abs(ps[minIndex].getY() - ps[currentIndex].getY()))){minIndex = i;}}}}currentMinAngle = minAngle;return minIndex;}public double getPseudoAngle(double dx, double dy) {//計算極角if (dx > 0 && dy >= 0)return dy / (dx + dy);if (dx <= 0 && dy > 0)return 1 + (abs(dx) / (abs(dx) + dy));if (dx < 0 && dy <= 0)return 2 + (dy / (dx + dy));if (dx >= 0 && dy < 0)return 3 + (dx / (dx + abs(dy)));throw new Error("Impossible");}public static void main(String[] args) {long start = System.currentTimeMillis();JarvisMarch j = new JarvisMarch(100000);Point[] points = j.getPs();int firstIndex = j.getFirstIndex();System.out.println("the first point is: " + firstIndex + ":(" + points[firstIndex].getX() + "," + points[firstIndex].getY() + ")"); System.out.println("*****************************************************************");j.calculateHull();System.out.println("The total running time is " + (System.currentTimeMillis() - start) + " millis.");} } package cn.ansj;public class PointFactory { /*** 單例模式,大批量產生Point,也可以手動產生Point*/private Point[] points = null;private int newIndex;private int firstIndex = 0;public Point[] getPoints() {return points;}public int getFirstIndex() {return firstIndex;}public static PointFactory getInstance() {return new PointFactory();}public static PointFactory getInstance(int count) {return new PointFactory(count);}public static PointFactory getInstance(int[] x, int[] y) {return new PointFactory(x, y);}private PointFactory() {this(10);}private PointFactory(int count) {points = new Point[count];for (int i = 0; i < count; i++) {points[i] = new Point();newIndex = i;validatePoints();}firstIndex = getFirstPoint();}public PointFactory(int[] x, int[] y) {points = new Point[y.length];for (int i = 0; i < y.length; i++) {points[i] = new Point(x[i], y[i]);}firstIndex = getFirstPoint();}private void validatePoints() {for(int i = 0; i < newIndex; i++) {if(points[i].equals(points[newIndex])) {points[newIndex] = new Point();validatePoints();}}}public int getFirstPoint() {int minIndex = 0;for (int i = 1; i < points.length; i++) {if (points[i].getY() < points[minIndex].getY()) {minIndex = i;} else if ((points[i].getY() == points[minIndex].getY())&& (points[i].getX() < points[minIndex].getX())) {minIndex = i;}}return minIndex;}} package cn.ansj;public class Point {// 定義點的x,y坐標,之所以是int類型,是為了日后可以在計算機屏幕上進行可視化。private int x;private int y;// x,y的get方法public int getX() {return x;}public int getY() {return y;} // 定義點到屏幕邊緣的距離private static double PADDING = 20; // 點在屏幕中的范圍private static double POINT_RANGE = (800 - PADDING * 2);// 默認構造方法,產生隨機點public Point() {this.x = (int) ((Math.random() * POINT_RANGE) + PADDING);this.y = (int) ((Math.random() * POINT_RANGE) + PADDING);}// 帶參構造方法,可以實現手動輸入固定點 public Point(int x, int y) {this.x = x;this.y = y;}// 覆寫hashCode()和equals()方法,實現比較和Hash@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + x;result = prime * result + y;return result;}@Overridepublic boolean equals(Object obj) {Point other = (Point) obj;if ((x == other.x) && (y == other.y))return true;return false;}}執行結果如下: the first point is: 72886:(52,20) ***************************************************************** The hull points is: -> 72886:(52,20) 37943:(778,20) 81531:(779,21) 34317:(779,779) 69049:(20,779) 14579:(20,22) 80398:(22,21) **************************************************************** The count of all hull points is 7 The total running time is 38019 millis.
總結
以上是生活随笔為你收集整理的Java实现算法导论中凸包问题Jarvis步进法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 算法导论之计算几何学
- 下一篇: Java实现算法导论中最近点对问题分治法