Esempio n. 1
0
        /// <summary>
        /// Решить прямую задачу
        /// </summary>
        /// <param name="model">Полная модель</param>
        /// <returns>Прибыль с точек, цена блоков маршрута, результат = прибыль - цена блоков</returns>
        public TracePrice Solve(Model model)
        {
            var trace = TraceBuilder.CalculateTrace(model);

            var income = GetRouteIncome(model, trace.Points);

            return(new TracePrice(income, trace.Price));
        }
Esempio n. 2
0
        private void Run()
        {
            var points = _answer.Points;

            const double epsilon = Constants.RADIUS * 2 / 3;

            var k     = 0; // Индекс текущей точки
            var point = points[k];

            // Список посещённых точек
            var visited = new Dictionary <int, Point>();

            visited[k] = point;

            // Планируемая трасса
            var trace = new List <(string name, Point point, int direction)>();

            trace.Add(("L0", new Point(0, 0, 0), 1));

            int FindNearest()
            {
                var nearest = -1; // Индекс ближайшей соседней точки

                for (var i = 0; i < _answer.Distances[k].Length; i++)
                {
                    if (visited.ContainsKey(i) || point.Equals(points[i]))
                    {
                        continue;
                    }
                    if (nearest == -1 || _answer.Distances[k][i] < _answer.Distances[k][nearest])
                    {
                        nearest = i;
                    }
                }

                return(nearest);
            }

            var mi  = FindNearest();
            var aim = points[mi];

            while (true)
            {
                var(_, last, _) = trace[trace.Count - 1];

                // Список возможных вариантов
                var stepVariants = new List <(string name, int direction)>
                {
                    ("T8", -1),
                    ("T4", -1),
                    ("L1", 1),
                    ("L2", 1),
                    ("L3", 1),
                    ("T4", +1),
                    ("T8", +1),
                };

                var variants = stepVariants.Select(variant =>
                {
                    var nextPoint = TraceBuilder.MakeStep(last, variant.name, variant.direction);
                    return(variant, point: nextPoint, distance: MathFunctions.GetDistanceToPoint(aim, nextPoint));
                }).ToList();

                var lastDistance = MathFunctions.GetDistanceToPoint(aim, last);

                // Выбираем наилучший вариант
                var best = variants[0];
                for (var i = 1; i < variants.Count; i++)
                {
                    if (variants[i].distance < best.distance && variants[i].distance < lastDistance)
                    {
                        best = variants[i];
                    }
                }

                // Добавляем его к маршруту
                trace.Add((best.variant.name, best.point, best.variant.direction));

                _answer.Order.Add(best.variant.name);
                _answer.Topology.Add(new TopologyItem(trace.Count - 2, trace.Count - 1, best.variant.direction));
                OnStepEvent?.Invoke(this, new FinalAnswer(_answer, _checker.Solve(_answer)));

                // Если приблизились достаточно близко к целевой точке - идём к следующей
                if (MathFunctions.GetDistanceToPoint(aim, best.point) < epsilon)
                {
                    k          = mi;
                    point      = points[k];
                    visited[k] = point;
                    mi         = FindNearest();
                    if (mi == -1)
                    {
                        if (k == 0)
                        {
                            break;
                        }
                        mi = 0;
                    }
                    aim = points[mi];
                }
            }
        }