Пример #1
0
        private double GetScore(BuildingProject item, CellType[,] filledCells, MatrixCoordinate inputCoordinate)
        {
            if (inputCoordinate.Row + item.Plan.GetLength(0) > filledCells.GetLength(0) ||
                inputCoordinate.Column + item.Plan.GetLength(1) > filledCells.GetLength(1))
            {
                return(int.MinValue);
            }

            if (!InMatrix(inputCoordinate.Row + item.Plan.GetLength(0) - 1,
                          inputCoordinate.Column + item.Plan.GetLength(1) - 1))
            {
                return(int.MinValue);
            }

            for (int row = 0; row < item.Plan.GetLength(0); row++)
            {
                for (int col = 0; col < item.Plan.GetLength(1); col++)
                {
                    int rowToCheck = inputCoordinate.Row + row;
                    int colToCheck = inputCoordinate.Column + col;

                    if (filledCells[rowToCheck, colToCheck].IsOccupied)
                    {
                        return(int.MinValue);
                    }
                }
            }

            if (item.BuildingType == BuildingType.Residential)
            {
                return(1.0 * GetResidntialScore(item, filledCells, inputCoordinate));
            }
            return(1.0 * GetUtilityScore(item, filledCells, inputCoordinate));
        }
Пример #2
0
 public Load(int droneId, int warehouseId, int productId, int countOfProducts, int time, int endTime, MatrixCoordinate startPosition)
 {
     DroneId         = droneId;
     WarehouseId     = warehouseId;
     ProductId       = productId;
     CountOfProducts = countOfProducts;
     Time            = time;
     EndTime         = endTime;
     StartPosition   = startPosition;
 }
Пример #3
0
        private MatrixCoordinate AddBestProject(CellType[,] filledCells, MatrixCoordinate first, BuildingProject bestProject)
        {
            resId++;
            for (int row = 0; row < bestProject.Plan.GetLength(0); row++)
            {
                for (int col = 0; col < bestProject.Plan.GetLength(1); col++)
                {
                    if (filledCells[row + first.Row, first.Column + col].IsOccupied)
                    {
                        int n = 0;
                    }
                    filledCells[row + first.Row, first.Column + col].IsOccupied   = bestProject.Plan[row, col];
                    filledCells[row + first.Row, first.Column + col].BuildingType = bestProject.BuildingType;

                    filledCells[row + first.Row, first.Column + col].BuildingIndex       = bestProject.Index;
                    filledCells[row + first.Row, first.Column + col].BuildingUniqueIndex = resId;

                    for (int i = -m_Input.MaxDistance; i <= m_Input.MaxDistance; i++)
                    {
                        for (int j = -m_Input.MaxDistance + Math.Abs(i); j <= m_Input.MaxDistance - Math.Abs(i); j++)
                        {
                            int rowToCheck = row + i;
                            int colToCheck = col + i;

                            if (!InMatrix(rowToCheck, colToCheck))
                            {
                                continue;
                            }

                            var cellToCheck = filledCells[rowToCheck, colToCheck];
                            if (!cellToCheck.IsOccupied)
                            {
                                continue;
                            }

                            if (cellToCheck.BuildingType == BuildingType.Utility)
                            {
                                filledCells[row + first.Row, first.Column + col].NearUtilities.Add(cellToCheck.UtilityIndex);
                            }
                            else
                            {
                                if (bestProject.BuildingType == BuildingType.Utility)
                                {
                                    cellToCheck.NearUtilities.Add(bestProject.UtilityType);
                                }
                            }
                        }
                    }
                }
            }

            return(first);
        }
Пример #4
0
        private static MatrixCoordinate[] NewMethod(TextReader reader)
        {
            int numOfBackbones = int.Parse(reader.ReadLine());

            MatrixCoordinate[] coordaintes = new MatrixCoordinate[numOfBackbones];
            for (int i = 0; i < numOfBackbones; i++)
            {
                string line = reader.ReadLine();
                coordaintes[i] = new MatrixCoordinate(line[0], line[1]);
            }

            return(coordaintes);
        }
Пример #5
0
        private static List <MatrixCoordinate> CalculateRouterCoordinates(ProblemInput input, Dictionary <MatrixCoordinate, ScoredCoordinate> scoreDictionary, SortedSet <ScoredCoordinate> set, Cell[,] cells)
        {
            int maxRouters = (int)Math.Ceiling((double)input.StartingBudger / input.RouterPrice);
            List <MatrixCoordinate> coordinates = new List <MatrixCoordinate>();

            for (int i = 0; i < maxRouters; i++)
            {
                var max = set.Max;
                if (max.Score != 0)
                {
                    MatrixCoordinate coordinate = max.Coordinate;
                    coordinates.Add(coordinate);
                    var routerRadius = input.RouterRadius;
                    var notPossible  = GetNotPossibleCells(input, cells, coordinate.Row, coordinate.Column, routerRadius);
                    for (int k = 0; k < notPossible.GetLength(0); k++)
                    {
                        for (int l = 0; l < notPossible.GetLength(1); l++)
                        {
                            if (!notPossible[k, l])
                            {
                                var x = coordinate.Row + k - routerRadius;
                                var y = coordinate.Column + l - routerRadius;
                                if (x >= 0 && x < cells.GetLength(0) && y >= 0 && y < cells.GetLength(1))
                                {
                                    var key = new MatrixCoordinate(x, y);
                                    if (scoreDictionary.TryGetValue(key, out var value))
                                    {
                                        set.Remove(value);
                                        value.Score--;
                                        if (value.Score > 0)
                                        {
                                            set.Add(value);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                else
                {
                    break;
                }
            }

            return(coordinates);
        }
Пример #6
0
        private int GetUtilityScore(BuildingProject item, CellType[,] filledCells, MatrixCoordinate inputCoordinate)
        {
            HashSet <int> nearResidntials  = new HashSet <int>();
            List <int>    nearResidntials2 = new List <int>();

            foreach (var currCoordinate in m_AffectedCoordinates[item])
            {
                if (!InMatrix(currCoordinate.Row + inputCoordinate.Row, currCoordinate.Column + inputCoordinate.Column))
                {
                    continue;
                }

                var cellToCheck = filledCells[currCoordinate.Row + inputCoordinate.Row, currCoordinate.Column + inputCoordinate.Column];
                if (!cellToCheck.IsOccupied)
                {
                    continue;
                }

                if (cellToCheck.BuildingType == BuildingType.Utility)
                {
                    continue;
                }

                if (cellToCheck.NearUtilities.Contains(item.UtilityType))
                {
                    continue;
                }
                if (nearResidntials.Add(cellToCheck.BuildingUniqueIndex))
                {
                    nearResidntials2.Add(cellToCheck.BuildingIndex);
                }
            }

            if (nearResidntials2.Any())
            {
                return(nearResidntials2.Sum(_ => m_Input.BuildingProjects[_].Capacity));
            }
            return(1);
        }
Пример #7
0
        private void TourmenetSolution(ProblemInput input, ProblemOutput output, CellType[,] filledCells)
        {
            List <MatrixCoordinate> possiblePoints = new List <MatrixCoordinate>
            {
                new MatrixCoordinate(0, 0)
            };

            while (possiblePoints.Count != 0)
            {
                MatrixCoordinate first = possiblePoints[0];
                if (first.Row == 99)
                {
                    int n = 0;
                }
                possiblePoints.RemoveAt(0);
                BuildingProject bestProject = GetBestFit(input.BuildingProjects, filledCells, first);
                if (bestProject == null)
                {
                    continue;
                }

                if (output.Buildings.Count == 1700)
                {
                    int r = 0;
                }
                first = AddBestProject(filledCells, first, bestProject);

                possiblePoints.Add(new MatrixCoordinate(first.Row + bestProject.Plan.GetLength(0), first.Column));
                possiblePoints.Add(new MatrixCoordinate(first.Row, first.Column + bestProject.Plan.GetLength(1)));
                possiblePoints.Add(new MatrixCoordinate(first.Row + bestProject.Plan.GetLength(0), first.Column + bestProject.Plan.GetLength(1)));
                output.Buildings.Add(new OutputBuilding()
                {
                    Coordinate = first, ProjectNumber = bestProject.Index
                });
            }
        }
Пример #8
0
 public Warehouse(int columnPosition, int rowPosition, int[] numberOfItemsForProduct, int index) : base(index)
 {
     Coordinate = new MatrixCoordinate(rowPosition, columnPosition);
     NumberOfItemsForProduct = numberOfItemsForProduct;
 }
Пример #9
0
        protected override ProblemOutput Solve(ProblemInput input)
        {
            Dictionary <MatrixCoordinate, ScoredCoordinate> scoreDictionary = new Dictionary <MatrixCoordinate, ScoredCoordinate>();
            SortedSet <ScoredCoordinate> set = new SortedSet <ScoredCoordinate>(new Shit());

            Cell[,] cells     = input.Cells;
            int[,] cellScores = new int[cells.GetLength(0), cells.GetLength(1)];
            for (int i = 0; i < cells.GetLength(0); i++)
            {
                for (int j = 0; j < cells.GetLength(1); j++)
                {
                    if (cells[i, j] == Cell.Traget)
                    {
                        InitScoreMatrix(input, cells, cellScores, i, j);
                    }
                }
            }

            for (int i = 0; i < cellScores.GetLength(0); i++)
            {
                for (int j = 0; j < cellScores.GetLength(1); j++)
                {
                    var coordinate = new MatrixCoordinate(i, j);
                    var cellScore  = cellScores[i, j];
                    if (cellScore != 0)
                    {
                        var item = new ScoredCoordinate {
                            Coordinate = coordinate, Score = cellScore
                        };
                        scoreDictionary.Add(coordinate, item);
                        set.Add(item);
                    }
                }
            }

            int budget = input.StartingBudger;
            List <MatrixCoordinate> coordinates = CalculateRouterCoordinates(input, scoreDictionary, set, cells);

            int cost = 0;
            List <MatrixCoordinate>    routerCoordinates   = new List <MatrixCoordinate>();
            HashSet <MatrixCoordinate> backBoneCoordinates = new HashSet <MatrixCoordinate>();

            foreach (var coordinate in coordinates)
            {
                MatrixCoordinate startingBackbonePosition = input.StartingBackbonePosition;
                cost += input.RouterPrice;

                MatrixCoordinate  backboneCoordinate = coordinate;
                List <Coordinate> coords             = new List <Coordinate>();
                while (!backboneCoordinate.Equals(startingBackbonePosition) && budget > cost)
                {
                    if (backBoneCoordinates.Add(backboneCoordinate))
                    {
                        cost += input.BackBonePrice;
                    }
                    backboneCoordinate = new MatrixCoordinate(backboneCoordinate.Row - Math.Sign(backboneCoordinate.Row - startingBackbonePosition.Row),
                                                              backboneCoordinate.Column - Math.Sign(backboneCoordinate.Column - startingBackbonePosition.Column));
                }

                if (cost > budget)
                {
                    break;
                }
                routerCoordinates.Add(coordinate);
            }

            backBoneCoordinates.Add(input.StartingBackbonePosition);
            return(new ProblemOutput
            {
                BackBoneCoordinates = backBoneCoordinates.ToArray(),
                RouterCoordinates = routerCoordinates.ToArray()
            });
        }
Пример #10
0
        protected override ProblemOutput Solve(ProblemInput input)
        {
            List <Drone> drones = new List <Drone>();

            for (int i = 0; i < input.NumberOfDrones; i++)
            {
                drones.Add(new Drone(i));
            }

            ProblemOutput output = new ProblemOutput();

            foreach (var order in SolverHelper.OrderOrders(input, drones))
            {
                List <Drone> usedDrones = new List <Drone>();

                foreach (var product in order.ProductsInOrder)
                {
                    if (product.Value * input.Products[product.Key].Weight > input.MaxDrownLoad)
                    {
                        // throw new NotSupportedException();
                        break;
                    }

                    Drone     selectedDrone     = null;
                    Warehouse selectedWarehouse = null;
                    int       minTime           = int.MaxValue;
                    foreach (var warehouse in input.Warehouses)
                    {
                        // TODO: Handle drone can't load all items
                        if (warehouse.NumberOfItemsForProduct[product.Key] > product.Value)
                        {
                            foreach (var drone in drones)
                            {
                                var time = drone.CurrentTime +
                                           Math.Ceiling(drone.CurrentPosition.CalcEucledianDistance(warehouse.Coordinate)) + 1 +
                                           Math.Ceiling(warehouse.Coordinate.CalcEucledianDistance(order.Coordinate)) + 1;

                                if (time < minTime && time < input.NumberOfIterations)
                                {
                                    minTime           = (int)time;
                                    selectedDrone     = drone;
                                    selectedWarehouse = warehouse;
                                }
                            }
                        }
                    }

                    if (selectedDrone == null)
                    {
                        SolverHelper.CancelOrders(usedDrones, output);
                        break;
                    }
                    else
                    {
                        usedDrones.Add(selectedDrone);
                        var time = selectedDrone.CurrentTime +
                                   Math.Ceiling(selectedDrone.CurrentPosition.CalcEucledianDistance(selectedWarehouse.Coordinate)) + 1 +
                                   Math.Ceiling(selectedWarehouse.Coordinate.CalcEucledianDistance(order.Coordinate)) + 1;

                        int firstOrderTime = selectedDrone.CurrentTime;
                        MatrixCoordinate firstOrderCoordinate = selectedDrone.CurrentPosition;
                        int lastOrderTime = selectedDrone.CurrentTime - 1 - (int)Math.Ceiling(selectedWarehouse.Coordinate.CalcEucledianDistance(order.Coordinate));
                        selectedDrone.CurrentTime    += (int)time;
                        selectedDrone.CurrentPosition = order.Coordinate;

                        output.Add(new Load(selectedDrone.Index, order.Index, product.Key, product.Value, firstOrderTime, lastOrderTime, firstOrderCoordinate));
                        output.Add(new Deliver(selectedDrone.Index, order.Index, product.Key, product.Value, lastOrderTime, selectedDrone.CurrentTime));
                    }
                }
            }

            return(output);
        }
Пример #11
0
        private int GetResidntialScore(BuildingProject item, CellType[,] filledCells, MatrixCoordinate inputCoordinate)
        {
            // return (int)(100.0 * item.Capacity / item.Plan.GetLength(0) / item.Plan.GetLength(1));

            HashSet <int> nearUtilities = new HashSet <int>();

            foreach (var currCoordinate in m_AffectedCoordinates[item])
            {
                if (!InMatrix(currCoordinate.Row + inputCoordinate.Row, currCoordinate.Column + inputCoordinate.Column))
                {
                    continue;
                }

                var cellToCheck = filledCells[currCoordinate.Row + inputCoordinate.Row, currCoordinate.Column + inputCoordinate.Column];
                if (!cellToCheck.IsOccupied)
                {
                    continue;
                }

                if (cellToCheck.BuildingType == BuildingType.Residential)
                {
                    continue;
                }

                nearUtilities.Add(cellToCheck.UtilityIndex);
            }

            if (nearUtilities.Any())
            {
                return(nearUtilities.Count * item.Capacity);
            }
            return(1);
        }
Пример #12
0
        private BuildingProject GetBestFit(IEnumerable <BuildingProject> orderResidntial, CellType[,] filledCells, MatrixCoordinate inputCoordinate)
        {
            BuildingProject bestResdintial      = null;
            double          bestResidntialScore = int.MinValue;
            object          lockObject          = new object();

            // Parallel.ForEach(orderResidntial, new ParallelOptions() { MaxDegreeOfParallelism = 5 }, item =>
            foreach (var item in orderResidntial)
            {
                double currScore = GetScore(item, filledCells, inputCoordinate);
                //lock (lockObject)
                {
                    if (bestResidntialScore < currScore)
                    {
                        bestResdintial      = item;
                        bestResidntialScore = currScore;
                    }
                }
            }
            //});

            return(bestResdintial);
        }
Пример #13
0
 public Drone(int index) : base(index)
 {
     CurrentPosition = new MatrixCoordinate(0, 0);
 }