Advertisement
Guest User

EfficientPoint2DMinDIstance+1

a guest
Oct 12th, 2015
189
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using System.Diagnostics;
  7.  
  8. namespace EfficientPoint2DMinDIstance
  9. {
  10.     public static class Utils
  11.     {
  12.         public static T MinBy<T, R>(this IEnumerable<T> source, Func<T, R> f) where R : IComparable<R>
  13.         {
  14.             IEnumerator<T> e = source.GetEnumerator();
  15.             if (!e.MoveNext())
  16.             {
  17.                 throw new Exception("You need to provide at least one element.");
  18.             }
  19.             T min = e.Current;
  20.             R minf = f(min);
  21.             while (e.MoveNext())
  22.             {
  23.                 T x = e.Current;
  24.                 R xf = f(x);
  25.                 if (minf.CompareTo(xf) > 0)
  26.                 {
  27.                     min = x;
  28.                     minf = xf;
  29.                 }
  30.             }
  31.             return min;
  32.         }
  33.  
  34.     }
  35.  
  36.     class Point
  37.     {
  38.         public readonly int id;
  39.         public float x;
  40.         public float y;
  41.         public Point(int id, float x, float y)
  42.         {
  43.             this.id = id;
  44.             this.x = x;
  45.             this.y = y;
  46.         }
  47.         public float Distance(Point p)
  48.         {
  49.             float dx = this.x - p.x;
  50.             float dy = this.y - p.y;
  51.             return (float)Math.Sqrt(dx * dx + dy * dy);
  52.         }
  53.     }
  54.  
  55.     class Program
  56.     {
  57.         enum Version
  58.         {
  59.             CommuSoft,
  60.             IpavluA1,
  61.             IpavluA2,
  62.             IpavluB,
  63.             IvanStoev
  64.         }
  65.         static void Main()
  66.         {
  67.             Console.WriteLine();
  68.             Point p = new Point(3, 0.6f, 0.0f);
  69.             Point p_rslt = null;
  70.             int t_tests = 5;
  71.  
  72.             var list_a = BuildList(3);
  73.             var list_b = BuildList(3000000);
  74.  
  75.  
  76.             for (int t = 0; t < t_tests; ++t)
  77.             {
  78.                 Batch(10000000, list_a, p, out p_rslt);
  79.             }
  80.  
  81.  
  82.             for (int t = 0; t < t_tests; ++t)
  83.             {
  84.                 Batch(1, list_b, p, out p_rslt);
  85.             }
  86.  
  87.             Console.ReadKey();
  88.         }
  89.         static List<Point> BuildList(int items)
  90.         {
  91.             var list = new List<Point>();
  92.             //Random r = new Random();
  93.             bool odd_even = false;
  94.             for (int i = 0; i < items; i++, odd_even = !odd_even)
  95.             {
  96.                 var multiply = odd_even ? 1.0 : 2.0;
  97.                 //var rnd = (float)(r.NextDouble() * multiply);
  98.                 var rnd = (float)(0.6 * multiply);
  99.                 list.Add(new Point(i, rnd, 0.0f));
  100.             }
  101.             return list;
  102.         }
  103.         static void Compute(int batch_iterations, Version version, Point p, List<Point> list, out Point rslt)
  104.         {
  105.             Stopwatch sw = new Stopwatch();
  106.             rslt = null;
  107.             switch (version)
  108.             {
  109.                 case Version.CommuSoft:
  110.                     sw.Start();
  111.                     for (int b = 0; b < batch_iterations; b++)
  112.                     {
  113.                         rslt = CommuSoft(list, p);
  114.                     }
  115.                     sw.Stop();
  116.                     break;
  117.                 case Version.IpavluA1:
  118.                     sw.Start();
  119.                     for (int b = 0; b < batch_iterations; b++)
  120.                     {
  121.                         rslt = ipavlu_VersionA1(list, p);
  122.                     }
  123.                     sw.Stop();
  124.                     break;
  125.                 case Version.IpavluA2:
  126.                     sw.Start();
  127.                     for (int b = 0; b < batch_iterations; b++)
  128.                     {
  129.                         rslt = ipavlu_VersionA2(list, p);
  130.                     }
  131.                     sw.Stop();
  132.                     break;
  133.                 case Version.IpavluB:
  134.                     sw.Start();
  135.                     for (int b = 0; b < batch_iterations; b++)
  136.                     {
  137.                         rslt = ipavlu_VersionB(list, p);
  138.                     }
  139.                     sw.Stop();
  140.                     break;
  141.                 case Version.IvanStoev:
  142.                     sw.Start();
  143.                     for (int b = 0; b < batch_iterations; b++)
  144.                     {
  145.                         rslt = IvanStoev(list, p);
  146.                     }
  147.                     sw.Stop();
  148.                     break;
  149.             }
  150.             Console.Write("{0}: {1} ", version.ToString(), sw.ElapsedMilliseconds);
  151.         }
  152.         static void Batch(int batch_iterations, List<Point> list, Point p, out Point p_rslt)
  153.         {
  154.             Console.Write("B[{0}] I[{1}]: ", batch_iterations, list.Count);
  155.             Compute(batch_iterations, Version.CommuSoft, p, list, out p_rslt);
  156.             Compute(batch_iterations, Version.IpavluA1, p, list, out p_rslt);
  157.             Compute(batch_iterations, Version.IpavluA2, p, list, out p_rslt);
  158.             Compute(batch_iterations, Version.IpavluB, p, list, out p_rslt);
  159.             Compute(batch_iterations, Version.IvanStoev, p, list, out p_rslt);
  160.             Console.Write("\n");
  161.         }
  162.         static Point CommuSoft(List<Point> list, Point p)
  163.         {
  164.             return
  165.             list
  166.             .Where(x => x.Distance(p) <= 1.0)
  167.             .OrderBy(x => x.Distance(p))
  168.             .FirstOrDefault()
  169.             ;
  170.         }
  171.         static Point ipavlu_VersionA1(List<Point> list, Point p)
  172.         {
  173.             //version A, most efficient memory and cpu usage
  174.             Point closest_to_p = null;
  175.             float shortest_d = float.MaxValue;
  176.  
  177.             list.ForEach(point =>
  178.             {
  179.                 var d = point.Distance(p);
  180.                 if (d > 1.0f) return;
  181.                 if (closest_to_p == null || shortest_d > d)
  182.                 {
  183.                     closest_to_p = point;
  184.                     shortest_d = d;
  185.                 }
  186.             });
  187.             return closest_to_p;
  188.         }
  189.         static Point ipavlu_VersionA2(List<Point> list, Point p)
  190.         {
  191.             //version A, most efficient memory and cpu usage, better than A1
  192.             Point closest_to_p = null;
  193.             float shortest_d = float.MaxValue;
  194.             int max = list.Count;
  195.  
  196.             for (int i = 0; i < max; ++i)
  197.             {
  198.                 var point = list[i];
  199.                 var d = point.Distance(p);
  200.                 if (d > 1.0f) continue;
  201.                 if (closest_to_p == null || shortest_d > d)
  202.                 {
  203.                     closest_to_p = point;
  204.                     shortest_d = d;
  205.                 }
  206.             }
  207.             return closest_to_p;
  208.         }
  209.         static Point ipavlu_VersionB(List<Point> list, Point p)
  210.         {
  211.             KeyValuePair<Point,float> null_point =  new KeyValuePair<Point,float>(null, float.PositiveInfinity);
  212.             var rslt_point =
  213.             list
  214.             .Select(xp =>
  215.             {
  216.                 var d = xp.Distance(p);
  217.                 return d <= 1.0f ? new KeyValuePair<Point, float>(xp, d) : null_point;
  218.             })
  219.             .Aggregate(null_point, (a, b) =>
  220.             {
  221.                 if (a.Key == null) return b;
  222.                 if (b.Key == null) return a;
  223.                 return a.Value > b.Value ? b : a;
  224.             }, x => x.Key);
  225.             return rslt_point;
  226.         }
  227.  
  228.  
  229.         static Point IvanStoev(List<Point> list, Point p)
  230.         {
  231.             var closest =
  232.             list
  233.             .Select(item => new { item, distance = item.Distance(p) })
  234.             .Aggregate((a, b) => a.distance <= b.distance ? a : b)
  235.             ;
  236.             var closestPt = closest.distance <= 1.0 ? closest.item : null;
  237.             return closestPt;
  238.         }
  239.     }
  240. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement