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(); }
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) { } }
public RouteMatrix(RouteMatrix matrix, MatrixCoord excluded) { BaseMinTimespan = matrix.MinTimespan; _passedRoutes.AddRange(matrix.PassedRoutes); State = RouteMatrixState.Process; Headers = matrix.Headers; Items = new MatrixValue[Headers.ColumnsCount + 1, Headers.RowsCount + 1]; for (int col = 0; col < ColumnsCount; ++col) { for (int row = 0; row < RowsCount; ++row) { Items[col, row] = matrix.Items[col, row]; } } Items[excluded.Col, excluded.Row].SetInfinity(); }
/// <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); }