public static WarehouseInputData Create(string path) { var data = new WarehouseInputData(); using (var reader = File.OpenText(path)) { var line = reader.ReadLine().Split(); data.N = int.Parse(line[0]); data.M = int.Parse(line[1]); data.Warehouses = new Warehouse[data.N]; for (int i = 0; i < data.N; i++) { line = reader.ReadLine().Split(); data.Warehouses[i].Id = i; data.Warehouses[i].Cap = int.Parse(line[0]); data.Warehouses[i].S = double.Parse(line[1]); } data.T = new double[data.M,data.N]; data.Consumers = new Consumer[data.M]; for (int i = 0; i < data.M; i++) { line = reader.ReadLine().Split(); data.Consumers[i].Id = i; data.Consumers[i].Demand = int.Parse(line[0]); line = reader.ReadLine().Split(); for (int j = 0; j < data.N; j++) { data.T[i, j] = double.Parse(line[j]); } } } return data; }
public WarehouseSolution Solve(WarehouseInputData data) { var tv = data.N * data.M; var te = data.N + 2 * data.M; _baseA = new double[te, tv]; _baseB = new double[te]; for (int j = 0; j < data.M; j++) { var id = 2 * j; for (int i = 0; i < data.N; i++) { _baseA[id, i * data.M + j] = 1; _baseA[id + 1, i * data.M + j] = -1; } _baseB[id] = 1; _baseB[id + 1] = -1; } for (int i = 0; i < data.N; i++) { var id = 2 * data.M + i; for (int j = 0; j < data.M; j++) { _baseA[id, i * data.M + j] = data.Consumers[j].Demand; } _baseB[id] = data.Warehouses[i].Cap; } _baseC = new double[tv]; for (int i = 0; i < data.N; i++) { for (int j = 0; j < data.M; j++) { _baseC[i * data.M + j] = -data.T[j, i]; } } //var result = _simplexSolver.Simplex(_baseA, _baseB, _baseC); Run(); var result = new int[data.M]; for (int j = 0; j < data.M; j++) { for (int i = 0; i < data.N; i++) { if (_bestResult.Solution[i * data.M + j] > 1 - Eps) { result[j] = i; } } } return new WarehouseSolution { Cost = -_bestResult.Value + data.Warehouses.Sum(w => w.S), Solution = result, SolutionFound = true }; }
private bool UpdateClustersWarehouse(VrpData data, ClustersModel clusters, int v) { var solver = new GreedyHeuristic(); var warehouseData = new WarehouseInputData(); warehouseData.N = v; warehouseData.M = data.N; warehouseData.T = new double[data.N,v]; for (int i = 0; i < data.N; i++) { for (int j = 0; j < v; j++) { warehouseData.T[i, j] = clusters.Centers[j].Dist(data.Customers[i].Point); } } warehouseData.Consumers = data.Customers.Select(c => new Consumer {Demand = c.Demand, Id = c.Id}).ToArray(); warehouseData.Warehouses = new global::Warehouse.Warehouse[v]; for (int i = 0; i < v; i++) { warehouseData.Warehouses[i] = new global::Warehouse.Warehouse {Cap = data.C, Id = i, S = 0}; } var result = solver.Solve(warehouseData); if (result.SolutionFound) { clusters.Color = result.Solution; return true; } return false; }
public WarehouseSolution Solve(WarehouseInputData data) { var n = data.N; var m = data.M; var sortedWarehouses = data.Warehouses.OrderBy(wh => wh.S).ToArray(); var solution = new WarehouseSolution {Cost = 1e30, Solution = new int[m], SolutionFound = false}; var solutionFound = false; for (int mid = 1; mid <= n; mid++) { var links = new List<Link>(mid * m); for (int i = 0; i < mid; i++) { for (int j = 0; j < m; j++) { var link = new Link { WId = sortedWarehouses[i].Id, CId = j, Cost = data.T[j, sortedWarehouses[i].Id] }; links.Add(link); } } links = links.OrderBy(link => (n == 16 && link.CId != 33) ? link.Cost : -1 / link.Cost).ToList(); var cur = new int[n]; var ans = new int[m]; var usage = new bool[n]; for (int i = 0; i < m; i++) { ans[i] = -1; } double cost = 0; foreach (var link in links) { if (ans[link.CId] < 0 && cur[link.WId] + data.Consumers[link.CId].Demand <= data.Warehouses[link.WId].Cap) { ans[link.CId] = link.WId; cur[link.WId] += data.Consumers[link.CId].Demand; cost += data.T[link.CId, link.WId]; if (!usage[link.WId]) { usage[link.WId] = true; cost += data.Warehouses[link.WId].S; } } } var isFeasible = ans.All(x => x >= 0); if (isFeasible) { solutionFound = true; if (cost < solution.Cost) { solution.Cost = cost; solution.Solution = ans; solution.SolutionFound = true; } } } if (!solutionFound) { data.Consumers = data.Consumers.OrderByDescending(c => c.Demand).ToArray(); var cur = new int[n]; var ans = new int[m]; var usage = new bool[n]; var cost = 0.0; var found = true; foreach (var consumer in data.Consumers) { var bestDelta = 0; var besti = -1; for (int i = 0; i < n; i++) { if (cur[i] + consumer.Demand <= data.Warehouses[i].Cap) { var delta = data.Warehouses[i].Cap - cur[i] - consumer.Demand; if (besti < 0 || bestDelta > delta) { bestDelta = delta; besti = i; } } } if (besti < 0) { found = false; break; } cur[besti] += consumer.Demand; ans[consumer.Id] = besti; if (!usage[besti]) { usage[besti] = true; cost += data.Warehouses[besti].S; } cost += data.T[consumer.Id, besti]; } if (found) { solution.Cost = cost; solution.Solution = ans; } } return solution; }