import java.util.Arrays;
class TransportationProblem {
private static final double INFINITY
= Double.
MAX_VALUE;
public static void main
(String[] args
) { // Problem data
String[] canneries
= {"Bellingham",
"Eugene",
"Albert_Lea"}; String[] warehouses
= {"Sacramento",
"Salt_Lake",
"Rapid_City",
"Albuquerque"};
int[] supply = {75, 125, 100};
int[] demand = {80, 65, 70, 85};
double[][] originalCost = {
{464, 513, 654, 867},
{352, 416, 690, 791},
{995, 682, 388, 685}
};
// Create a working copy of the cost matrix
double[][] workingCost = new double[originalCost.length][];
for (int i = 0; i < originalCost.length; i++) {
workingCost
[i
] = Arrays.
copyOf(originalCost
[i
], originalCost
[i
].
length); }
// Solve using Vogel's approximation method
double[][] solution = solveTransportation(supply, demand, workingCost);
// Print solution using original costs
printSolution(canneries, warehouses, solution, originalCost);
}
public static double[][] solveTransportation(int[] supply, int[] demand, double[][] cost) {
int m = supply.length;
int n = demand.length;
double[][] solution = new double[m][n];
int[] s
= Arrays.
copyOf(supply, m
); int[] d
= Arrays.
copyOf(demand, n
);
while (true) {
int[] cell = findNextCell(cost, s, d);
if (cell == null) break;
int i = cell[0], j = cell[1];
double amount
= Math.
min(s
[i
], d
[j
]); solution[i][j] = amount;
s[i] -= amount;
d[j] -= amount;
if (s[i] == 0) {
for (int k = 0; k < n; k++) cost[i][k] = INFINITY;
}
if (d[j] == 0) {
for (int k = 0; k < m; k++) cost[k][j] = INFINITY;
}
}
return solution;
}
private static int[] findNextCell(double[][] cost, int[] s, int[] d) {
double minCost = INFINITY;
int[] cell = null;
for (int i = 0; i < cost.length; i++) {
if (s[i] == 0) continue;
for (int j = 0; j < cost[0].length; j++) {
if (d[j] == 0) continue;
if (cost[i][j] < minCost) {
minCost = cost[i][j];
cell = new int[]{i, j};
}
}
}
return cell;
}
public static void printSolution
(String[] sources,
String[] destinations,
double[][] solution, double[][] cost) {
System.
out.
println("Transportation Solution:"); double totalCost = 0;
for (int i = 0; i < solution.length; i++) {
for (int j = 0; j < solution[0].length; j++) {
if (solution[i][j] > 0) {
double costAmount = solution[i][j] * cost[i][j];
System.
out.
printf("%-10s → %-12s: %6.1f units (Cost: $%8.1f)%n",
sources[i], destinations[j],
solution[i][j], costAmount);
totalCost += costAmount;
}
}
}
System.
out.
printf("%nTotal Transportation Cost: $%.1f%n", totalCost
); }
}
aW1wb3J0IGphdmEudXRpbC5BcnJheXM7CgpjbGFzcyBUcmFuc3BvcnRhdGlvblByb2JsZW0gewogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgZG91YmxlIElORklOSVRZID0gRG91YmxlLk1BWF9WQUxVRTsKICAgIAogICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nW10gYXJncykgewogICAgICAgIC8vIFByb2JsZW0gZGF0YQogICAgICAgIFN0cmluZ1tdIGNhbm5lcmllcyA9IHsiQmVsbGluZ2hhbSIsICJFdWdlbmUiLCAiQWxiZXJ0X0xlYSJ9OwogICAgICAgIFN0cmluZ1tdIHdhcmVob3VzZXMgPSB7IlNhY3JhbWVudG8iLCAiU2FsdF9MYWtlIiwgIlJhcGlkX0NpdHkiLCAiQWxidXF1ZXJxdWUifTsKICAgICAgICAKICAgICAgICBpbnRbXSBzdXBwbHkgPSB7NzUsIDEyNSwgMTAwfTsKICAgICAgICBpbnRbXSBkZW1hbmQgPSB7ODAsIDY1LCA3MCwgODV9OwogICAgICAgIAogICAgICAgIGRvdWJsZVtdW10gb3JpZ2luYWxDb3N0ID0gewogICAgICAgICAgICB7NDY0LCA1MTMsIDY1NCwgODY3fSwKICAgICAgICAgICAgezM1MiwgNDE2LCA2OTAsIDc5MX0sCiAgICAgICAgICAgIHs5OTUsIDY4MiwgMzg4LCA2ODV9CiAgICAgICAgfTsKICAgICAgICAKICAgICAgICAvLyBDcmVhdGUgYSB3b3JraW5nIGNvcHkgb2YgdGhlIGNvc3QgbWF0cml4CiAgICAgICAgZG91YmxlW11bXSB3b3JraW5nQ29zdCA9IG5ldyBkb3VibGVbb3JpZ2luYWxDb3N0Lmxlbmd0aF1bXTsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG9yaWdpbmFsQ29zdC5sZW5ndGg7IGkrKykgewogICAgICAgICAgICB3b3JraW5nQ29zdFtpXSA9IEFycmF5cy5jb3B5T2Yob3JpZ2luYWxDb3N0W2ldLCBvcmlnaW5hbENvc3RbaV0ubGVuZ3RoKTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgLy8gU29sdmUgdXNpbmcgVm9nZWwncyBhcHByb3hpbWF0aW9uIG1ldGhvZAogICAgICAgIGRvdWJsZVtdW10gc29sdXRpb24gPSBzb2x2ZVRyYW5zcG9ydGF0aW9uKHN1cHBseSwgZGVtYW5kLCB3b3JraW5nQ29zdCk7CiAgICAgICAgCiAgICAgICAgLy8gUHJpbnQgc29sdXRpb24gdXNpbmcgb3JpZ2luYWwgY29zdHMKICAgICAgICBwcmludFNvbHV0aW9uKGNhbm5lcmllcywgd2FyZWhvdXNlcywgc29sdXRpb24sIG9yaWdpbmFsQ29zdCk7CiAgICB9CiAgICAKICAgIHB1YmxpYyBzdGF0aWMgZG91YmxlW11bXSBzb2x2ZVRyYW5zcG9ydGF0aW9uKGludFtdIHN1cHBseSwgaW50W10gZGVtYW5kLCBkb3VibGVbXVtdIGNvc3QpIHsKICAgICAgICBpbnQgbSA9IHN1cHBseS5sZW5ndGg7CiAgICAgICAgaW50IG4gPSBkZW1hbmQubGVuZ3RoOwogICAgICAgIGRvdWJsZVtdW10gc29sdXRpb24gPSBuZXcgZG91YmxlW21dW25dOwogICAgICAgIGludFtdIHMgPSBBcnJheXMuY29weU9mKHN1cHBseSwgbSk7CiAgICAgICAgaW50W10gZCA9IEFycmF5cy5jb3B5T2YoZGVtYW5kLCBuKTsKICAgICAgICAKICAgICAgICB3aGlsZSAodHJ1ZSkgewogICAgICAgICAgICBpbnRbXSBjZWxsID0gZmluZE5leHRDZWxsKGNvc3QsIHMsIGQpOwogICAgICAgICAgICBpZiAoY2VsbCA9PSBudWxsKSBicmVhazsKICAgICAgICAgICAgCiAgICAgICAgICAgIGludCBpID0gY2VsbFswXSwgaiA9IGNlbGxbMV07CiAgICAgICAgICAgIGRvdWJsZSBhbW91bnQgPSBNYXRoLm1pbihzW2ldLCBkW2pdKTsKICAgICAgICAgICAgc29sdXRpb25baV1bal0gPSBhbW91bnQ7CiAgICAgICAgICAgIHNbaV0gLT0gYW1vdW50OwogICAgICAgICAgICBkW2pdIC09IGFtb3VudDsKICAgICAgICAgICAgCiAgICAgICAgICAgIGlmIChzW2ldID09IDApIHsKICAgICAgICAgICAgICAgIGZvciAoaW50IGsgPSAwOyBrIDwgbjsgaysrKSBjb3N0W2ldW2tdID0gSU5GSU5JVFk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGRbal0gPT0gMCkgewogICAgICAgICAgICAgICAgZm9yIChpbnQgayA9IDA7IGsgPCBtOyBrKyspIGNvc3Rba11bal0gPSBJTkZJTklUWTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICByZXR1cm4gc29sdXRpb247CiAgICB9CiAgICAKICAgIHByaXZhdGUgc3RhdGljIGludFtdIGZpbmROZXh0Q2VsbChkb3VibGVbXVtdIGNvc3QsIGludFtdIHMsIGludFtdIGQpIHsKICAgICAgICBkb3VibGUgbWluQ29zdCA9IElORklOSVRZOwogICAgICAgIGludFtdIGNlbGwgPSBudWxsOwogICAgICAgIAogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY29zdC5sZW5ndGg7IGkrKykgewogICAgICAgICAgICBpZiAoc1tpXSA9PSAwKSBjb250aW51ZTsKICAgICAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBjb3N0WzBdLmxlbmd0aDsgaisrKSB7CiAgICAgICAgICAgICAgICBpZiAoZFtqXSA9PSAwKSBjb250aW51ZTsKICAgICAgICAgICAgICAgIGlmIChjb3N0W2ldW2pdIDwgbWluQ29zdCkgewogICAgICAgICAgICAgICAgICAgIG1pbkNvc3QgPSBjb3N0W2ldW2pdOwogICAgICAgICAgICAgICAgICAgIGNlbGwgPSBuZXcgaW50W117aSwgan07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgcmV0dXJuIGNlbGw7CiAgICB9CiAgICAKICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBwcmludFNvbHV0aW9uKFN0cmluZ1tdIHNvdXJjZXMsIFN0cmluZ1tdIGRlc3RpbmF0aW9ucywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG91YmxlW11bXSBzb2x1dGlvbiwgZG91YmxlW11bXSBjb3N0KSB7CiAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJUcmFuc3BvcnRhdGlvbiBTb2x1dGlvbjoiKTsKICAgICAgICBkb3VibGUgdG90YWxDb3N0ID0gMDsKICAgICAgICAKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHNvbHV0aW9uLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgc29sdXRpb25bMF0ubGVuZ3RoOyBqKyspIHsKICAgICAgICAgICAgICAgIGlmIChzb2x1dGlvbltpXVtqXSA+IDApIHsKICAgICAgICAgICAgICAgICAgICBkb3VibGUgY29zdEFtb3VudCA9IHNvbHV0aW9uW2ldW2pdICogY29zdFtpXVtqXTsKICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50ZigiJS0xMHMg4oaSICUtMTJzOiAlNi4xZiB1bml0cyAoQ29zdDogJCU4LjFmKSVuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNvdXJjZXNbaV0sIGRlc3RpbmF0aW9uc1tqXSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzb2x1dGlvbltpXVtqXSwgY29zdEFtb3VudCk7CiAgICAgICAgICAgICAgICAgICAgdG90YWxDb3N0ICs9IGNvc3RBbW91bnQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgU3lzdGVtLm91dC5wcmludGYoIiVuVG90YWwgVHJhbnNwb3J0YXRpb24gQ29zdDogJCUuMWYlbiIsIHRvdGFsQ29zdCk7CiAgICB9Cn0=