import java.util.Arrays;
class TransportationProblem {
private static final double INFINITY
= Double.
MAX_VALUE;
public static void main
(String[] args
) { // ========== INPUT DATA ==========
String[] canneries
= {"Bellingham",
"Eugene",
"Albert_Lea"}; String[] warehouses
= {"Sacramento",
"Salt_Lake",
"Rapid_City",
"Albuquerque"};
int[] supply = {75, 125, 100}; // Cannery capacities
int[] demand = {80, 65, 70, 85}; // Warehouse requirements
double[][] costMatrix = { // Cost per truckload ($)
{464, 513, 654, 867}, // Bellingham costs
{352, 416, 690, 791}, // Eugene costs
{995, 682, 388, 685} // Albert Lea costs
};
// ========== SOLUTION ==========
printProblemStatement(canneries, warehouses, supply, demand, costMatrix);
double[][] optimalShipments = solveTransportationProblem(
supply,
demand,
deepCopyMatrix(costMatrix) // Preserve original
);
printOptimalSolution(canneries, warehouses, optimalShipments, costMatrix);
}
// ========== CORE ALGORITHM ==========
public static double[][] solveTransportationProblem(
int[] supply, int[] demand, double[][] cost) {
int m = supply.length, n = demand.length;
double[][] solution = new double[m][n];
int[] remainingSupply
= Arrays.
copyOf(supply, m
); int[] remainingDemand
= Arrays.
copyOf(demand, n
);
while (true) {
int[] nextShipment = findCheapestValidRoute(cost, remainingSupply, remainingDemand);
if (nextShipment == null) break; // Termination condition
int from = nextShipment[0], to = nextShipment[1];
double amount
= Math.
min(remainingSupply
[from
], remainingDemand
[to
]);
// Record shipment
solution[from][to] = amount;
remainingSupply[from] -= amount;
remainingDemand[to] -= amount;
// Mark exhausted routes
if (remainingSupply[from] == 0)
Arrays.
fill(cost
[from
], INFINITY
); // Entire row if (remainingDemand[to] == 0)
for (int i = 0; i < m; i++) cost[i][to] = INFINITY; // Entire column
}
return solution;
}
// ========== HELPER METHODS ==========
private static int[] findCheapestValidRoute(double[][] cost, int[] supply, int[] demand) {
double minCost = INFINITY;
int[] bestRoute = null;
for (int i = 0; i < cost.length; i++) {
if (supply[i] == 0) continue; // Skip exhausted sources
for (int j = 0; j < cost[0].length; j++) {
if (demand[j] == 0) continue; // Skip satisfied destinations
if (cost[i][j] < minCost) {
minCost = cost[i][j];
bestRoute = new int[]{i, j};
}
}
}
return bestRoute;
}
private static double[][] deepCopyMatrix(double[][] original) {
return Arrays.
stream(original
) .
map(row
-> Arrays.
copyOf(row, row.
length)) .toArray(double[][]::new);
}
// ========== OUTPUT FORMATTING ==========
private static void printProblemStatement(
int[] supply, int[] demand, double[][] cost) {
System.
out.
println("===== TRANSPORTATION PROBLEM ====="); System.
out.
println("\nSources (Supply):"); for (int i = 0; i < sources.length; i++)
System.
out.
printf("- %-12s: %d truckloads%n", sources
[i
], supply
[i
]);
System.
out.
println("\nDestinations (Demand):"); for (int j = 0; j < destinations.length; j++)
System.
out.
printf("- %-12s: %d truckloads%n", destinations
[j
], demand
[j
]);
System.
out.
println("\nCost Matrix ($ per truckload):"); System.
out.
print("From\\To\t"); for (String dest
: destinations
) System.
out.
printf("%-12s\t", dest
);
for (int i = 0; i < sources.length; i++) {
System.
out.
printf("%-12s\t", sources
[i
]); for (int j = 0; j < destinations.length; j++)
System.
out.
printf("$%-11.0f\t", cost
[i
][j
]); }
}
private static void printOptimalSolution(
double[][] shipments, double[][] costMatrix) {
System.
out.
println("\n===== OPTIMAL SOLUTION ====="); double totalCost = 0;
System.
out.
println("\nShipment Plan:"); for (int i = 0; i < shipments.length; i++) {
for (int j = 0; j < shipments[0].length; j++) {
if (shipments[i][j] > 0) {
double shipmentCost = shipments[i][j] * costMatrix[i][j];
"%-12s → %-12s: %5.1f truckloads @ $%-5.0f = $%-7.0f%n",
sources[i], destinations[j],
shipments[i][j], costMatrix[i][j], shipmentCost
);
totalCost += shipmentCost;
}
}
}
System.
out.
printf("%nTotal Transportation Cost: $%.2f%n", totalCost
); System.
out.
println("============================"); }
}
aW1wb3J0IGphdmEudXRpbC5BcnJheXM7CgpjbGFzcyBUcmFuc3BvcnRhdGlvblByb2JsZW0gewoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGRvdWJsZSBJTkZJTklUWSA9IERvdWJsZS5NQVhfVkFMVUU7CiAgICAKICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZ1tdIGFyZ3MpIHsKICAgICAgICAvLyA9PT09PT09PT09IElOUFVUIERBVEEgPT09PT09PT09PQogICAgICAgIFN0cmluZ1tdIGNhbm5lcmllcyA9IHsiQmVsbGluZ2hhbSIsICJFdWdlbmUiLCAiQWxiZXJ0X0xlYSJ9OwogICAgICAgIFN0cmluZ1tdIHdhcmVob3VzZXMgPSB7IlNhY3JhbWVudG8iLCAiU2FsdF9MYWtlIiwgIlJhcGlkX0NpdHkiLCAiQWxidXF1ZXJxdWUifTsKICAgICAgICAKICAgICAgICBpbnRbXSBzdXBwbHkgPSB7NzUsIDEyNSwgMTAwfTsgIC8vIENhbm5lcnkgY2FwYWNpdGllcwogICAgICAgIGludFtdIGRlbWFuZCA9IHs4MCwgNjUsIDcwLCA4NX07IC8vIFdhcmVob3VzZSByZXF1aXJlbWVudHMKICAgICAgICAKICAgICAgICBkb3VibGVbXVtdIGNvc3RNYXRyaXggPSB7ICAvLyBDb3N0IHBlciB0cnVja2xvYWQgKCQpCiAgICAgICAgICAgIHs0NjQsIDUxMywgNjU0LCA4Njd9LCAvLyBCZWxsaW5naGFtIGNvc3RzCiAgICAgICAgICAgIHszNTIsIDQxNiwgNjkwLCA3OTF9LCAvLyBFdWdlbmUgY29zdHMKICAgICAgICAgICAgezk5NSwgNjgyLCAzODgsIDY4NX0gIC8vIEFsYmVydCBMZWEgY29zdHMKICAgICAgICB9OwogICAgICAgIAogICAgICAgIC8vID09PT09PT09PT0gU09MVVRJT04gPT09PT09PT09PQogICAgICAgIHByaW50UHJvYmxlbVN0YXRlbWVudChjYW5uZXJpZXMsIHdhcmVob3VzZXMsIHN1cHBseSwgZGVtYW5kLCBjb3N0TWF0cml4KTsKICAgICAgICAKICAgICAgICBkb3VibGVbXVtdIG9wdGltYWxTaGlwbWVudHMgPSBzb2x2ZVRyYW5zcG9ydGF0aW9uUHJvYmxlbSgKICAgICAgICAgICAgc3VwcGx5LCAKICAgICAgICAgICAgZGVtYW5kLCAKICAgICAgICAgICAgZGVlcENvcHlNYXRyaXgoY29zdE1hdHJpeCkgLy8gUHJlc2VydmUgb3JpZ2luYWwKICAgICAgICApOwogICAgICAgIAogICAgICAgIHByaW50T3B0aW1hbFNvbHV0aW9uKGNhbm5lcmllcywgd2FyZWhvdXNlcywgb3B0aW1hbFNoaXBtZW50cywgY29zdE1hdHJpeCk7CiAgICB9CgogICAgLy8gPT09PT09PT09PSBDT1JFIEFMR09SSVRITSA9PT09PT09PT09CiAgICBwdWJsaWMgc3RhdGljIGRvdWJsZVtdW10gc29sdmVUcmFuc3BvcnRhdGlvblByb2JsZW0oCiAgICAgICAgaW50W10gc3VwcGx5LCBpbnRbXSBkZW1hbmQsIGRvdWJsZVtdW10gY29zdCkgewogICAgICAgIAogICAgICAgIGludCBtID0gc3VwcGx5Lmxlbmd0aCwgbiA9IGRlbWFuZC5sZW5ndGg7CiAgICAgICAgZG91YmxlW11bXSBzb2x1dGlvbiA9IG5ldyBkb3VibGVbbV1bbl07CiAgICAgICAgaW50W10gcmVtYWluaW5nU3VwcGx5ID0gQXJyYXlzLmNvcHlPZihzdXBwbHksIG0pOwogICAgICAgIGludFtdIHJlbWFpbmluZ0RlbWFuZCA9IEFycmF5cy5jb3B5T2YoZGVtYW5kLCBuKTsKICAgICAgICAKICAgICAgICB3aGlsZSAodHJ1ZSkgewogICAgICAgICAgICBpbnRbXSBuZXh0U2hpcG1lbnQgPSBmaW5kQ2hlYXBlc3RWYWxpZFJvdXRlKGNvc3QsIHJlbWFpbmluZ1N1cHBseSwgcmVtYWluaW5nRGVtYW5kKTsKICAgICAgICAgICAgaWYgKG5leHRTaGlwbWVudCA9PSBudWxsKSBicmVhazsgLy8gVGVybWluYXRpb24gY29uZGl0aW9uCiAgICAgICAgICAgIAogICAgICAgICAgICBpbnQgZnJvbSA9IG5leHRTaGlwbWVudFswXSwgdG8gPSBuZXh0U2hpcG1lbnRbMV07CiAgICAgICAgICAgIGRvdWJsZSBhbW91bnQgPSBNYXRoLm1pbihyZW1haW5pbmdTdXBwbHlbZnJvbV0sIHJlbWFpbmluZ0RlbWFuZFt0b10pOwogICAgICAgICAgICAKICAgICAgICAgICAgLy8gUmVjb3JkIHNoaXBtZW50CiAgICAgICAgICAgIHNvbHV0aW9uW2Zyb21dW3RvXSA9IGFtb3VudDsKICAgICAgICAgICAgcmVtYWluaW5nU3VwcGx5W2Zyb21dIC09IGFtb3VudDsKICAgICAgICAgICAgcmVtYWluaW5nRGVtYW5kW3RvXSAtPSBhbW91bnQ7CiAgICAgICAgICAgIAogICAgICAgICAgICAvLyBNYXJrIGV4aGF1c3RlZCByb3V0ZXMKICAgICAgICAgICAgaWYgKHJlbWFpbmluZ1N1cHBseVtmcm9tXSA9PSAwKSAKICAgICAgICAgICAgICAgIEFycmF5cy5maWxsKGNvc3RbZnJvbV0sIElORklOSVRZKTsgLy8gRW50aXJlIHJvdwogICAgICAgICAgICBpZiAocmVtYWluaW5nRGVtYW5kW3RvXSA9PSAwKSAKICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbTsgaSsrKSBjb3N0W2ldW3RvXSA9IElORklOSVRZOyAvLyBFbnRpcmUgY29sdW1uCiAgICAgICAgfQogICAgICAgIAogICAgICAgIHJldHVybiBzb2x1dGlvbjsKICAgIH0KCiAgICAvLyA9PT09PT09PT09IEhFTFBFUiBNRVRIT0RTID09PT09PT09PT0KICAgIHByaXZhdGUgc3RhdGljIGludFtdIGZpbmRDaGVhcGVzdFZhbGlkUm91dGUoZG91YmxlW11bXSBjb3N0LCBpbnRbXSBzdXBwbHksIGludFtdIGRlbWFuZCkgewogICAgICAgIGRvdWJsZSBtaW5Db3N0ID0gSU5GSU5JVFk7CiAgICAgICAgaW50W10gYmVzdFJvdXRlID0gbnVsbDsKICAgICAgICAKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvc3QubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgaWYgKHN1cHBseVtpXSA9PSAwKSBjb250aW51ZTsgLy8gU2tpcCBleGhhdXN0ZWQgc291cmNlcwogICAgICAgICAgICAKICAgICAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBjb3N0WzBdLmxlbmd0aDsgaisrKSB7CiAgICAgICAgICAgICAgICBpZiAoZGVtYW5kW2pdID09IDApIGNvbnRpbnVlOyAvLyBTa2lwIHNhdGlzZmllZCBkZXN0aW5hdGlvbnMKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgaWYgKGNvc3RbaV1bal0gPCBtaW5Db3N0KSB7CiAgICAgICAgICAgICAgICAgICAgbWluQ29zdCA9IGNvc3RbaV1bal07CiAgICAgICAgICAgICAgICAgICAgYmVzdFJvdXRlID0gbmV3IGludFtde2ksIGp9OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBiZXN0Um91dGU7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZG91YmxlW11bXSBkZWVwQ29weU1hdHJpeChkb3VibGVbXVtdIG9yaWdpbmFsKSB7CiAgICAgICAgcmV0dXJuIEFycmF5cy5zdHJlYW0ob3JpZ2luYWwpCiAgICAgICAgICAgICAgICAgICAubWFwKHJvdyAtPiBBcnJheXMuY29weU9mKHJvdywgcm93Lmxlbmd0aCkpCiAgICAgICAgICAgICAgICAgICAudG9BcnJheShkb3VibGVbXVtdOjpuZXcpOwogICAgfQoKICAgIC8vID09PT09PT09PT0gT1VUUFVUIEZPUk1BVFRJTkcgPT09PT09PT09PQogICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBwcmludFByb2JsZW1TdGF0ZW1lbnQoCiAgICAgICAgU3RyaW5nW10gc291cmNlcywgU3RyaW5nW10gZGVzdGluYXRpb25zLCAKICAgICAgICBpbnRbXSBzdXBwbHksIGludFtdIGRlbWFuZCwgZG91YmxlW11bXSBjb3N0KSB7CiAgICAgICAgCiAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCI9PT09PSBUUkFOU1BPUlRBVElPTiBQUk9CTEVNID09PT09Iik7CiAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJcblNvdXJjZXMgKFN1cHBseSk6Iik7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzb3VyY2VzLmxlbmd0aDsgaSsrKSAKICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGYoIi0gJS0xMnM6ICVkIHRydWNrbG9hZHMlbiIsIHNvdXJjZXNbaV0sIHN1cHBseVtpXSk7CiAgICAgICAgCiAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJcbkRlc3RpbmF0aW9ucyAoRGVtYW5kKToiKTsKICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IGRlc3RpbmF0aW9ucy5sZW5ndGg7IGorKykgCiAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRmKCItICUtMTJzOiAlZCB0cnVja2xvYWRzJW4iLCBkZXN0aW5hdGlvbnNbal0sIGRlbWFuZFtqXSk7CiAgICAgICAgCiAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJcbkNvc3QgTWF0cml4ICgkIHBlciB0cnVja2xvYWQpOiIpOwogICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIkZyb21cXFRvXHQiKTsKICAgICAgICBmb3IgKFN0cmluZyBkZXN0IDogZGVzdGluYXRpb25zKSBTeXN0ZW0ub3V0LnByaW50ZigiJS0xMnNcdCIsIGRlc3QpOwogICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigpOwogICAgICAgIAogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc291cmNlcy5sZW5ndGg7IGkrKykgewogICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50ZigiJS0xMnNcdCIsIHNvdXJjZXNbaV0pOwogICAgICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IGRlc3RpbmF0aW9ucy5sZW5ndGg7IGorKykgCiAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50ZigiJCUtMTEuMGZcdCIsIGNvc3RbaV1bal0pOwogICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oKTsKICAgICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBwcmludE9wdGltYWxTb2x1dGlvbigKICAgICAgICBTdHJpbmdbXSBzb3VyY2VzLCBTdHJpbmdbXSBkZXN0aW5hdGlvbnMsCiAgICAgICAgZG91YmxlW11bXSBzaGlwbWVudHMsIGRvdWJsZVtdW10gY29zdE1hdHJpeCkgewogICAgICAgIAogICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiXG49PT09PSBPUFRJTUFMIFNPTFVUSU9OID09PT09Iik7CiAgICAgICAgZG91YmxlIHRvdGFsQ29zdCA9IDA7CiAgICAgICAgCiAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJcblNoaXBtZW50IFBsYW46Iik7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzaGlwbWVudHMubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBzaGlwbWVudHNbMF0ubGVuZ3RoOyBqKyspIHsKICAgICAgICAgICAgICAgIGlmIChzaGlwbWVudHNbaV1bal0gPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgZG91YmxlIHNoaXBtZW50Q29zdCA9IHNoaXBtZW50c1tpXVtqXSAqIGNvc3RNYXRyaXhbaV1bal07CiAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGYoCiAgICAgICAgICAgICAgICAgICAgICAgICIlLTEycyDihpIgJS0xMnM6ICU1LjFmIHRydWNrbG9hZHMgQCAkJS01LjBmID0gJCUtNy4wZiVuIiwKICAgICAgICAgICAgICAgICAgICAgICAgc291cmNlc1tpXSwgZGVzdGluYXRpb25zW2pdLAogICAgICAgICAgICAgICAgICAgICAgICBzaGlwbWVudHNbaV1bal0sIGNvc3RNYXRyaXhbaV1bal0sIHNoaXBtZW50Q29zdAogICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgICAgdG90YWxDb3N0ICs9IHNoaXBtZW50Q29zdDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICBTeXN0ZW0ub3V0LnByaW50ZigiJW5Ub3RhbCBUcmFuc3BvcnRhdGlvbiBDb3N0OiAkJS4yZiVuIiwgdG90YWxDb3N0KTsKICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIj09PT09PT09PT09PT09PT09PT09PT09PT09PT0iKTsKICAgIH0KfQ==