Пример #1
0
    public AutoroutingMap(AutoroutingMap map)
    {
        Width  = map.Width;
        Height = map.Height;

        tiles = new AutoroutingTile[Width, Height];

        for (int y = 0; y < Height; y++)
        {
            for (int x = 0; x < Width; x++)
            {
                tiles[x, y] = new AutoroutingTile(x, y);

                tiles[x, y].Cost = map.tiles[x, y].Cost;
            }
        }

        foreach (AutoroutingNet n in map.nets)
        {
            AutoroutingNet autoroutingNet = new AutoroutingNet();
            foreach (AutoroutingTile t in n.Tiles)
            {
                autoroutingNet.Tiles.Add(tiles[t.X, t.Y]);
                tiles[t.X, t.Y].Net = autoroutingNet;
            }
            autoroutingNet.Start = tiles[n.Start.X, n.Start.Y];
            autoroutingNet.End   = tiles[n.End.X, n.End.Y];
            nets.Add(autoroutingNet);
        }
    }
Пример #2
0
    static List <Conveyor> GetNetsInTheWay(Map originalMap, Conveyor netToRoute, out bool routingComplete)
    {
        AutoroutingMap map = new AutoroutingMap(originalMap);
        AutoroutingNet net = new AutoroutingNet();

        net.Start = map.tiles[netToRoute._start.X, netToRoute._start.Y];
        net.End   = map.tiles[netToRoute._end.X, netToRoute._end.Y];

        List <AutoroutingNet> netIdsInTheWay = new List <AutoroutingNet>();

        var autorouteResult = Autoroute(map, net, netIdsInTheWay);

        routingComplete = autorouteResult != null;

        List <Conveyor> ret = netIdsInTheWay.Select(x => x.originalConveyor).ToList();

        foreach (Conveyor c in originalMap._conveyors)
        {
            if (c == netToRoute)
            {
                continue;
            }

            if (c.GetOccupiedTiles().Where(x => x == netToRoute._start || x == netToRoute._end).Count() > 0)
            {
                ret.Add(c);
            }
        }

        return(ret);
    }
Пример #3
0
    static List <Point> Autoroute(AutoroutingMap map, AutoroutingNet net, List <AutoroutingNet> netIdsInTheWay = null)
    {
        Func <Point, float> costEvaluator = delegate(Point to)
        {
            if (to.X == net.End.X && to.Y == net.End.Y || to.X == net.Start.X && to.Y == net.Start.Y)
            {
                return(1);
            }
            else if (map.tiles[to.X, to.Y].Net != null)
            {
                if (netIdsInTheWay != null && !netIdsInTheWay.Contains(map.tiles[to.X, to.Y].Net))
                {
                    netIdsInTheWay.Add(map.tiles[to.X, to.Y].Net);
                }

                return(float.PositiveInfinity);
            }
            else
            {
                return(map.tiles[to.X, to.Y].Cost);
            }
        };

        if (net.Start.Net != null && net.Start.Net != net)
        {
            return(null);
        }
        if (net.End.Net != null && net.End.Net != net)
        {
            return(null);
        }

        net.Start.Net = null;
        net.End.Net   = null;

        var aStarResult = CornersReductedAStar.Find(map.Width, map.Height, costEvaluator, net.Start.X, net.Start.Y, net.End.X, net.End.Y);

        if (aStarResult != null)
        {
            foreach (Point p in aStarResult)
            {
                map.tiles[p.X, p.Y].Net = net;
            }
        }

        return(aStarResult);
    }
Пример #4
0
    public int RipupNet(AutoroutingNet net)
    {
        int removals = System.Math.Max(0, net.Tiles.Count - 2);

        while (net.Tiles.Count > 2)
        {
            net.Tiles[1].Net = null;
            net.Tiles.RemoveAt(1);
        }

        net.Start.Net = net;
        net.End.Net   = net;

        net.Tiles.Clear();
        net.Tiles.Add(net.Start);
        net.Tiles.Add(net.End);

        return(removals);
    }
Пример #5
0
    public AutoroutingMap(Map map)
    {
        Width  = map.Width;
        Height = map.Height;

        tiles = new AutoroutingTile[Width, Height];
        for (int y = 0; y < Height; y++)
        {
            for (int x = 0; x < Width; x++)
            {
                tiles[x, y]      = new AutoroutingTile(x, y);
                tiles[x, y].Cost = 1;
            }
        }

        foreach (Machine m in map.Machines)
        {
            foreach (Point p in m.GetOccupiedTiles())
            {
                tiles[p.X, p.Y].Cost = Single.PositiveInfinity;
            }
        }

        foreach (Conveyor n in map._conveyors)
        {
            AutoroutingNet autoroutingNet = new AutoroutingNet();
            foreach (ConveyorSegment t in n._segments)
            {
                foreach (Point p in t._start.GetPointsTo(t._end))
                {
                    autoroutingNet.Tiles.Add(tiles[p.X, p.Y]);
                    tiles[p.X, p.Y].Net = autoroutingNet;
                }
            }
            autoroutingNet.Start            = tiles[n._start.X, n._start.Y];
            autoroutingNet.End              = tiles[n._end.X, n._end.Y];
            autoroutingNet.originalConveyor = n;
            nets.Add(autoroutingNet);
        }
    }
Пример #6
0
    static Dictionary <Conveyor, List <Point> > GetAutoroutingSolution(Map originalMap, Conveyor originalNet)
    {
        //originalMap.Remove(originalNet);


        System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
        stopwatch.Start();

        bool            autorouteSuccess = false;
        List <Conveyor> netIdsInTheWay   = GetNetsInTheWay(originalMap, originalNet, out autorouteSuccess);

        if (netIdsInTheWay.Contains(null))
        {
        }
        int bestCost = Int32.MaxValue;

        Conveyor[]           bestPermutation = null;
        List <List <Point> > bestRouting     = null;

        List <Conveyor> netsToPermute = new List <Conveyor>();

        netsToPermute.AddRange(netIdsInTheWay);
        netsToPermute.Add(originalNet);

        Parallel.ForEach <IEnumerable <Conveyor> >(netsToPermute.GetPermutations(), permutation =>
        {
            if (stopwatch.ElapsedMilliseconds >= 50 && (bestCost < Int32.MaxValue))
            {
                return;
            }
            else if (stopwatch.ElapsedMilliseconds >= 500)
            {
                return;
            }

            AutoroutingMap possibleMap = new AutoroutingMap(originalMap);

            AutoroutingNet originalNet2 = new AutoroutingNet();
            originalNet2.Start          = possibleMap.tiles[originalNet._start.X, originalNet._start.Y];
            originalNet2.End            = possibleMap.tiles[originalNet._end.X, originalNet._end.Y];

            foreach (Conveyor x in netIdsInTheWay)
            {
                possibleMap.RipupNet(x);
            }
            possibleMap.RipupNet(originalNet2);

            int cost = 0;

            List <List <Point> > routing = new List <List <Point> >();

            foreach (Conveyor n in permutation)
            {
                List <Point> result = Autoroute(possibleMap, possibleMap.tiles[n._start.X, n._start.Y].Net);

                if (result == null)
                {
                    return; //Bad permutation, can't route everything
                }
                routing.Add(result);
                cost += result.Count;
            }

            if (cost < bestCost)
            {
                bestCost        = cost;
                bestRouting     = routing;
                bestPermutation = permutation.ToArray();
            }
        });

        Dictionary <Conveyor, List <Point> > ret = new Dictionary <Conveyor, List <Point> >();

        if (bestCost != Int32.MaxValue)
        {
            for (int i = 0; i < bestPermutation.Length; i++)
            {
                if (bestPermutation[i] == originalNet)
                {
                    ret.Add(originalNet, bestRouting[i]);
                }
                else
                {
                    ret.Add(bestPermutation[i], bestRouting[i]);
                }
            }

            return(ret);
        }
        else
        {
            return(null);
        }
    }