Ejemplo n.º 1
0
        public void DoAlgPrim()
        {
            StringBuilder message = new StringBuilder();
            message.AppendFormat("[date: {0}]\n", DateTime.Now);
            message.AppendFormat("file: {0}\n", mainForm.ctlTabControl.SelectedTab.Text);
            message.AppendLine("--- Prim Algorithm ---");
            Router root;
            if (SelectedElements.Count == 1 && (root = SelectedElements[0] as Router) != null)
            {
                if (Network.CheckNetwork() == 0)
                {
                    message.AppendLine("checking: graph checking ... OK");
                    if (Network.Areas.Count > 1)
                    {
                        message.AppendLine("checking: network is segmented ... YES");
                    }
                    else
                    {
                        message.AppendLine("checking: network is segmented ... NO");
                    }
                    Network.ResetEquipment();

                    Stopwatch stopWatch = Stopwatch.StartNew();
                    AlgPrim algPrim = new AlgPrim(root, Network);
                    stopWatch.Stop();
                    root.Mark = Marks.Prim;
                    foreach (Channel channel in Network.Channels)
                        if (channel.Tree == true)
                            channel.Pen = new Pen(Color.Black, 4);
                    message.AppendFormat("root: R{0}\n", root.Number);
                    message.AppendFormat("area: {0}\n", root.Area.Number);
                    message.AppendFormat("time: {0:00.000} ms\n", (stopWatch.ElapsedTicks * 1000.0) / Stopwatch.Frequency);
                    message.AppendFormat("routers count: {0}\n", root.Area.Routers.Count);
                }
                else
                {
                    message.Append("warning: gaph is not closed!\n" +
                           "execution is stopped.\n");
                }
            }
            else
            {
                message.Append("warning: please select one router!\n" +
                       "execution is stopped.\n");
            }
            UpdateField();
            message.AppendLine("--- End ---");
            message.AppendLine();
            mainForm.ConsoleWrite(message.ToString());
        }
Ejemplo n.º 2
0
        private void DoAlg(Network net, Router root, Double q)
        {
            // 1 этап. Алгоритм Прима
            AlgPrim algPrim = new AlgPrim(root, net);

            // 2 этап. Получение первичных сегментов
            foreach (Router router in net.Routers)
            {
                Port port = Deg(router);
                if (port != null)
                {
                    Area area = new Area(net.Areas.Count);
                    area.AddRouter(port.Owner);
                    if (port.Router.Area == net.MainArea)
                        area.AddRouter(port.Router);
                    else
                        port.Router.Area.AddRouter(router);
                    net.Areas.Add(area);
                }
            }

            // 3 этап. Получение вторичных сегментов
            List<Router> unallocatedRouters;
            while ((unallocatedRouters = GetUnallocatedRouters(net.Routers, net.MainArea)).Count > 0 )
            {
                // список сегментов, к которым могут присоединиться нераспределенные вершины PA
                List<Area> potentialAreas = new List<Area>();
                // список весов ребер, связывающих вершины с их потенциальными сегментами PW
                List<Int32> potentialWeights = new List<Int32>();
                foreach (Router router in unallocatedRouters)
                {
                    // количество сегментов с одинаковой величиной связей
                    Int32 maxConnectValue = 0;
                    // список сегментов с одинаковой величиной связей ECA
                    List<Area> equalConnectAreas = new List<Area>();
                    // список весов ребер, соединяющий вершину с соответствующим сегментом
                    List<Int32> channelWeights = new List<Int32>();
                    foreach (Port port in router.ConnectedPorts)
                    {
                        if (port.Channel.Tree == true && port.Router.Area != net.MainArea && port.Router.Area.Used == false)
                        {
                            Int32 connectCount = ConnectCount(router, port.Router.Area);
                            if (connectCount == maxConnectValue)
                            {
                                // дополнение списка ECA
                                port.Router.Area.Used = true;
                                equalConnectAreas.Add(port.Router.Area);
                                channelWeights.Add(port.Channel.Criterion);
                            }
                            else if (connectCount > maxConnectValue)
                            {
                                // обновление списка ECA
                                foreach (Area area in equalConnectAreas)
                                    area.Used = false;
                                port.Router.Area.Used = true;
                                maxConnectValue = connectCount;
                                equalConnectAreas = new List<Area>() { port.Router.Area };
                                channelWeights = new List<Int32>() { port.Channel.Criterion };
                            }
                        }
                    }
                    /* выбор оптимального сегмента из соседей вершины */
                    Area connectedArea = null;
                    // минимальный вес ребра между сегментом и вершиной
                    Int32 minConn = Const.INF;
                    if (equalConnectAreas.Count > 0)
                    {
                        for (Int32 i = 0; i < equalConnectAreas.Count; i++ )
                        {
                            equalConnectAreas[i].Used = false;
                            if (channelWeights[i] < minConn)
                            {
                                connectedArea = equalConnectAreas[i];
                                minConn = channelWeights[i];
                            }
                        }
                    }
                    // добавление сегмента к списку PA
                    potentialAreas.Add(connectedArea);
                    // добавление веса ребра к списку PW
                    potentialWeights.Add(minConn);
                    /*
                        * ЗАМЕЧАНИЕ 1:
                        * индекс добавленного сегмента и веса ребра
                        * совпадает с индексом текущей нераспределенной вершины
                            * ЗАМЕЧАНИЕ 2:
                            * элемент списка PA может быть null
                    */
                }
                /* определение оптимальной пары сегмент - вершина */
                Area a = potentialAreas[0];
                Router r = unallocatedRouters[0];
                Int32 min = potentialWeights[0];
                for (Int32 i = 1; i < potentialAreas.Count; i++)
                    if (potentialWeights[i] < min)
                    {
                        min = potentialWeights[i];
                        a = potentialAreas[i];
                        r = unallocatedRouters[i];
                    }
                /* добавление вершины к сегменту */
                a.AddRouter(r);
            }

            // 4 этап. Окончательное разбиение
            // список неоптимальных сегментов ( Q < optQ )
            List<Area> suboptimalAreas;
            while ((suboptimalAreas = GetSuboptimalAreas(net.Areas, q)).Count > 0)
            {
                // список сегментов, которые могут быть объединены с неоптимальными сегментами PA
                List<Area> potentialAreas = new List<Area>();
                // список весов ребер, связывающих сегменты PW
                List<Int32> potentialWeights = new List<Int32>();
                foreach (Area area in suboptimalAreas)
                {
                    // количество сегментов с одинаковой величиной связей
                    Int32 maxConnectValue = 0;
                    // список сегментов с одинаковой величиной связей ECA
                    List<Area> equalConnectAreas = new List<Area>();
                    // список весов ребер, соединяющих сегменты
                    List<Int32> channelWeights = new List<Int32>();
                    foreach (Port gateway in area.Gateways)
                    {
                        if (gateway.Channel.Tree == true && gateway.Router.Area.Used == false)
                        {
                            Int32 connectCount = ConnectCount(area, gateway.Router.Area);
                            if (connectCount == maxConnectValue)
                            {
                                // дополнение списка ECA
                                gateway.Router.Area.Used = true;
                                equalConnectAreas.Add(gateway.Router.Area);
                                channelWeights.Add(gateway.Channel.Criterion);
                            }
                            else if (connectCount > maxConnectValue)
                            {
                                // обновление списка ECA
                                foreach (Area ar in equalConnectAreas)
                                    ar.Used = false;
                                gateway.Router.Area.Used = true;
                                maxConnectValue = connectCount;
                                equalConnectAreas = new List<Area>() { gateway.Router.Area };
                                channelWeights = new List<Int32>() { gateway.Channel.Criterion };
                            }
                        }
                    }
                    /* выбор оптимального сегмента из соседей текущего */
                    Area connectedArea = null;
                    // минимальный вес ребра между сегментами
                    Int32 minConn = Const.INF;
                    if (equalConnectAreas.Count > 0)
                    {
                        for (Int32 i = 0; i < equalConnectAreas.Count; i++)
                        {
                            equalConnectAreas[i].Used = false;
                            if (channelWeights[i] < minConn)
                            {
                                connectedArea = equalConnectAreas[i];
                                minConn = channelWeights[i];
                            }
                        }
                    }
                    // добавление сегмента к списку PA
                    potentialAreas.Add(connectedArea);
                    // добавление веса ребра к списку PW
                    potentialWeights.Add(minConn);
                    /*
                        * ЗАМЕЧАНИЕ 3:
                        * индекс добавленного сегмента и веса ребра
                        * совпадает с индексом текущего неоптимального сегмента
                            * ЗАМЕЧАНИЕ 4:
                            * элемент списка PA может быть null
                    */
                }
                /* определение оптимальной пары сегмент - сегмент */
                Area a1 = potentialAreas[0];
                Area a2 = suboptimalAreas[0];
                Int32 min = potentialWeights[0];
                for (Int32 i = 1; i < potentialAreas.Count; i++)
                    if (potentialWeights[i] < min)
                    {
                        min = potentialWeights[i];
                        a1 = potentialAreas[i];
                        a2 = suboptimalAreas[i];
                    }
                /* объединение сегментов */
                a1.Merge(a2);
            }
        }