Example #1
0
        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);
            }
        }