예제 #1
0
 private Int32 ConnectCount(Area area1, Area area2)
 {
     Int32 connectCount = 0;
     foreach (Port gateway in area1.Gateways)
         if (gateway.Router.Area == area2) connectCount++;
     return connectCount;
 }
        public void DoAlg(int areasCount)
        {
            Area area = new Area();
            area.Number = network.Areas.Count;
            foreach (Router router in network.Areas[0].Routers)
            {
                area.Routers.Add(router);
                router.Area = area;
            }
            network.Areas[0].Routers.Clear();
            network.Areas.Add(area);

            DoBisection(network.Routers, areasCount);

            foreach (Channel channel in network.Channels)
            {
                if (channel.StartRouter.Area == channel.EndRouter.Area)
                {
                    channel.Area = channel.StartRouter.Area;
                    channel.Area.Channels.Add(channel);
                }
                else
                {
                    channel.Area = null;
                }
            }
        }
예제 #3
0
 private Int32 ConnectCount(Router router, Area area)
 {
     Int32 connectCount = 0;
     foreach (Port port in router.ConnectedPorts)
         if (port.Router.Area == area) connectCount++;
     return connectCount;
 }
예제 #4
0
        /// <summary>
        /// Первоначальная инициализация
        /// </summary>
        /// <param name="area">Сетевой сегмент</param>
        public void DoAlg(Area area)
        {
            // Сортировка узлов по удалению от корня дерева кратчайших путей
            area.Routers = area.Routers.OrderBy(r => r.DistancePointer).ToList();
            // установки для корня дерева оптимальных путей
            area.Routers[0].EnterPort = null;

            // Построение резервных маршрутов
            for (Int32 i = 1; i < area.Routers.Count; i++)
            {
                PaveReserveRouts(area.Routers[i]);
            }
        }
예제 #5
0
 /// <summary>
 /// Динамический перерасчет дерева оптимальных маршрутов
 /// в сетевом сегменте
 /// </summary>
 /// <param name="area">Сетевой сегмент</param>
 /// <returns></returns>
 public Boolean Recalculate(Area area)
 {
     foreach (Router router in area.Routers)
     {
         foreach (Port port in router.ConnectedPorts)
         {
             if (port.Router.Area == area && port.Router.DistancePointer > 0)
             {
                 if (port == router.EnterPort)
                 {
                     port.OppositePort.Distance = Const.INF;
                     port.OppositePort.Route.Clear();
                 }
                 else
                 {
                     port.OppositePort.Distance = router.DistancePointer + port.Channel.Criterion;
                     port.OppositePort.Route.Clear();
                     port.OppositePort.Route.AddRange(router.MainRoute);
                     port.OppositePort.Route.Add(port);
                     if (port.OppositePort == port.Router.EnterPort)
                     {
                         Int32 dist = port.Router.ConnectedPorts[0].Distance;
                         foreach (Port p in port.Router.ConnectedPorts)
                         {
                             if (p.Distance < dist)
                             {
                                 dist = p.Distance;
                                 port.Router.EnterPort = p;
                             }
                         }
                     }
                 }
                 if (port.OppositePort.Distance < port.Router.DistancePointer)
                 {
                     set.Add(new PairRoutes(port.Router.EnterPort.Route, port.OppositePort.Route));
                     //set.Add(CreateRoute(port.Router.EnterPort.Route));
                     //set.Add(CreateRoute(port.Route));
                     port.Router.EnterPort = port.OppositePort;
                     port.Router.DistancePointer = port.Router.EnterPort.Distance;
                     port.Router.MainRoute.Clear();
                     port.Router.MainRoute.AddRange(port.Router.EnterPort.Route);
                     return false;
                 }
                 port.Router.DistancePointer = port.Router.EnterPort.Distance;
                 port.Router.MainRoute.Clear();
                 port.Router.MainRoute.AddRange(port.Router.EnterPort.Route);
             }
         }
     }
     return true;
 }
예제 #6
0
 // конструктор
 public Settings(Double q, List<Area> areas, Int32 changesCount, 
                 Int32 limit, Area areaPointer, Int32 segCount, Boolean auto,
                 Boolean fullMesh, Boolean autoWeight, Boolean autoPortName)
 {
     InitializeComponent();
     cbArea.DataSource = areas;
     txtValue.Text = q.ToString();
     txtChangesCount.Text = changesCount.ToString();
     txtLimit.Text = limit.ToString();
     txtSegmentsCount.Text = segCount.ToString();
     rbtnAuto.Checked = auto;
     ckAutoWeight.Checked = autoWeight;
     ckFullMesh.Checked = fullMesh;
     if (areas.Contains(areaPointer) == true)
         cbArea.SelectedItem = areaPointer;
 }
예제 #7
0
 /// <summary>
 /// Динамический перерасчет дерева оптимальных маршрутов
 /// в сетевом сегменте
 /// </summary>
 /// <param name="area">Сетевой сегмент</param>
 /// <returns></returns>
 public Boolean Recalculate(Area area)
 {
     foreach (Router router in area.Routers)
     {
         foreach (Port port in router.ConnectedPorts)
         {
             if (port.Router.Area == area && port.Router.DistancePointer > 0)
             {
                 if (port == router.EnterPort)
                 {
                     port.OppositePort.Distance = Const.INF;
                 }
                 else
                 {
                     port.OppositePort.Distance = router.DistancePointer + port.Channel.Criterion;
                     if (port.OppositePort == port.Router.EnterPort)
                     {
                         Int32 dist = port.Router.EnterPort.Distance;
                         foreach (Port p in port.Router.ConnectedPorts)
                         {
                             if (p.Distance < dist)
                             {
                                 dist = p.Distance;
                                 port.Router.EnterPort = p;
                             }
                         }
                     }
                 }
                 if (port.OppositePort.Distance < port.Router.DistancePointer)
                 {
                     set.Add(new ChannelsPair(port.Router.EnterPort.Channel, port.Channel));
                     port.Router.EnterPort = port.OppositePort;
                     port.Router.DistancePointer = port.Router.EnterPort.Distance;
                     return false;
                 }
                 port.Router.DistancePointer = port.Router.EnterPort.Distance;
             }
         }
     }
     return true;
 }
        private void DoBisection(List<Router> routers, int areasCount)
        {
            int diameter = AlgDiameter.DoAlg(routers);
            Router tmpRouter = null;
            foreach (Router router in routers)
            {
                foreach (Router r in routers)
                {
                    r.DistancePointer = Const.INF;
                    r.Used = false;
                }
                router.DistancePointer = 0;
                tmpRouter = router;
                for (int i = 0; i < routers.Count; i++)
                {
                    foreach (Port port in tmpRouter.ConnectedPorts)
                    {
                        if ((port.Router.DistancePointer > tmpRouter.DistancePointer + 1) && (port.Router.Used == false))
                        {
                            port.Router.DistancePointer = tmpRouter.DistancePointer + 1;
                        }
                    }
                    tmpRouter.Used = true;
                    int min = Const.INF;
                    foreach (Router r in routers)
                    {
                        if ((r.DistancePointer < min) && (r.Used == false))
                        {
                            tmpRouter = r;
                            min = r.DistancePointer;
                        }
                    }
                }

                if (tmpRouter.DistancePointer == diameter)
                {
                    break;
                }
            }

            Area area = new Area();
            area.Number = network.Areas.Count;
            network.Areas.Add(area);
            List<Router> newArea = new List<Router>();
            foreach (Router router in routers)
            {
                if (router.DistancePointer < diameter / 2 + 1)
                {
                    newArea.Add(router);
                }
            }

            foreach (Router router in newArea)
            {
                router.Area.Routers.Remove(router);
                network.Areas[network.Areas.Count - 1].Routers.Add(router);
                router.Area = network.Areas[network.Areas.Count - 1];
            }

            if ((areasCount / 2 > 1) && (network.Areas[network.Areas.Count - 1].Routers.Count > 2) && (network.Areas[network.Areas.Count - 2].Routers.Count > 2))
            {
                DoBisection(network.Areas[network.Areas.Count - 1].Routers, areasCount / 2);
                DoBisection(network.Areas[network.Areas.Count - 3].Routers, areasCount / 2);
            }
        }
예제 #9
0
        // событие: пункт Величиа Связности выбран
        private void menuOptionsSettings_Click(object sender, EventArgs e)
        {
            Settings settings = new Settings(Q, this.CurrentField.Network.Areas, changeCount, limit, areaPointer,
                                             SegmentsCount, autoRecalculate, FullMesh, AutoWeight, AutoPortName);

            if (settings.ShowDialog(this) == DialogResult.OK)
            {
                Q = settings.Q;
                areaPointer = settings.AreaPointer;
                changeCount = settings.ChangeCount;
                limit = settings.Limit;
                SegmentsCount = settings.SegmentsCount;
                autoRecalculate = settings.Auto;
                FullMesh = settings.FullMesh;
                AutoWeight = settings.AutoWeight;
                AutoPortName = settings.AutoPortName;
                lblQ.Text = String.Format("   Q: {0:0.##}", Q);
            }
        }
예제 #10
0
 public void UpdateGraphics(Area area)
 {
     Pen grayPen = new Pen(Color.Gray, 1);
     Pen areaPen = new Pen(area.SpecChannelColor, 4);
     foreach (Channel channel in area.Channels)
         channel.Pen = grayPen;
     foreach (Router router in area.Routers)
     {
         foreach (Port port in router.ConnectedPorts)
             if (router.DistancePointer - port.Channel.Criterion == port.Router.DistancePointer && port.Router.Area == area)
             {
                 port.Channel.Pen = areaPen;
                 break;
             }
         if (router.DistancePointer == 0)
             router.Mark = Marks.Dejkstra;
     }
 }
예제 #11
0
 public void ResetReserve(Area resetedArea)
 {
     foreach (Router router in resetedArea.Routers)
     {
         router.Grade = Const.INF;
         router.Open = true;
     }
 }
예제 #12
0
        public void ResetEquipment(Area resetedArea)
        {
            // исходные установки узлов связи
            foreach (Router router in resetedArea.Routers)
            {
                router.DistancePointer = Const.INF;
                router.Mark = Marks.None;
                router.Used = false;
                foreach (Port port in router.ConnectedPorts)
                {
                    port.Distance = Const.INF;
                    port.Route.Clear();
                }
            }

            // исходные установки каналов связи
            Pen pen = new Pen(Color.Gray, 1);
            foreach (Channel channel in resetedArea.Channels)
            {
                channel.Pen = pen;
                channel.Tree = false;
            }
        }
예제 #13
0
        public List<Int32> MultiRePairSwitch(Area area, Int32 changesCount, Int32 limit)
        {
            List<int> changesSet = new List<int>();
            AlgPairSwitch algPairSwitch = new AlgPairSwitch();
            StringBuilder message = new StringBuilder();
            message.AppendFormat("[date: {0}]\n", DateTime.Now);
            message.AppendFormat("file: {0}\n", mainForm.ctlTabControl.SelectedTab.Text);
            message.AppendLine("--- Pair Shifts Algorithm: Recalculate ---");

            Stopwatch stopWatch = Stopwatch.StartNew();
            Random rnd = new Random();
            for (int i = 0; i < changesCount; i++)
            {
                area.Channels[rnd.Next(area.Channels.Count - 2)].Criterion = 1 + rnd.Next(limit);
                while (algPairSwitch.Recalculate(area) == false) { }
                changesSet.Add(algPairSwitch.Set.Count);
                algPairSwitch.Set.Clear();
            }
            stopWatch.Stop();

            foreach (Channel channel in area.Channels)
            {
                channel.ChangeCriterion(mainForm.Criterion);
            }

            mainForm.AddPairOperationResult(changesSet, mainForm.ctlTabControl.SelectedTab.Text, area.Number, "Pair Switch", area.Routers.Count);
            message.AppendFormat("time: {0:00.000} ms\n", (stopWatch.ElapsedTicks * 1000.0) / Stopwatch.Frequency);
            UpdateField();
            message.AppendLine("--- End ---");
            message.AppendLine();
            mainForm.ConsoleWrite(message.ToString());

            return changesSet;
        }
예제 #14
0
 public void Merge(Area area)
 {
     while (area.Routers.Count > 0)
         AddRouter(area.Routers[0]);
 }
예제 #15
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);
            }
        }
예제 #16
0
 private List<Router> GetUnallocatedRouters(List<Router> routers, Area mainArea)
 {
     List<Router> unallocatedRouters = new List<Router>();
     foreach (Router router in routers)
         if (router.Area == mainArea)
             unallocatedRouters.Add(router);
     return unallocatedRouters;
 }
예제 #17
0
 public void ResetChannels(Area resetedArea)
 {
     // исходные установки каналов связи
     Pen pen = new Pen(Color.Gray, 1);
     foreach (Channel channel in Channels)
     {
         channel.Pen = pen;
         channel.Tree = false;
     }
 }
예제 #18
0
        // получение списка вершин, составляющих путь между двумя исходными вершинами
        private void PaveRoute(Area startArea, Area endArea, int position)
        {
            /* Поиск маршрута по алгоритму Дейкстры */
            startArea.DistancePointer = 0;
            Area tmpArea = startArea;

            while (tmpArea != endArea)
            {
                foreach (Port port in tmpArea.Gateways)
                {
                    if ((port.Router.Area.DistancePointer > (tmpArea.DistancePointer + port.Channel.Criterion)) &&
                        (port.Router.Area.Used == false))
                    {
                        port.Router.Area.DistancePointer = tmpArea.DistancePointer + port.Channel.Criterion;
                    }
                }
                tmpArea.Used = true;
                int min = Const.INF;
                foreach (Area area in network.Areas)
                {
                    lab += 1;
                    if ((area.DistancePointer < min) && (area.Used == false))
                    {
                        min = area.DistancePointer;
                        tmpArea = area;
                    }
                }
            }

            /* Построение найденного маршрута */
            tmpArea = endArea;
            while (tmpArea != startArea)
            {
                foreach (Port port in tmpArea.Gateways)
                {
                    if (port.Router.Area.DistancePointer == tmpArea.DistancePointer - port.Channel.Criterion)
                    {
                        if (port.Router == port.Channel.StartRouter)
                        {
                            routeRouters.Insert(position, port.Channel.EndRouter);
                            routeRouters.Insert(position, port.Channel.StartRouter);
                        }
                        else
                        {
                            routeRouters.Insert(position, port.Channel.StartRouter);
                            routeRouters.Insert(position, port.Channel.EndRouter);
                        }

                        tmpArea = port.Router.Area;
                        routeChannels.Add(port.Channel);
                        break;
                    }
                }
            }
        }