Exemplo n.º 1
0
        private static void PlaceOptimal(Mnet mainNetwork, RouteUtils.Node[] mcNodes, out int PlaceLayer, out int BaseSize)
        {
            //Расчитать baseSize
            PlaceLayer = 60;
            int xStep = mcNodes.Select(t => t.SizeX).Max() + Dolled;
            int yStep = mcNodes.Select(t => t.SizeY).Max() + Dolled;

            BaseSize = (new int[] { Convert.ToInt32(Math.Sqrt(mcNodes.Length)) * xStep, Convert.ToInt32(Math.Sqrt(mcNodes.Length)) * yStep }).Max() + 60;

            //Разместить порты
            var ports = mainNetwork.nodes.Where(t => t.NodeType.Contains("Port"));
            if (BaseSize < ports.Count() * 5)
            {
                BaseSize = ports.Count()*5 + 60;
            }
            int lastxcoord = 1;
            foreach (var port in ports)
            {
                port.Placed = true;
                port.X = lastxcoord;
                port.Y = 1;
                port.Z = PlaceLayer;
                lastxcoord += mcNodes.FirstOrDefault(t => t.NodeName == port.NodeName).SizeX + Dolled;
            }
            //Расчитать матрицу связоности
            int[,] connectionMatrix = new int[mainNetwork.nodes.Count, mainNetwork.nodes.Count];
            for (int i = 0; i < mainNetwork.nodes.Count; i++)
            {
                for (int j = 0; j < mainNetwork.nodes.Count; j++)
                {
                    connectionMatrix[i, j] = mainNetwork.wires.Where(t => t.SrcName == mainNetwork.nodes[i].NodeName && t.DistName == mainNetwork.nodes[j].NodeName ||
                                                                          t.SrcName == mainNetwork.nodes[j].NodeName && t.DistName == mainNetwork.nodes[i].NodeName).Count();
                }
            }

            //Разместить ноды в ячейки
            var unPlaced = mainNetwork.nodes.Where(t => !t.Placed);
            while (unPlaced.Count() > 0)
            {
                //Поиск нода максимально связанного с установленными
                int[] localConnectionMatrix = new int[mainNetwork.nodes.Count];
                for (int i = 0; i < mainNetwork.nodes.Count; i++)
                {
                    localConnectionMatrix[i] += mainNetwork.wires.Where(t => !mainNetwork.nodes[i].Placed &&
                                                                             (t.SrcName == mainNetwork.nodes[i].NodeName && mainNetwork.nodes.FirstOrDefault(n => n.NodeName == t.DistName).Placed)).Count();
                    localConnectionMatrix[i] += mainNetwork.wires.Where(t => !mainNetwork.nodes[i].Placed &&
                                                                             (t.DistName == mainNetwork.nodes[i].NodeName && mainNetwork.nodes.FirstOrDefault(n => n.NodeName == t.SrcName).Placed)).Count();
                }
                int maxConections = localConnectionMatrix.Max();
                Node nodeToPlace = new Node();
                for (int i = 0; i < mainNetwork.nodes.Count; i++)
                {
                    if (localConnectionMatrix[i] == maxConections)
                    {
                        nodeToPlace = mainNetwork.nodes[i];
                    }
                }
                if (maxConections == 0)
                {
                    nodeToPlace = unPlaced.FirstOrDefault();
                }
                //Поиск места для установки
                int[,] placeMatrix = new int[BaseSize, BaseSize];
                var connectionsa = mainNetwork.wires.Where(k => k.SrcName == nodeToPlace.NodeName).Select(s => mainNetwork.nodes.FirstOrDefault(q => s.DistName == q.NodeName)).Where(l => l.Placed);
                var connectionsb = mainNetwork.wires.Where(k => k.DistName == nodeToPlace.NodeName).Select(s => mainNetwork.nodes.FirstOrDefault(q => s.SrcName == q.NodeName)).Where(l => l.Placed);
                var connections = connectionsa.Union(connectionsb);
                var mcNode = mcNodes.FirstOrDefault(k => k.NodeName == nodeToPlace.NodeName);
                int sizex = mcNode.SizeX + Dolled;
                int sizey = mcNode.SizeY + Dolled;
                var placedNodes = mainNetwork.nodes.Where(t => t.Placed);

                char[,] mask = new char[BaseSize, BaseSize];
                foreach (var node in placedNodes)
                {
                    DrawAtMask(mask, node.X, node.Y, node.McNode.SizeX + 3, node.McNode.SizeY);//При Более близко расположении бывают ошибки
                }

                for (int i = 0; i < BaseSize; i += Step)
                {
                    for (int j = 0; j < BaseSize; j += Step)
                    {
                        //bool collision = placedNodes.Where(t => CheckCollision(t, t.mcNode, i, j, mcNode)).Count() > 0;
                        if (BaseSize > i + sizex + 1 && BaseSize > j + sizey + 1)
                            if (!CheckMaskCollision(mask, nodeToPlace, i, j))
                            {
                                foreach (Node n in connections)
                                {
                                    placeMatrix[i, j] += (n.X - i) * (n.X - i) + (n.Y - j) * (n.Y - j);
                                }
                            }
                    }
                }
                //Установка
                int pcondMin = 90000000;
                int xplace = 0;
                int yplace = 0;
                for (int i = 1; i < BaseSize; i++)
                {
                    for (int j = 1; j < BaseSize; j++)
                    {
                        if (placeMatrix[i, j] < pcondMin && placeMatrix[i, j] > 0)
                        {
                            xplace = i;
                            yplace = j;
                            pcondMin = placeMatrix[i, j];
                        }
                    }
                }
                nodeToPlace.X = xplace;
                nodeToPlace.Y = yplace;
                nodeToPlace.Z = PlaceLayer;
                nodeToPlace.Placed = true;
                Console.ForegroundColor = ConsoleColor.DarkYellow;
                Console.WriteLine("{0} - Осталось:{1}", nodeToPlace.NodeName, unPlaced.Count());
                Console.ForegroundColor = ConsoleColor.White;
            }
            //foreach(Node node in )

            BaseSize += PlaceLayer;
            //Debug Draw Image
            System.Drawing.Image im = new System.Drawing.Bitmap(BaseSize, BaseSize);
            System.Drawing.Graphics Gr = System.Drawing.Graphics.FromImage(im);
            Gr.Clear(System.Drawing.Color.Black);
            foreach (var node in mainNetwork.nodes)
            {
                Gr.DrawRectangle(System.Drawing.Pens.Green, node.X, node.Y, node.McNode.SizeX, node.McNode.SizeY);
            }
            im.Save("1.png");

            //Увеличить плотность
            //throw new NotImplementedException();
        }