/// <summary> /// Поиск оптимального маршрута /// /// Route.Way содержит путь, null, если пути нет /// Route.Value - цена маршрута /// </summary> /// <param name="vertColl">Коллекция вершин</param> /// <param name="edgColl">Коллекция дуг</param> /// <param name="criterial">Критерий поиска</param> /// <param name="driver">Водитель</param> public void FindMinLengthWay(Vertexes vertColl, Edges edgColl, Main.Criterial criterial, Driver.Driver driver) { CurrentDriver = new Driver.Driver(driver.FIO, driver.IsViolateTL, driver.Car); long[,] parents; long[] IDs; long fromVertex = 0, toVertex = 0; for (int i = 0; i < Map.vertexes.GetCountElements(); i++) { if (Map.vertexes.GetElement(i).ID == Start.ID) { fromVertex = i; } if (Map.vertexes.GetElement(i).ID == End.ID) { toVertex = i; } } double[,] matrix = GetMatrixWay(out parents, out IDs, vertColl, edgColl, criterial, driver); int size = (int)Math.Sqrt(matrix.Length); for (int k = 0; k < size; ++k) { for (int i = 0; i < size; ++i) { for (int j = 0; j < size; ++j) { if (matrix[i, k] < Double.MaxValue && matrix[k, j] < Double.MaxValue && matrix[i, k] + matrix[k, j] < matrix[i, j]) { matrix[i, j] = matrix[i, k] + matrix[k, j]; parents[i, j] = parents[k, j]; } } } } if (matrix[fromVertex, toVertex] == Double.MaxValue) //Путь не найден { Way = null; } else { Criterial = criterial; List <long> wayList = GetWay(fromVertex, toVertex, parents); Way = new List <long>(wayList.Count); for (int i = 0; i < wayList.Count; i++) { Way.Add(IDs[wayList[i]]); } Value = matrix[fromVertex, toVertex]; } }
/// <summary> /// Возвращение цены по критерию /// </summary> /// <param name="criterial">Критерий поиска</param> /// <param name="driver">Водитель</param> /// <returns></returns> internal double GetCriterialValue(Main.Criterial criterial, Driver.Driver driver) { switch (criterial) { case Main.Criterial.Length: { return(GetLength(MakeMap.ViewPort.ScaleCoefficient)); } case Main.Criterial.Price: { return(GetPrice(GetLength(MakeMap.ViewPort.ScaleCoefficient), driver)); } case Main.Criterial.Time: { return(GetTime(driver)); } } return(0); }
/// <summary> /// Получение матрицы стоимости /// </summary> /// <param name="parents">Матрица предков</param> /// <param name="arrayOfID">Массив ID вершин (для восстановления не по порядку из коллекции)</param> /// <param name="vertexes">Коллекция вершин</param> /// <param name="edges">Коллекция дуг</param> /// <param name="criterial">Критерий поиска</param> /// <param name="driver">Водитель</param> /// <returns></returns> private double[,] GetMatrixWay(out long[,] parents, out long[] arrayOfID, Vertexes vertexes, Edges edges, Main.Criterial criterial, Driver.Driver driver) { int count = vertexes.GetCountElements(); double[,] array = new double[count, count]; parents = new long[count, count]; arrayOfID = new long[count]; List <Vertex> vertexList = vertexes.List; for (int i = 0; i < count; i++) { for (int j = 0; j < count; j++) { if (i == j) { array[i, j] = 0; } else { Edge edge = GetEdge(vertexList[i], vertexList[j], edges); array[i, j] = (edge != null) ? edge.GetCriterialValue(criterial, driver) : Double.MaxValue; //Текущее значение матрицы = критерий текущей дуги parents[i, j] = i; } } arrayOfID[i] = vertexList[i].ID; } return(array); }