我目前正在努力为我的配对系统编写算法。对于对数学一无所知的人来说,这可能是孩子们的游戏,好吧,我不知道。
让我们看下面的例子:
一个大厅正好由8 名玩家组成。
队列中有 9 方。派对规模为:1、6、3、8、2、1、5、3、2
。算法需要从这些派对中创建尽可能多的完整大厅。
可能只有满员的大厅。因此,可能存在无法匹配的各方。然后,那些将等待新的政党进入队列。
我当前的代码确实将各方与大厅匹配,但它缺乏找到最佳组合以找到尽可能多的完整大厅的功能。
示例:大厅大小正好为 7,派对:2,2,4,3,1,5 -> 2,5 和 4,3 可以匹配,但是 2,2,3 和 4,1,5 不能匹配被匹配。
我很感激任何帮助。
我当前的代码:
// Limitation: Is not intelligent. Example: Size 7, Teams 2,2,4,3,1,5 -> 2,5 and 4,3 could be matched, but it will do 2,2,3 and 4,1,5
// Possible solution: Sort for size or match parties with lowest possible match e.g try 5,1 then 5,2 ...
public List<MatchedParty> getLobbies(List<Party> parties, int teamSize) {
List<MatchedParty> lobbies = new ArrayList<>();
parties.sort(Comparator.comparing(Party::getJoinedQueueTime));
while (!(parties.isEmpty())) {
MatchedParty matchedParty = new MatchedParty();
List<Party> team1 = new ArrayList<>();
List<Party> team2 = new ArrayList<>();
boolean teamReset = false;
int counter = 0;
while (team1.stream().mapToLong(c -> c.getMembers().size()).sum() != teamSize || team2.stream().mapToLong(c -> c.getMembers().size()).sum() != teamSize) {
if (team1.stream().mapToLong(c -> c.getMembers().size()).sum() != teamSize) {
team1.clear();
}
if (team2.stream().mapToLong(c -> c.getMembers().size()).sum() != teamSize) {
team2.clear();
}
// Iterate over all parties and add matching ones to the teams
for (int i = counter; i < parties.size(); i++) {
if (team1.stream().mapToLong(c -> c.getMembers().size()).sum() + parties.get(i).getMembers().size() <= teamSize && !(team2.contains(parties.get(i)))) {
team1.add(parties.get(i));
} else if (team2.stream().mapToLong(c -> c.getMembers().size()).sum() + parties.get(i).getMembers().size() <= teamSize && !(team1.contains(parties.get(i)))) {
team2.add(parties.get(i));
}
}
// Reset search when first team is full
if ((team1.stream().mapToLong(c -> c.getMembers().size()).sum() == teamSize || team2.stream().mapToLong(c -> c.getMembers().size()).sum() == teamSize) && !(teamReset)) {
counter = 0;
teamReset = true;
}
// Check if we iterated over all parties, if so exit the loop
if (counter <= parties.size()) {
counter++;
} else {
break;
}
}
// Are there still teams found? If not, return the lobbies
if (team1.stream().mapToLong(c -> c.getMembers().size()).sum() == teamSize && team2.stream().mapToLong(c -> c.getMembers().size()).sum() == teamSize) {
matchedParty.setTeam1(team1);
matchedParty.setTeam2(team2);
lobbies.add(matchedParty);
parties.removeAll(team1);
parties.removeAll(team2);
} else {
return lobbies;
}
}
// Maybe all parties found a team, if so return too
return lobbies;
}