static void Main(string[] args) { PatternGenerate PGObj = new PatternGenerate(); List <xyPairs> testPointLi = PGObj.generateArray(); /*List<xyPairs> testPointLi = new List<xyPairs>(); * xyPairs u1 = new xyPairs(); u1.x = 906; u1.y = 39; testPointLi.Add(u1); * xyPairs u2 = new xyPairs(); u2.x = 559; u2.y = 132; testPointLi.Add(u2); * xyPairs u3 = new xyPairs(); u3.x = 97; u3.y = 39; testPointLi.Add(u3); * xyPairs u4 = new xyPairs(); u4.x = 703; u4.y = 868; testPointLi.Add(u4); * xyPairs u5 = new xyPairs(); u5.x = 416; u5.y = 936; testPointLi.Add(u5); * xyPairs u6 = new xyPairs(); u6.x = 279; u6.y = 289; testPointLi.Add(u6); * xyPairs u7 = new xyPairs(); u7.x = 543; u7.y = 261; testPointLi.Add(u7); * xyPairs u8 = new xyPairs(); u8.x = 461; u8.y = 308; testPointLi.Add(u8); * xyPairs u9 = new xyPairs(); u9.x = 244; u9.y = 639; testPointLi.Add(u9); * xyPairs u10 = new xyPairs();u10.x = 667; u10.y = 768; testPointLi.Add(u10);*/ Stopwatch sw = new Stopwatch(); //using System.Diagnostics; sw.Reset(); //initial sw.Start(); BruteFinder BFObj = new BruteFinder(); closetTwoPoints testCptObj = BFObj.BruteForceFindClosetPairs(testPointLi); Console.WriteLine("({0},{1}) and ({2},{3}), BruteForce method Result: dmin={4})", testCptObj.point1_x, testCptObj.point1_y, testCptObj.point2_x, testCptObj.point2_y, testCptObj.dmin); sw.Stop(); Console.WriteLine("Brute Mathod : {0} ms", sw.Elapsed.TotalMilliseconds); /*StreamWriter sw = new StreamWriter(@"D:\testPattern.txt"); * for(int i = 0; i< testPointLi.Count; i++) * { * sw.WriteLine("({0},{1})", testPointLi[i].x, testPointLi[i].y); * } * sw.Close();*/ Console.WriteLine(); Console.WriteLine(); Console.WriteLine("Below is DCF log:"); Stopwatch sw2 = new Stopwatch(); //using System.Diagnostics; sw2.Reset(); //initial sw2.Start(); DCFinder DCFObj = new DCFinder(); DCFObj.InitialXandYLis(testPointLi); closetTwoPoints DCF_CptObj = DCFObj.FindClosetPairs(); Console.WriteLine("({0},{1}) and ({2},{3}), divide and Conquer method Result: dmin={4})", DCF_CptObj.point1_x, DCF_CptObj.point1_y, DCF_CptObj.point2_x, DCF_CptObj.point2_y, DCF_CptObj.dmin); sw2.Stop(); Console.WriteLine("DCF Mathod : {0} ms", sw2.Elapsed.TotalMilliseconds); // Keep the console window open in debug mode. Console.WriteLine("Press any key to exit."); Console.ReadKey(); }
public closetTwoPoints FindClosetPairs() { if (orderX_Li.Count > 3) { DCFinder leftRecursiveDCFObj = new DCFinder(); DCFinder rightRecursiveDCFObj = new DCFinder(); //divide points into 2 sub-points List <xyPairs> leftSubOrderX_Li = orderX_Li.GetRange(0, (orderX_Li.Count + 1) / 2); List <xyPairs> rightSubOrderX_Li = orderX_Li.GetRange(((orderX_Li.Count + 1) / 2), orderX_Li.Count - ((orderX_Li.Count + 1) / 2)); double line_x = (double)(leftSubOrderX_Li[leftSubOrderX_Li.Count - 1].x + rightSubOrderX_Li[0].x) / 2.0; leftRecursiveDCFObj.orderX_Li = leftSubOrderX_Li; rightRecursiveDCFObj.orderX_Li = rightSubOrderX_Li; //also produce y-points group for merge-consideration List <xyPairs> leftSubOrderY_Li = new List <xyPairs>(); List <xyPairs> rightSubOrderY_Li = new List <xyPairs>(); write_Y_PointsToSubPoints(leftSubOrderY_Li, rightSubOrderY_Li, leftSubOrderX_Li, rightSubOrderX_Li); leftRecursiveDCFObj.orderY_Li = leftSubOrderY_Li; rightRecursiveDCFObj.orderY_Li = rightSubOrderY_Li; //handle the sub-points closetTwoPoints leftCtpObj = leftRecursiveDCFObj.FindClosetPairs(); closetTwoPoints rightCtpObj = rightRecursiveDCFObj.FindClosetPairs(); //combine result //First, consider left and right group's result if (leftCtpObj.dmin <= rightCtpObj.dmin) { this.ctpObj = leftCtpObj; } else { this.ctpObj = rightCtpObj; } //Then, consider nearby 2d region near the x-line //the height should take care in 1.5d for each points double d_regionL = this.ctpObj.dmin; double x_leftBound = line_x - d_regionL; if (x_leftBound < 0.0) { x_leftBound = 0.0; } double x_rightBound = line_x + d_regionL; if (x_rightBound > testFieldWidth) { x_rightBound = testFieldWidth; } double y_offset = 1.5 * d_regionL; //take care left side first (from bottom to top) for (int i = 0; i < leftSubOrderY_Li.Count; i++) { if (((double)(leftSubOrderY_Li[i].x) >= x_leftBound)) { for (int j = 0; j < rightSubOrderY_Li.Count; j++) { bool condition1 = ((double)(rightSubOrderY_Li[j].x) <= x_rightBound); bool condition2 = ((double)(rightSubOrderY_Li[j].y) >= leftSubOrderY_Li[i].y); bool condition3 = ((double)(rightSubOrderY_Li[j].y) <= leftSubOrderY_Li[i].y + y_offset); if (condition1 && condition2 && condition3) { double d = this.ComputeDistanceBetweenPoints(leftSubOrderY_Li[i], rightSubOrderY_Li[j]); if (d < this.ctpObj.dmin) { this.updateClosetTwoPoints(leftSubOrderY_Li[i], rightSubOrderY_Li[j], d); //Console.WriteLine("update case1 {0}", d); } } else { continue; } } } else { continue; } } //take care right side (from bottom to top) for (int i = 0; i < rightSubOrderY_Li.Count; i++) { if ((double)(rightSubOrderY_Li[i].x) <= x_rightBound) { for (int j = 0; j < leftSubOrderY_Li.Count; j++) { bool condition1 = ((double)(leftSubOrderY_Li[j].x) >= x_leftBound); bool condition2 = ((double)(leftSubOrderY_Li[j].y) >= rightSubOrderY_Li[i].y); bool condition3 = ((double)(leftSubOrderY_Li[j].y) <= rightSubOrderY_Li[i].y + y_offset); if (condition1 && condition2 && condition3) { double d = this.ComputeDistanceBetweenPoints(rightSubOrderY_Li[i], leftSubOrderY_Li[j]); if (d < this.ctpObj.dmin) { this.updateClosetTwoPoints(leftSubOrderY_Li[j], rightSubOrderY_Li[i], d); //Console.WriteLine("update case2 {0}", d); } } else { continue; } } } else { continue; } } //Console.WriteLine(this.ctpObj.dmin); return(this.ctpObj); } else { //points less than 3, directly use brute force to calculate this.ctpObj.dmin = testFieldWidth * 10; //max value for (int i = 0; i < orderX_Li.Count; i++) { for (int j = 0; j < orderX_Li.Count; j++) { if (j == i) { continue; } else { double d = this.ComputeDistanceBetweenPoints(orderX_Li[i], orderX_Li[j]); if (d < this.ctpObj.dmin) { this.updateClosetTwoPoints(orderX_Li[i], orderX_Li[j], d); } } } } //Console.WriteLine(ctpObj.dmin); return(this.ctpObj); } }