예제 #1
0
        /// <summary>
        /// Декодировать пути между элементами секций хромосомы.
        /// </summary>
        /// <param name="chromosome">Декодируемая хромосома.</param>
        protected void DecodePathes(TopologyChromosome chromosome)
        {
            try
            {
                // Группируем секции по частям с УСПД и перебираем группы
                foreach (var dadGroup in Sections.GroupBy(q => q.DADPart, new DataAcquisitionSectionPartComparer()))
                {
                    var pathes = new List <TopologyPath>();

                    foreach (var channelGroup in dadGroup.GroupBy(w => w.Channel))  // Группы секций группируем по каналам передачи данных, которые связывают КУ и УСПД
                    {
                        // Находим путь между УСПД и всеми КУ по каждому каналу передачи в группе секций
                        var path = TopologyPathfinder.GetShortestPath(chromosome.CurrentProject.Graph, dadGroup.Key.Vertex, channelGroup.Select(q => q.MCDPart.Vertex), channelGroup.Key);

                        if (path != null)
                        {
                            pathes.AddRange(path);
                        }
                    }

                    Pathes.Add(dadGroup.Key, pathes);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("DecodePathes failed! {0}", ex.Message);
            }
        }
예제 #2
0
        /// <summary>
        /// Проверить, что КУ и УСПД могут связываться по данному КПД, найти путь от КПД до всех КУ и рассчитать его стоимость.
        /// </summary>
        /// <param name="project">Свойства текущего проекта.</param>
        /// <param name="dadPart">Часть секции с УСПД.</param>
        /// <param name="dataChannel">Канал, соединяющий УСПД и КУ.</param>
        /// <param name="connectedMCDs">Соединяемые с УСПД КУ по КПД.</param>
        /// <returns>Стоимость путей от УСПД до КУ по КПД.</returns>
        protected double GetConnectionCost(Project project, DataAcquisitionSectionPart dadPart, MeasurementAndControlSectionPart[] connectedMCDs, DataChannel dataChannel)
        {
            try
            {
                if (connectedMCDs.Any(q => !q.MCD.SendingCommunications.Contains(dataChannel.Communication)))   // Если есть хоть одно КУ, которое не поддерживает канал, то дальше можно не смотреть
                {
                    return(3 * UNACCEPTABLE);
                }

                if (!dadPart.DAD.ReceivingCommunications.Keys.Contains(dataChannel.Communication))              // Если УСПД не поддерживает данный канал, дальше можно не смотреть
                {
                    return(2 * UNACCEPTABLE);
                }

                var dadUsedCommunication = dadPart.DAD.ReceivingCommunications.Single(q => q.Key == dataChannel.Communication);

                // Проверить, что УСПД поддерживает количество подключенных устройств по КПД
                if (connectedMCDs.Length > dadUsedCommunication.Value)
                {
                    return(VERY_BAD * (connectedMCDs.Length - dadUsedCommunication.Value));
                }

                // Найти все пути, соединяющие УСПД и все КУ, присоединённые по данному КПД
                var pathes = TopologyPathfinder.GetShortestPath(project.Graph, dadPart.Vertex, connectedMCDs.Select(q => q.Vertex), dataChannel);

                // Проверить длину пути и проходимость сквозь участки беспроводной связи
                var distance = GetMinDistance(pathes, dataChannel);

                if (distance > dataChannel.MaxRange)
                {
                    return(distance * BAD);                                   // Чем дальше, тем хуже значение фитнес-функции
                }
                return(pathes?.Sum(q => q.GetCost(project)) ?? UNACCEPTABLE); // Вернуть сумму стоимостей всех составных частей пути, если путь не найден, то плохо - высокая стоимость
            }
            catch (Exception ex)
            {
                Console.WriteLine("GetConnectionCost failed! {0}", ex.Message);
                return(10 * UNACCEPTABLE);
            }
        }
예제 #3
0
        /// <summary>
        /// Сгруппировать УСПД одной модели, расположенные на одном участке.
        /// </summary>
        /// <param name="chromosome">Декодириуемая хромосома.</param>
        protected void GroupDADs(TopologyChromosome chromosome)
        {
            try
            {
                var dadSectionPartGroups = Sections
                                           .Select((section, Index) => new { Part = section.DADPart, Index }) // Запоминаем и индекс секции
                                           .GroupBy(q => q.Part.DAD)                                          // Группируем секции с одинаковым УСПД
                                           .Where(q => q.Count() > 1);                                        // Берём те группы, если хоть какие-то УСПД сгруппировали

                foreach (var dadSectionPartGroup in dadSectionPartGroups)
                {
                    // Далее группируем по участкам и берём те группы, где их больше 1 и где они ещё не на одной вершине
                    var regionSectionPartGroups = dadSectionPartGroup
                                                  .GroupBy(q => q.Part.Vertex.Region)
                                                  .Where(q => q.Count() > 1);

                    foreach (var regionSectionPartGroup in regionSectionPartGroups)
                    {
                        // Если все устройства и так уже в одной вершине, пропускаем эту группу
                        var firstVertex = dadSectionPartGroup.FirstOrDefault()?.Part.Vertex;

                        if (firstVertex == null || regionSectionPartGroup.All(q => q.Part.Vertex == firstVertex))
                        {
                            continue;
                        }

                        var dadsBus = TopologyPathfinder.GetShortestPath(   // Находим кратчайший путь
                            chromosome.CurrentProject.Graph,
                            firstVertex,                                    // Из первой вершины в группе
                            regionSectionPartGroup
                            .Select(q => q.Part.Vertex)                     // До остальных вершин в группе
                            .Distinct()                                     // Без повторяющихся вершин и без исходной вершины
                            .Where(q => q != firstVertex),                  // По топологии шина и учитывая только расстояние
                            new DataChannel {
                            ConnectionType = ConnectionType.None, Topology = DataChannelTopology.Bus
                        });

                        // Берём все грани пути и выбираем из них целевые вершины
                        var pathVertices = dadsBus.Where(q => q.Path != null).SelectMany(q => q.Path).Select(q => q.Target).ToList();

                        pathVertices.Add(firstVertex);                                      // И добавляем исходную вершину

                        var minVertexWeight = pathVertices.Min(q => q.LaboriousnessWeight); // Определяем самый малый вес у вершин пути

                        // Находим все вершины с наименьшим весом
                        var minWeightVertices = pathVertices.Where(q => q.LaboriousnessWeight == minVertexWeight);

                        // Выбираем случайно одну вершину из тех, что с наименьшим весом
                        var randomOptimalVertex = minWeightVertices.ElementAt(RandomizationProvider.Current.GetInt(0, minWeightVertices.Count()));

                        // Перемещаем все УСПД, которые ещё не в оптимальной вершине, в эту вершину, чтобы они стали одним УСПД
                        foreach (var sectionPart in regionSectionPartGroup.Where(q => q.Part.Vertex != randomOptimalVertex))
                        {
                            sectionPart.Part.Move(randomOptimalVertex);

                            // Определяем индекс вершины в упорядоченном массиве вершин
                            var index = Array.IndexOf(chromosome.CurrentProject.Graph.VerticesArray, randomOptimalVertex);

                            // Модифицируем хромосому тоже, находим ген позиции УСПД и обновляем индекс новой вершины
                            chromosome.ReplaceGene(sectionPart.Index * TopologyChromosome.GENES_IN_SECTION + 3, new GeneticSharp.Domain.Chromosomes.Gene(index));
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("GroupDADs failed! {0}", ex.Message);
            }
        }