public static double CalculateDistance(Node[] graph, long startNode, long endNode, double[] dist, bool[] isProcessed)
        {
            if (startNode == endNode)
            {
                return(0);
            }

            bool[] open      = new bool[graph.Length];
            bool[] closed    = new bool[graph.Length];
            int    openCount = 0;

            dist[startNode] = 0;
            for (int i = 1; i < graph.Length; i++)
            {
                graph[i].Potential = CalculatePotential(graph, graph[i], graph[endNode], dist);
            }
            open[(int)startNode] = true;
            MinHeap heap = new MinHeap(graph.Length - 1);

            heap.BuildHeap(graph, (int)startNode);
            openCount++;
            Node temp = new Node();

            while (openCount > 0)
            {
                temp = graph[heap.ExtractMin()];

                if (temp.Key == endNode)
                {
                    return(dist[temp.Key]);
                }

                open[temp.Key] = false;
                openCount--;
                closed[temp.Key] = true;

                for (int i = 0; i < temp.Children.Count; i++)
                {
                    if (closed[temp.Children[i].Key])
                    {
                        continue;
                    }

                    var tentative_dist = dist[temp.Key] + temp.Children[i].Weight;

                    if (!open[temp.Children[i].Key])
                    {
                        open[temp.Children[i].Key] = true;
                        openCount++;
                    }
                    else if (tentative_dist >= dist[temp.Children[i].Key])
                    {
                        continue;
                    }

                    dist[temp.Children[i].Key] = tentative_dist;

                    if (dist[temp.Children[i].Key] +
                        CalculatePotential(graph, graph[temp.Children[i].Key], graph[endNode], dist)
                        < graph[temp.Children[i].Key].Potential)
                    {
                        graph[temp.Children[i].Key].Potential =
                            dist[temp.Children[i].Key] +
                            CalculatePotential(graph, graph[temp.Children[i].Key], graph[endNode], dist);

                        heap.ChangePriority(temp.Children[i].Key, graph[temp.Children[i].Key].Potential);
                    }
                }
            }
            return(-1);
        }
Beispiel #2
0
        public double Solve(long pointCount, long[][] points)
        {
            double  cost  = 0;
            MinHeap edges = new MinHeap(pointCount * pointCount);

            for (int i = 0; i < pointCount - 1; i++)
            {
                for (int j = i + 1; j < pointCount; j++)
                {
                    edge edge = new edge();
                    edge.u    = i;
                    edge.v    = j;
                    edge.cost = Math.Pow(Math.Pow((points[i][0] - points[j][0]), 2) + Math.Pow((points[i][1] - points[j][1]), 2), 0.5);
                    edges.Add(edge);
                }
            }

            List <long> sets = new List <long>();

            for (int i = 0; i < pointCount; i++)
            {
                sets.Add(i);
            }
            int edgeNumber = 0;
            int size       = edges._size;

            for (int i = 0; i < size; i++)
            {
                if (edgeNumber == pointCount - 1)
                {
                    break;
                }
                edge edge = edges.Pop();
                if (sets[edge.u] != sets[edge.v])
                {
                    edgeNumber++;

                    cost += edge.cost;
                    long tmp = sets[edge.v];
                    for (int j = 0; j < pointCount; j++)
                    {
                        if (sets[j] == tmp)
                        {
                            sets[j] = sets[edge.u];
                        }
                    }
                }
            }

            /*List<Node> graph = new List<Node>();
             * List<edge> edges = new List<edge>();
             *
             * for (int i=0; i<pointCount; i++)
             * {
             *  graph.Add(new Node());
             *  graph[i].x = points[i][0];
             *  graph[i].y = points[i][1];
             *  graph[i].set = i;
             *
             * }
             *
             *
             * for (int i=0; i < pointCount-1; i++)
             * {
             *  for (int j=i+1; j < pointCount;j++)
             *  {
             *      edge edge = new edge();
             *      edge.u = graph[i];
             *      edge.v = graph[j];
             *      edge.cost = Math.Pow(Math.Pow((edge.u.x - edge.v.x), 2) + Math.Pow((edge.u.y - edge.v.y), 2), 0.5);
             *      edges.Add(edge);
             *  }
             * }
             * for (int i=0; i < edges.Count; i++)
             * {
             *  double min = double.MaxValue;
             *  int minIndex = int.MaxValue;
             *  for (int j=i; j < edges.Count; j++)
             *  {
             *      if (edges[j].cost < min)
             *      {
             *          minIndex = j;
             *          min = edges[j].cost;
             *      }
             *  }
             *  edge tmp = edges[i];
             *  edges[i] = edges[minIndex];
             *  edges[minIndex] = tmp;
             * }
             * double cost = 0;
             * int edgeNumber = 0;
             *
             * for(int i= 0; i<edges.Count; i++)
             * {
             *  if (edgeNumber == pointCount - 1)
             *      break;
             *  if (edges[i].u.set != edges[i].v.set)
             *  {
             *      edgeNumber++;
             *      edges[i].v.edges.Add(edges[i].u);
             *      edges[i].u.edges.Add(edges[i].v);
             *      cost += edges[i].cost;
             *      long tmp = edges[i].v.set;
             *      for (int j = 0; j < pointCount; j++)
             *      {
             *          if (graph[j].set == tmp)
             *              graph[j].set = edges[i].u.set;
             *      }
             *  }
             *
             * }*/
            return((double)((long)(cost * 1000000 + 0.5)) / 1000000);
        }