假设我有一个带N的数组(对于这个例子N = 10)值,每个值都在1-10之间:
10
8.4
7.9
7.8
7.7
7.3
7.3
6.9
6.1
5.8
现在,我想将它们分成P组(对于这个例子P = 2),所有组都是偶数(AKA为SUM),或尽可能接近。
我已经为此写了一个算法:
public static void mainLogic(ArrayList<Player> team) {
Player currentPlayer = new Player();
Player minDifPlayer = new Player();
double minDiff = 100;
for (int ind = 0; ind < team.size(); ind++) {
if (team.isEmpty())
return;
double temp = team.get(ind).get_playeroverall();
if (ind == team.size() - 1) {
//if num of Player match for two teams
if (team.size() < 18) {
// if the teams are equals or teamA AVG small then teamB
if (sum(teamA) <= sum(teamB)) {
teamA.add(currentPlayer);
teamB.add(minDifPlayer);
Results.TempArray.add(currentPlayer);
Results.TempArray.add(minDifPlayer);
team.remove(currentPlayer);
team.remove(minDifPlayer);
//if teamB AVG small then teamA
} else if (sum(teamA) > sum(teamB)) {
teamB.add(currentPlayer);
teamA.add(minDifPlayer);
Results.TempArray.add(currentPlayer);
Results.TempArray.add(minDifPlayer);
team.remove(currentPlayer);
team.remove(minDifPlayer);
}
// if the teams are full, Player are subscribed to the following team
if (teamA.size() == 6 && teamB.size() == 6) {
teamC.addAll(team);
Results.TempArray.addAll(team);
team.clear();
}
ind = 0;
minDiff = 100;
if (!team.isEmpty())
temp = team.get(ind).get_playeroverall();
}
}
for (int pointer = ind + 1; pointer <= team.size() - 1; pointer++) {
double rankToCompare = team.get(pointer).get_playeroverall();
if (Math.abs(temp - rankToCompare) < minDiff) {
minDiff = Math.abs(temp - rankToCompare);
currentPlayer = team.get(ind);
minDifPlayer = team.get(pointer);
}
}
}
}
问题是该算法没有完美解决。对于上面的例子,他给了我
10 8.4
7.8 7.9
7.3 7.3
6.9 7.7
5.8 6.1
SUM=37.8 SUM=37.4
我可以通过这种方式手动匹配它们:
10 8.4
7.7 7.9
7.3 7.3
6.9 7.8
5.8 6.1
SUM=37.7 SUM=37.5
(我写的算法针对3组,每组6名玩家 - 当额外玩家移动到下一组时,意味着18名玩家排名靠前)
答案 0 :(得分:2)
您发布的问题是NP-Hard问题,在计算机科学中称为K方式分区问题。
这个问题很少有近似解决方案和贪心解决方案。
由于这是一个众所周知的理论问题,我建议你看看Partitioning Problem。