Beispiel #1
0
        public RouteMatrix(IEnumerable <IRoute> routes)
        {
            State   = RouteMatrixState.Process;
            Headers = new MatrixHeaders(routes);
            if (Headers.GetLines().Count() <= 2)
            {
                throw new ArgumentOutOfRangeException(nameof(routes));
            }

            Items = new MatrixValue[Headers.ColumnsCount + 1, Headers.RowsCount + 1];
            foreach (var r in routes)
            {
                var from  = r.From.Line;
                var to    = r.To.Line;
                var coord = Headers.GetCoord(from, to);
                Items[coord.Col, coord.Row] = new MatrixValue(r);
                coord = Headers.GetCoord(to, from);
                Items[coord.Col, coord.Row] = new MatrixValue(r);
            }

            // Добавление бесконечности в пути, соединяющие одну и ту же ветку
            foreach (var line in Headers.GetLines())
            {
                if (Headers.TryGetCoord(line, line, out var coord))
                {
                    Items[coord.Col, coord.Row] = MatrixValue.Infinity;
                }
                else
                {
                    throw new ArgumentException("Набор маршрутов покрывает не все возможные варианты движения");
                }
            }

            Reduction();
        }
Beispiel #2
0
 private RouteMatrix(MatrixHeaders headers, ICollection <IRoute> passedRoutes, int baseMinTimespan, RouteMatrixState state = RouteMatrixState.Process)
 {
     if (baseMinTimespan <= 0)
     {
         throw new ArgumentOutOfRangeException(nameof(baseMinTimespan));
     }
     if (passedRoutes != null)
     {
         _passedRoutes.AddRange(passedRoutes);
     }
     BaseMinTimespan = baseMinTimespan;
     State           = state;
     if (State == RouteMatrixState.IsComplete)
     {
         var len = 0;
         foreach (var r in PassedRoutes)
         {
             len += r.Timespan;
         }
         CurrentMinTimespan = len - BaseMinTimespan;
     }
     else if (State == RouteMatrixState.Process)
     {
         Headers = headers;
         Items   = new MatrixValue[Headers.ColumnsCount + 1, Headers.RowsCount + 1];
     }
     else if (State == RouteMatrixState.Unreachable)
     {
     }
 }
            /// <summary>
            /// Создать копию объекта, удалив колонку и строку
            /// </summary>
            /// <param name="col">Индекс колонки</param>
            /// <param name="row">Индекс строки</param>
            /// <returns>Новый объект заголовка</returns>
            public MatrixHeaders CopyWithoutColRow(int col, int row)
            {
                var result = new MatrixHeaders(this);

                result.Columns.RemoveAt(col);
                result.Rows.RemoveAt(row);

                return(result);
            }
Beispiel #4
0
        /// <summary>
        /// Создать копию матрицы, удалив из неё столбец и строку
        /// </summary>
        /// <param name="coord">Удаляемые строка и столбец</param>
        /// <returns>Копия матрицы</returns>
        public RouteMatrix CopyWithoutColAndRow(MatrixCoord coord)
        {
            // Настройка заголовков строк и столбцов создаваемой матрицы
            MatrixHeaders    newHeaders = null;
            RouteMatrixState newState   = RouteMatrixState.Process;
            List <IRoute>    routes     = null;

            var addedRoute = GetRoute(coord);

            if (CanAddPassedRoute(PassedRoutes, addedRoute))    // Контроль за образованием цикла
            {
                routes = new List <IRoute>(PassedRoutes)
                {
                    addedRoute
                };
                newHeaders = Headers.CopyWithoutColRow(coord.Col, coord.Row);

                if (newHeaders.ColumnsCount == 1 &&
                    newHeaders.RowsCount == 1)
                {
                    var newLinesCount = newHeaders.GetLines().Count();
                    if (newLinesCount == 2)
                    {
                        var fromLine = newHeaders.GetLineByRow(0);
                        var toLine   = newHeaders.GetLineByCol(0);
                        var curCoord = Headers.GetCoord(toLine, fromLine);
                        // Оставшийся последним маршрут достижим
                        if (!Items[curCoord.Col, curCoord.Row].IsInfinity)
                        {
                            var lastRoute = GetRoute(curCoord);
                            routes.Add(lastRoute);

                            newState = RouteMatrixState.IsComplete;
                        }
                        else
                        {
                            newState = RouteMatrixState.Unreachable;
                        }
                    }
                    else
                    {
                        newState = RouteMatrixState.Unreachable;
                    }
                    newHeaders = null;
                }
            }
            else
            {
                newState = RouteMatrixState.Unreachable;
            }


            RouteMatrix result = new RouteMatrix(newHeaders, routes, MinTimespan, newState);

            if (result.State == RouteMatrixState.Process)
            {
                for (int col = 0; col < ColumnsCount; ++col)
                {
                    if (col != coord.Col)
                    {
                        var newCol = result.Headers.GetColByLine(Headers.GetLineByCol(col));

                        for (int row = 0; row < RowsCount; ++row)
                        {
                            if (row != coord.Row)
                            {
                                var newRow = result.Headers.GetRowByLine(Headers.GetLineByRow(row));
                                result.Items[newCol, newRow] = Items[col, row];
                            }
                        }
                    }
                }
                // Устанавливаем элемент [row, col] в бесконечность
                var fromLine = Headers.GetLineByRow(coord.Row);
                var toLine   = Headers.GetLineByCol(coord.Col);
                var infCol   = result.Headers.GetColByLine(fromLine);
                var infRow   = result.Headers.GetRowByLine(toLine);
                if (infCol >= 0 && infRow >= 0)
                {
                    result.Items[infCol, infRow].SetInfinity();
                }

                result.FillMinValuesByRows();
                result.FillMinValuesByCols();
                result.CalcCurrentMinTimespan();
            }

            return(result);
        }
 private MatrixHeaders(MatrixHeaders other)
 {
     Columns = new List <Line>(other.Columns);
     Rows    = new List <Line>(other.Rows);
 }