public static List<List<Potencial>> Potencials(float[,] result, int[,] tariffs) { List<Potencial> u = new List<Potencial>(); u.Add(new Potencial(0, 0)); List<Potencial> v = new List<Potencial>(); List<BasisPoint> points = new List<BasisPoint>(); int basisCount = 0; for (int i = 0; i < result.GetUpperBound(0) + 1; ++i) { for (int j = 0; j < result.GetUpperBound(1) + 1; ++j) { if (!float.IsNaN(result[i, j])) { BasisPoint point = new BasisPoint(i, j); points.Add(point); basisCount++; } } } if (points.Count < (result.GetUpperBound(0) + 1 + result.GetUpperBound(1))) { int x = 0, y = 0; foreach (BasisPoint p in points) { foreach (BasisPoint q in points) { if (p == q) continue; if (p.x == q.x) x++; if (p.y == q.y) y++; } if ((x == 0) && (y == 0)) { points.Add(new BasisPoint(p.x, p.y + 1)); result[p.x, p.y + 1] = 0; break; } } } int t = 0; while (points.Count > 0) { int basis = points.Count; if (t < basis - 1) t++; else t = 0; if (Existence(u, points[t].x)) v.Add(new Potencial(tariffs[points[t].x, points[t].y] - indexValue(u, points[t].x), points[t].y)); else if (Existence(v, points[t].y)) u.Add(new Potencial(tariffs[points[t].x, points[t].y] - indexValue(v, points[t].y), points[t].x)); if ((Existence(v, points[t].y)) && (Existence(u, points[t].x))) points.Remove(points[t]); } List<List<Potencial>> res = new List<List<Potencial>>() { u, v }; return res; }
private static bool turnUp(List<BasisPoint> points, BasisPoint min, BasisPoint qurPoint) { List<BasisPoint> qurPoints = napoln(points); List<BasisPoint> qurStr = new List<BasisPoint>(); foreach (BasisPoint p in qurPoints) { if (p.y == qurPoint.y) qurStr.Add(p); } if (qurStr.Count == 0) return false; foreach (BasisPoint q in qurStr) { qurPoints.Remove(q); } foreach (BasisPoint q in qurStr) { foreach (BasisPoint p in qurPoints) { if (turnDown(qurPoints, min, q)) return true; else continue; } } return false; }
public static float[,] Optimization(float[,] result, int[,] tariffs, List<List<Potencial>> potencials) { List<Delta> delts = new List<Delta>(); for (int i = 0; i < result.GetUpperBound(0) + 1; ++i) { for (int j = 0; j < result.GetUpperBound(1) + 1; ++j) { if (float.IsNaN(result[i, j])) { Delta delta = new Delta(i, j, tariffs[i, j] - (indexValue(potencials[0], i) + indexValue(potencials[1], j))); delts.Add(delta); } else continue; } } a: Delta min = delts[0]; int minCount = 0; foreach (Delta d in delts) { if (d.value < min.value) min = d; } foreach (Delta d in delts) { if (d.value == min.value) minCount++; } if (min.value >= 0) return null; min.zn = "+"; List<BasisPoint> points = new List<BasisPoint>(); for (int i = 0; i < result.GetUpperBound(0) + 1; ++i) { for (int j = 0; j < result.GetUpperBound(1) + 1; ++j) { if (!float.IsNaN(result[i, j])) { BasisPoint point = new BasisPoint(i, j, result[i, j]); points.Add(point); } } } BasisPoint qurPoint = min; List<BasisPoint> cycle = new List<BasisPoint>(); cycle.Add(min); bool turn = false; bool complete = false; bool error = false; while (complete != true) { if (error) { delts.Remove(min); goto a; } List<BasisPoint> qurStr = new List<BasisPoint>(); if (turn == false) { foreach (BasisPoint p in points) { if (p.x == qurPoint.x) qurStr.Add(p); } foreach (BasisPoint q in qurStr) { points.Remove(q); if (q.y == min.y) { q.zn = "-"; cycle.Add(q); complete = true; } } foreach (BasisPoint q in qurStr) { foreach (BasisPoint p in points) { if (q.y == p.y) { if (q.value > 0.0) { if (turnUp(points, min, q)) { qurPoint = q; qurPoint.zn = "-"; cycle.Add(qurPoint); turn = !turn; break; } } else error = true; } } } } else { foreach (BasisPoint p in points) { if (p.y == qurPoint.y) qurStr.Add(p); } foreach (BasisPoint q in qurStr) { points.Remove(q); } foreach (BasisPoint q in qurStr) { foreach (BasisPoint p in points) { if (q.x == p.x) { if (turnDown(points, min, q)) { qurPoint = q; qurPoint.zn = "+"; cycle.Add(qurPoint); turn = !turn; break; } } } } } } List<float> end = new List<float>(); for (int i = 0; i < result.GetUpperBound(0) + 1; ++i) for (int j = 0; j < result.GetUpperBound(1) + 1; ++j) foreach (BasisPoint p in cycle) if ((p.x == i) && (p.y == j) && (p.zn == "-")) end.Add(result[i, j]); for (int i = 0; i < result.GetUpperBound(0) + 1; ++i) for (int j = 0; j < result.GetUpperBound(1) + 1; ++j) foreach (BasisPoint p in cycle) if ((p.x == i) && (p.y == j)) { if (float.IsNaN(result[i, j])) result[i, j] = 0; if (p.zn == "+") result[i, j] += end.Min(); else result[i, j] -= end.Min(); if (result[i, j] == 0) result[i, j] = float.NaN; } return result; }