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); } }
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); }
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); }
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); }
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); } }
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); } }