/// <summary> /// Solves a partial problem. /// </summary> /// <param name="partProblem">DVRP partial problem to solve.</param> /// <param name="timeout">Timeout for computations.</param> /// <returns>Solution of the given problem.</returns> public DvrpSolution Solve(DvrpPartialProblem partProblem, TimeSpan timeout) { var resultCarsRoutes = new List <int> [_dvrpProblem.VehicleCount]; for (var i = 0; i < _dvrpProblem.VehicleCount; i++) { resultCarsRoutes[i] = new List <int>(); } var min = partProblem.ApproximateResult; var n = _dvrpProblem.Requests.Length; var max = new int[n]; max[0] = -1; var part = partProblem.SetBegin; _timer.Reset(); _timer.Start(); // let's check all the partitions for (ulong i = 0; IsLowerSet(part, partProblem.SetEnd); ++i) { if (_timer.Elapsed.TotalSeconds >= timeout.TotalSeconds) { State = UCCTaskSolver.TaskSolver.TaskSolverState.Timeout; break; } for (var j = 1; j < n; ++j) { if (max[j - 1] < part[j - 1]) { max[j] = part[j - 1]; } else { max[j] = max[j - 1]; } } var p = n - 1; while (part[p] == max[p] + 1) { part[p] = 0; p = p - 1; } part[p] = part[p] + 1; var breaking = false; var cap = new List <int>(); var listOfRoutes = new List <List <int> >(); for (var j = 0; j < part.Length; ++j) { if (listOfRoutes.Count == part[j]) { // With this version of algorthm we assume that one car can do only one ride if (listOfRoutes.Count == _dvrpProblem.VehicleCount) { breaking = true; break; } listOfRoutes.Add(new List <int> { j }); cap.Add(_dvrpProblem.Requests[j].Demand); } else { listOfRoutes[part[j]].Add(j); cap[part[j]] += (_dvrpProblem.Requests[j].Demand); // The road has to be served in one ride if (cap[part[j]] >= -_dvrpProblem.VehicleCapacity) { continue; } breaking = true; var tmp = Math.Max(max[j], part[j]); for (var k = j + 1; k < part.Length; k++) { part[k] = ++tmp; } break; } } // if any of partitions doesn't fulfil the requirements if (breaking) { continue; } double distance = 0; var carsRoutes = new List <int> [_dvrpProblem.VehicleCount]; for (var j = 0; j < listOfRoutes.Count; ++j) { distance += _tspSolver.Solve(listOfRoutes[j], min, out carsRoutes[j]); if (distance < min) { continue; } int k = 0; for (int l = 0; l <= j; l++) { k = Math.Max(listOfRoutes[l][listOfRoutes[l].Count - 1], k); } var tmp = Math.Max(max[k], part[k]); for (k += 1; k < part.Length; k++) { part[k] = ++tmp; } break; } if (min <= distance) { continue; } min = distance; for (var j = 0; j < _dvrpProblem.VehicleCount; j++) { if (carsRoutes[j] == null) { resultCarsRoutes[j] = new List <int>(); } else { resultCarsRoutes[j] = new List <int>(carsRoutes[j]); } } } var routes = new int[_dvrpProblem.VehicleCount][]; for (var i = 0; i < routes.Length; i++) { routes[i] = resultCarsRoutes[i].ToArray(); } _timer.Stop(); return(new DvrpSolution(min, routes)); }
/// <summary> /// Solves a partial problem. /// </summary> /// <param name="partProblem">DVRP partial problem to solve.</param> /// <param name="timeout">Timeout for computations.</param> /// <returns>Solution of the given problem.</returns> public DvrpSolution Solve(DvrpPartialProblem partProblem, TimeSpan timeout) { var resultCarsRoutes = new List<int>[_dvrpProblem.VehicleCount]; for (var i = 0; i < _dvrpProblem.VehicleCount; i++) { resultCarsRoutes[i] = new List<int>(); } var min = partProblem.ApproximateResult; var n = _dvrpProblem.Requests.Length; var max = new int[n]; max[0] = -1; var part = partProblem.SetBegin; _timer.Reset(); _timer.Start(); // let's check all the partitions for (ulong i = 0; IsLowerSet(part, partProblem.SetEnd); ++i) { if (_timer.Elapsed.TotalSeconds >= timeout.TotalSeconds) { State = UCCTaskSolver.TaskSolver.TaskSolverState.Timeout; break; } for (var j = 1; j < n; ++j) { if (max[j - 1] < part[j - 1]) max[j] = part[j - 1]; else max[j] = max[j - 1]; } var p = n - 1; while (part[p] == max[p] + 1) { part[p] = 0; p = p - 1; } part[p] = part[p] + 1; var breaking = false; var cap = new List<int>(); var listOfRoutes = new List<List<int>>(); for (var j = 0; j < part.Length; ++j) { if (listOfRoutes.Count == part[j]) { // With this version of algorthm we assume that one car can do only one ride if (listOfRoutes.Count == _dvrpProblem.VehicleCount) { breaking = true; break; } listOfRoutes.Add(new List<int> { j }); cap.Add(_dvrpProblem.Requests[j].Demand); } else { listOfRoutes[part[j]].Add(j); cap[part[j]] += (_dvrpProblem.Requests[j].Demand); // The road has to be served in one ride if (cap[part[j]] >= -_dvrpProblem.VehicleCapacity) continue; breaking = true; var tmp = Math.Max(max[j], part[j]); for (var k = j + 1; k < part.Length; k++) { part[k] = ++tmp; } break; } } // if any of partitions doesn't fulfil the requirements if (breaking) continue; double distance = 0; var carsRoutes = new List<int>[_dvrpProblem.VehicleCount]; for (var j = 0; j < listOfRoutes.Count; ++j) { distance += _tspSolver.Solve(listOfRoutes[j], min, out carsRoutes[j]); if (distance < min) continue; int k = 0; for (int l = 0; l <= j; l++) { k = Math.Max(listOfRoutes[l][listOfRoutes[l].Count - 1], k); } var tmp = Math.Max(max[k], part[k]); for (k += 1; k < part.Length; k++) { part[k] = ++tmp; } break; } if (min <= distance) continue; min = distance; for (var j = 0; j < _dvrpProblem.VehicleCount; j++) { if (carsRoutes[j] == null) resultCarsRoutes[j] = new List<int>(); else resultCarsRoutes[j] = new List<int>(carsRoutes[j]); } } var routes = new int[_dvrpProblem.VehicleCount][]; for (var i = 0; i < routes.Length; i++) { routes[i] = resultCarsRoutes[i].ToArray(); } _timer.Stop(); return new DvrpSolution(min, routes); }