package iamrescue.util;
import java.util.Arrays;
public class OptimalAssignmentCalculator {
/**
* Assigns a set of tasks to agents in order to minimise the overall cost.
* @param costs
* Takes an array where costs[taskID][agentID] represents a cost
* of a particular agent performing a given task.
* @return An assignment of tasks to agents, such that assignment[taskID] =
* agentID.
*/
public static int[] calculateOptimalAssignment(double[][] costs) {
if (costs.length == 0 || costs[0].length == 0) {
return new int[0];
}
int tasks = costs.length;
int agents = costs[0].length;
if (agents < tasks) {
throw new IllegalArgumentException(
"There must be at least as many agents as there are tasks. "
+ " I have " + tasks + " tasks and " + agents
+ " agents.");
}
Hungarian hungarian = new Hungarian(agents, tasks);
for (int i = 0; i < tasks; i++) {
if (costs[i].length != agents) {
throw new IllegalArgumentException(
"Different number of agents for task " + i);
}
double[] preferences = new double[agents];
for (int j = 0; j < agents; j++) {
preferences[j] = -costs[i][j];
}
hungarian.addColumn(i, preferences);
}
hungarian.solve();
// int[] solutions = hungarian.getSolutions();
// int[] taskSolutions = new int[tasks];
return hungarian.getSolutions();
}
public static double calculateCost(double[][] costs, int[] assignment) {
double cost = 0;
if (assignment.length != costs.length) {
throw new IllegalArgumentException(
"Length of assignment does not match length of costs: "
+ assignment.length + " != " + costs.length + " "
+ Arrays.toString(assignment));
}
for (int i = 0; i < assignment.length; i++) {
cost += costs[i][assignment[i]];
}
return cost;
}
}