예제 #1
0
        public static void doTruckDelivery(SquareGrid grid, Truck truck, Location start, Location deliveryLocation)
        {
            truck.status = Status.OnMission;
            truck.log.Add(new Log(truck.id,
                                  truck.currentPosition,
                                  ViewModel.orders.Where(x => (x.x == truck.currentPosition.x && x.y == truck.currentPosition.y)).FirstOrDefault()?.address,
                                  truck.time,
                                  truck.status,
                                  "success"));

            var path         = simpleRoute(grid, start, deliveryLocation);
            var pathLength   = path.Count * BaseConstants.PolygonSize;
            var deliveryTime = pathLength / BaseConstants.TruckSpeed + BaseConstants.TruckDropDeliveryTime;

            truck.time           += deliveryTime;
            truck.status          = Status.Ready;
            truck.currentPosition = deliveryLocation;
            var availableDrones = truck.drones.Where(x => x.status.Equals(Status.Available)).ToList();

            foreach (var drone in availableDrones)
            {
                drone.currentPosition = truck.currentPosition;
            }
            truck.log.Add(new Log(truck.id,
                                  truck.currentPosition,
                                  ViewModel.orders.Where(x => (x.x == truck.currentPosition.x && x.y == truck.currentPosition.y)).FirstOrDefault()?.address,
                                  truck.time,
                                  truck.status,
                                  "Delivery finished"));
        }
예제 #2
0
        public static void doDroneDelivery(FSTSPRouting.droneRouteSheet routeSheet, SquareGrid grid)
        {
            List <Location> path = new List <Location>();

            //routeSheet.drone.time += BaseConstants.DroneLoadTime;
            routeSheet.drone.status = Status.OnMission;

            path.AddRange(simpleRoute(grid, routeSheet.start, routeSheet.deliveryPoint));
            var pathLength   = path.Count * BaseConstants.PolygonSize;
            var deliveryTime = pathLength / BaseConstants.DroneSpeed + BaseConstants.DropDeliveryTime;

            routeSheet.drone.currentPosition = routeSheet.deliveryPoint;
            routeSheet.drone.time           += deliveryTime;
            routeSheet.drone.log.Add(new Log(routeSheet.drone.id,
                                             routeSheet.drone.currentPosition,
                                             ViewModel.orders.Where(x => (x.x == routeSheet.drone.currentPosition.x && x.y == routeSheet.drone.currentPosition.y)).FirstOrDefault()?.address,
                                             routeSheet.drone.time,
                                             routeSheet.drone.status,
                                             "Delivery finished"));

            path.Clear();
            path.AddRange(simpleRoute(grid, routeSheet.deliveryPoint, routeSheet.meetingPoint));
            pathLength   = path.Count * BaseConstants.PolygonSize;
            deliveryTime = pathLength / BaseConstants.DroneSpeed;
            routeSheet.drone.currentPosition = routeSheet.meetingPoint;
            routeSheet.drone.time           += deliveryTime;
            routeSheet.drone.status          = Status.Awaitng;
            routeSheet.drone.log.Add(new Log(routeSheet.drone.id,
                                             routeSheet.drone.currentPosition,
                                             ViewModel.orders.Where(x => (x.x == routeSheet.drone.currentPosition.x && x.y == routeSheet.drone.currentPosition.y)).FirstOrDefault()?.address,
                                             routeSheet.drone.time,
                                             routeSheet.drone.status,
                                             "success"));
        }
예제 #3
0
        public static List <Location> simpleRoute(SquareGrid grid, Location start, Location finish)
        {
            List <Location> path  = new List <Location>();
            AStarSearch     astar = new AStarSearch(grid, start, finish);

            path = astar.ReconstructPath(start, finish, astar.cameFrom);

            return(path);
        }
예제 #4
0
        public static void buildUnitRoute(SquareGrid grid, List <Order> GlobalOrders, Truck truck)
        {
            var orders = new List <Order>();

            orders.AddRange(GlobalOrders);
            while (orders.Count() > 0)
            {
                if (Settings.TrafficScore == 0)
                {
                    Truck.adjustTruckSpeed(truck.time);
                }

                if (truck.status.Equals(Status.Ready))
                {
                    var availableDrones = truck.drones.Where(drone => drone.status.Equals(Status.Available)).ToList();
                    var routeSheets     = selectDronesOrders(availableDrones, orders);

                    List <Location> truckRoute = new List <Location>();
                    truckRoute.Add(truck.currentPosition);
                    foreach (var sheet in routeSheets)
                    {
                        sheet.drone.status = Status.Preparing;
                        truckRoute.Add(sheet.meetingPoint);
                    }

                    if (routeSheets.Count() == 0)
                    {
                        truckRoute.Add(new Location(orders.First().x, orders.First().y, 0));
                    }

                    for (int i = 0; i < truckRoute.Count() - 1; i++)
                    {
                        var awaitingDrones = truck.drones.Where(drone => drone.status.Equals(Status.Awaitng) && drone.currentPosition.Equals(truck.currentPosition)).ToList();
                        Vehicle.compareAndUpdateTime(awaitingDrones, truck);
                        Drone.retrieveDrones(truck, awaitingDrones);

                        Truck.doTruckDelivery(ViewModel.groundGrid, truck, truckRoute[i], truckRoute[i + 1]);
                        //Truck.doTruckDelivery(grid, truck, truckRoute[i], truckRoute[i + 1]);
                        var deliveredOrder = orders.Find(order => order.x == truckRoute[i + 1].x && order.y == truckRoute[i + 1].y);
                        orders.Remove(deliveredOrder);

                        foreach (var sheet in routeSheets)
                        {
                            Drone.loadDrones(truck, sheet.drone);
                            Drone.doDroneDelivery(sheet, grid);
                            deliveredOrder = orders.Find(order => order.x == sheet.deliveryPoint.x && order.y == sheet.deliveryPoint.y);
                            orders.Remove(deliveredOrder);
                        }
                        routeSheets.Clear();
                    }
                    Order.sortOrders(ref orders, truck.currentPosition);
                }
            }
        }
예제 #5
0
        public static void loadFromXML(SquareGrid grid, string filename)
        {
            var xdocument = new XmlDocument();

            xdocument.Load(filename);
            var doc = xdocument.DocumentElement;

            int length = 0, width = 0, height = 0;
            var measurements = doc.GetElementsByTagName("Measurements")[0];

            foreach (XmlNode xnode in measurements)
            {
                switch (xnode.Name)
                {
                case "length":
                    length = Int16.Parse(xnode.InnerText);
                    break;

                case "width":
                    width = Int16.Parse(xnode.InnerText);
                    break;

                case "height":
                    height = Int16.Parse(xnode.InnerText);
                    break;
                }
            }
            var newGrid = new SquareGrid(length, width, height);

            var walls = doc.GetElementsByTagName("wall");

            foreach (XmlNode xnode in walls)
            {
                int x = 0, y = 0, z = 0;
                foreach (XmlNode childnode in xnode.ChildNodes)
                {
                    switch (childnode.Name)
                    {
                    case "x":
                        x = Int16.Parse(childnode.InnerText);
                        break;

                    case "y":
                        y = Int16.Parse(childnode.InnerText);
                        break;

                    case "z":
                        z = Int16.Parse(childnode.InnerText);
                        break;
                    }
                }
                newGrid.walls.Add(new Location(x, y, z));
            }
        }
예제 #6
0
        /// <summary>
        /// Starts sequence to execute Travelling Salesman Problem algorithm with A* and a set of conditions
        /// </summary>
        /// <returns></returns>
        public string runTSP(int areaSizeInput, int numberOfCustomers)
        {
            var areaSize = areaSizeInput * 1000 / BaseConstants.PolygonSize; //sets size in nodes

            Depot = new Location(areaSize / 2, areaSize / 2, 0);
            //await generateSpace(areaSize, 1);
            groundGrid = grid;

            generateOrders(areaSize, numberOfCustomers);

            var truck = Truck.generateTruck("singleTruck1", 0, areaSize, Depot);

            var result = string.Empty;

            try
            {
                if (!Settings.DeliveryInterval)
                {
                    Order.sortOrders(ref orders, Depot);
                    doTruck(Depot, orders, truck);
                }
                else
                {
                    var timeClusteredOrders = new List <List <Order> >();
                    var intervals           = new DeliveryIntervals();
                    foreach (var interval in intervals.Intervals)
                    {
                        var ordersInInterval = orders.Where(x => x.dueTime.Equals(interval.Key)).ToList();
                        timeClusteredOrders.Add(ordersInInterval);
                    }

                    for (int i = 0; i < timeClusteredOrders.Count(); i++)
                    {
                        if (truck.time < intervals.Intervals.ToArray()[i].Value.start)
                        {
                            truck.time = intervals.Intervals.ToArray()[i].Value.start;
                        }

                        var timedOrders = timeClusteredOrders.ElementAt(i);
                        Order.sortOrders(ref timedOrders, truck.currentPosition);
                        doTruck(truck.currentPosition, timedOrders, truck);
                    }
                }
            }
            catch (Exception ex)
            {
                return("Unhandled exception during path reconstruction\nPlease try again");
            }

            result = ComposeResult(truck);

            return(result);
        }
예제 #7
0
        public async Task <string> generateSpace(int areaSizeInput, int areaHeight)
        {
            var areaSize = areaSizeInput * 1000 / BaseConstants.PolygonSize;

            grid = new SquareGrid(areaSize, areaSize, areaHeight);
            await Task.Run(() =>
            {
                GridGeneration.fillGrid(grid, areaSize, areaHeight);
            });

            return($"Space of {areaSizeInput} km2 ({areaSize * areaSize * areaHeight} polygons) generated successfully\n");
        }
예제 #8
0
        //public static void fillGrid(SquareGrid grid, int areaSize, int areaHeight)
        //{
        //    bool[,,] obstacles = new bool[areaSize, areaSize, areaHeight];
        //    Random rnd = new Random();
        //    int threshold = 65;

        //    for (int x = 0; x < areaSize; x++)
        //    {
        //        for (int y = 0; y < areaSize; y++)
        //        {
        //            obstacles[x, y, 0] = true;
        //        }
        //    }

        //    for (int x = 0; x < areaSize; x++)
        //    {
        //        if (rnd.Next(100) > threshold)
        //        {
        //            for (int y = 0; y < areaSize; y++)
        //            {
        //                obstacles[x, y, 0] = false;
        //            }
        //        }
        //    }

        //    for (int y = 0; y < areaSize; y++)
        //    {
        //        if (rnd.Next(100) > threshold)
        //        {
        //            for (int x = 0; x < areaSize; x++)
        //            {
        //                obstacles[x, y, 0] = false;
        //            }
        //        }
        //    }

        //    for (int x = 0; x < areaSize; x++)
        //    {
        //        for (int y = 0; y < areaSize; y++)
        //        {
        //            if (obstacles[x, y, 0])
        //                grid.walls.Add(new Location(x, y, 0));
        //        }
        //    }


        //    for (int z = 1; z < areaHeight; z++)
        //    {
        //        for (int x = 0; x < areaSize; x++)
        //        {
        //            for (int y = 0; y < areaSize; y++)
        //            {
        //                if ((rnd.Next(100) > threshold || rnd.Next(100) > 20) && obstacles[x, y, z - 1])
        //                {
        //                    obstacles[x, y, z] = true;
        //                    grid.walls.Add(new Location(x, y, z));
        //                }
        //                else
        //                {
        //                    obstacles[x, y, z] = false;
        //                }
        //            }
        //        }
        //        threshold -= 5;
        //    }
        //}

        public static void fillGrid(SquareGrid grid, int areaSize, int areaHeight)
        {
            //var threshold = 65;
            Random rnd = new Random();

            List <int> xStreets = new List <int>();
            List <int> yStreets = new List <int>();

            defineStreets(xStreets, yStreets, areaSize);

            var watch = new System.Diagnostics.Stopwatch();

            watch.Start();

            for (int x = 0; x < areaSize; x++)
            {
                for (int y = 0; y < areaSize; y++)
                {
                    if (!xStreets.Contains(x) && !yStreets.Contains(y))
                    {
                        grid.walls.Add(new Location(x, y, 0));
                    }
                }
            }



            var increment = 1.0;

            for (int z = 1; z < areaHeight; z++)
            {
                var previousLevelWalls = grid.walls.Where(location => location.z == z - 1).ToList();
                //var newLevelWalls = new List<Location>();
                for (int i = 0; i < previousLevelWalls.Count(); i += (int)Math.Round(increment, MidpointRounding.ToEven))
                {
                    grid.walls.Add(new Location(previousLevelWalls[i].x, previousLevelWalls[i].y, z));
                }
                increment += 0.3;
            }

            watch.Stop();
            var seconds = watch.ElapsedMilliseconds / 1000;

            //saveToXML(grid, "c:\\FSTSP_Files\\grid.xml");
            //loadFromXML(grid, "c:\\FSTSP_Files\\grid.xml");
        }
예제 #9
0
        public async Task <string> generateSpace(int areaSizeInput)
        {
            var areaSize = areaSizeInput * 1000 / BaseConstants.PolygonSize;

            if (grid != null && grid.length == areaSize)
            {
                return($"Space of {areaSizeInput} km2 was already generated\n");
            }

            grid = new SquareGrid(areaSize, areaSize, BaseConstants.areaHeight);

            await Task.Run(() =>
            {
                GridGeneration.fillGrid(grid, areaSize, BaseConstants.areaHeight);
            });


            groundGrid       = new SquareGrid(areaSize, areaSize, 1);
            groundGrid.walls = grid.walls.Where(location => location.z == 0).ToHashSet();

            return($"Space of {areaSizeInput} km2 ({areaSize * areaSize * BaseConstants.areaHeight} polygons) generated successfully\n");
        }
예제 #10
0
        public static void saveToXML(SquareGrid grid, string filename)
        {
            TextWriter writer   = new StreamWriter(filename);
            XDocument  document = new XDocument();

            var Grid = new XElement("Grid", new XAttribute("xsd", "http://www.w3.org/2001/XMLSchema"),
                                    new XAttribute("xsi", "http://www.w3.org/2001/XMLSchema-instance"));

            document.Add(Grid);
            Grid.Add(new XElement("Measurements", new XElement("length", grid.length), new XElement("width", grid.width), new XElement("height", grid.height)));
            var walls = new XElement("Walls");

            Grid.Add(walls);

            foreach (var wall in grid.walls)
            {
                walls.Add(new XElement("wall", new XElement("x", wall.x), new XElement("y", wall.y), new XElement("z", wall.z)));
            }

            document.Save(writer);
            writer.Close();
        }
예제 #11
0
        public static string[] DrawGrid(SquareGrid grid, AStarSearch astar, Location start, Location goal)
        {
            string[] output = new string[4];
            // Печать массива cameFrom
            for (int z = 0; z < 4; z++)
            {
                for (var y = 0; y < 41; y++)
                {
                    for (var x = 0; x < 41; x++)
                    {
                        Location id  = new Location(x, y, z);
                        Location ptr = id;
                        if (!astar.cameFrom.TryGetValue(id, out ptr))
                        {
                            ptr = id;
                        }
                        if (start.x == x && start.y == y && start.z == z) /*Console.Write("\u2191 ");*/ x {
                            ++; output[z] += "S";
                        }
                        if (goal.x == x && goal.y == y && goal.z == z) /*Console.Write("\u2191 ");*/ x {
                            ++; output[z] += "F";
                        }

                        if (grid.walls.Contains(id)) /*Console.Write("##");*/ output {
예제 #12
0
        public static List <Order> generateOrders(SquareGrid grid, Location Depot, int ordersCount, int areaSize, bool intervals = false)
        {
            var weight = 1000;
            //var lightweightOrdersCount = Math.Ceiling(ordersCount * (1 - BaseConstants.LightweightOrdersPercentile));
            var          heavyweightOrdersCount = Math.Ceiling(ordersCount * (1 - ((double)Settings.PrecipitationVolume / 10)));
            Random       rnd        = new Random();
            List <Order> ordersList = new List <Order>();

            while (ordersCount > 0)
            {
                int x, y;
                void generateLocation()
                {
                    switch (BaseConstants.OrdersLocation)
                    {
                    case "center":
                        x = rnd.Next(areaSize / 4, areaSize * 3 / 4);
                        y = rnd.Next(areaSize / 4, areaSize * 3 / 4);
                        break;

                    case "corner":
                        x = rnd.Next(0, areaSize / 4);
                        y = rnd.Next(0, areaSize / 4);
                        break;

                    case "peripheral":
                        x = rnd.Next(areaSize);
                        if (x > areaSize / 4 && x < areaSize / 2)
                        {
                            x -= areaSize / 4;
                        }
                        if (x > areaSize / 2 && x < areaSize * 3 / 4)
                        {
                            x += areaSize / 4;
                        }

                        y = rnd.Next(areaSize);
                        if (y > areaSize / 4 && y < areaSize / 2)
                        {
                            y -= areaSize / 4;
                        }
                        if (y > areaSize / 2 && y < areaSize * 3 / 4)
                        {
                            y += areaSize / 4;
                        }
                        break;

                    default:
                        x = rnd.Next(areaSize);
                        y = rnd.Next(areaSize);
                        break;
                    }
                }

                generateLocation();

                var isWall = true;
                while (isWall)
                {
                    if (grid.walls.Contains(new Location(x, y, 0)))
                    {
                        generateLocation();
                        //x = rnd.Next(areaSize);
                        //y = rnd.Next(areaSize);
                    }
                    else
                    {
                        isWall = false;
                    }
                }

                if (ordersCount < heavyweightOrdersCount)
                {
                    weight = 10000;
                }

                //ordersList.Add(new Order(x, y, rnd.Next(100, 6000), rnd.Next(1, 4)));
                ordersList.Add(new Order(x, y, weight, rnd.Next(1, 4)));
                ordersCount--;
            }
            return(ordersList);
        }