二分图中的联盟分组?

时间:2014-10-08 16:19:04

标签: algorithm data-structures graph grouping bipartite

我试图找出解决以下问题的好(快速)解决方案:

我有两个与我合作的模特,让我们称他们为球员和球队。玩家可以在多个团队中,团队可以拥有多个玩家。我正致力于在表单上创建UI元素,允许用户选择多个团队(复选框)。当用户选择(或取消选择)团队时,我想显示由玩家分组的团队。

例如:

  1. 如果所选球队没有相交的球员,则每支球队都有自己的部分。

  2. 如果用户选择了两支球队并且他们拥有相同的球员,则会有一个部分包含两支球队和所有球员的名字。

  3. 如果TEAM_A有玩家[1,2,4,5],TEAM_B有玩家[1,3,5,6]。将有以下部分:SECTION_X = [TEAM_A,TEAM_B,1,5],SECTION_Y = [TEAM_A,2,3],SECTION _Z = [TEAM_B,3,5]

  4. 我希望这很清楚。从本质上讲,我希望找到玩家共同拥有的团队,并通过该团队进行分组。我想也许有办法通过导航二分图来做到这一点?不确定如何,我可能会过度思考它。我希望通过在服务器上创建某种类型的数据结构并在客户端上使用它来实现这一点。我很想听听您的建议,感谢您给予的任何帮助!

1 个答案:

答案 0 :(得分:0)

一个解决方案是让每个玩家包装器跟踪它所在的选定团队

class PlayerWrapper {
  Player player;
  TeamList teamList;
}

class TeamList {
  private List<Team> teams;
  int hashValue = // hash value derived from teams list
  void add(Team team) {
    teams.add(team);
    hashValue = // update hash value
  }
}

然后维护一个玩家集的哈希表,以及一个玩家包装器的哈希表

HashTable<TeamList, Set<Player>> playerSets
HashTable<Player, PlayerWrapper> playerWrappers

当用户选择新的团队时,遍历团队的玩家并从playerWrappers检索玩家包装。对于每个玩家包装器,从Set<Player>检索playerSets并从集合中删除玩家,然后将新团队添加到包装器TeamList,从{{Set<Player>检索playerSets 1}}并将播放器添加到集合中。

void updatePlayer(Team team, Player player) {
  PlayerWrapper wrapper = playerWrappers.get(player);
  Set<Player> set = playerSets.get(wrapper.teamList);
  set.remove(player);
  wrapper.teamList.add(team);
  set = playerSets.get(wrapper.teamList);
  set.add(player);
}

假设您正在为Set<Player>使用哈希集,这平均需要一段时间来处理团队的玩家。取消选择团队将以相同的方式运行,除非您从wrapper.teamList移除团队而不是添加团队,并且您将通过TeamList进行线性时间搜索以找到并删除团队。在List中使用TeamList假设用户界面会阻止重复的小组;小心使用Set代替,因为确保两个封套可能更加困难。 TeamLists将具有相同的hashValue(即您可能需要采取措施确保两个包装器以相同的顺序返回其团队 - 类似于java LinkedHashSet会做的事情诀窍)