制作奇偶圈的算法?

时间:2016-01-03 05:35:56

标签: algorithm graph

我正在尝试制作一个程序(带有GUI)来解析文本文件输入,并创建一个“奇偶圈”,String(byte[] bytes, Charset charset)

举一个简单的例子,让我们说Aaron,Bob和Chuck正在玩摇滚剪刀,并且:

  • Aaron击败Bob
  • 鲍勃击败查克
  • Chuck击败Aaron

然后,存在奇偶性圈:Aaron>鲍勃> Chuck>亚伦(和重复)。通过(不合逻辑的)归纳推理,可以说鲍勃在石头剪刀上比亚伦更好,尽管鲍勃输给了亚伦。

但是,如果:

  • Aaron击败Bob
  • 鲍勃失去所有比赛
  • Chuck击败Aaron

然后不存在奇偶校验圈。每个人必须至少有一个胜利和一个存在一个完整的奇偶圈的1个损失。因此,对于我来说,在具有最少胜/亏的个人/团队/节点进行分析似乎是合乎逻辑的。

最后,如果:

  • Aaron击败Bob&卡盘
  • 鲍勃失去所有比赛
  • Chuck击败Bob&亚伦

然后存在不完整的奇偶圈:Aaron> Chuck>亚伦。

在我的计划中,每个团队/个人都会列出所有已经击败的团队,并且该计划将与大量团队(30岁以上)打交道,因此效率总是很好。我还可以实现它丢失的所有球队的列表。有关如何实现算法以通过这些列表的任何建议?提前谢谢!

2 个答案:

答案 0 :(得分:1)

我认为这是https://en.wikipedia.org/wiki/Hamiltonian_path_problem,其中没有已知的有效算法。对于小图,回溯搜索可能是可行的。有一个动态编程解决方案,理论上比回溯搜索更快 - 但这只是从大约O(n!)到O(n ^ 2 * 2 ^ n)的变化

答案 1 :(得分:0)

只是为了好玩,考虑一下......(免责声明:现在已经很晚了,我只是头脑风暴:-))

我正在努力解决用图论解决这个问题的好处。
假设您构建了一个捕获每个游戏的图表。
你将如何遍历它以产生分数? 你必须跟踪一个"访问过的"列表为每个球员得分,递归城市。 你似乎必须为每个玩家进行详尽的遍历。
为O(n ^哎哟)

所以...告诉我这是否合理:

Example Games:
A/B: winner.A
B/C: winner.B
C/A: winner.C

explicit (using vict since same # letters as loss):
A.vict.B   B.loss.A
B.vict.C   C.loss.B
C.vict.A   A.loss.C

Breaking all these out:
:   raw     : simple sort  :
: A.vict.B  : A.loss.C     :
: B.loss.A  : A.vict.B     :
: B.vict.C  : B.loss.A     :
: C.loss.B  : B.vict.C     :
: C.vict.A  : C.loss.B     :
: A.loss.C  : C.vict.A     :


Grouped by loss vs. vict:
A:  loss[ C ]   vict [ B ]
B:  loss[ A ]   vict [ C ]
C:  loss[ B ]   vict [ A ]

为你的球员排名......
从他们的净胜利开始呢?

在上面的例子中,每个人都有零赢,所以所有人都同样强(或弱)。


或者代替净赢,可能是每个玩家的winLossRatio。上述示例中的所有玩家将具有0.5的比率(例如,总共1场胜利/ 2场比赛)。
然后根据对手的力量为你赢得(和损失)的地方产生一个加权的赢利。

这可能更好,因为SQL更新数据库表...
但是这个想法的草图遵循伪java ...

Class Player {
   //something to track all players.
   //and I suppose to load their wins & losses.
   static updateScores() {
      foreach player ( players ) {
         player.updateWinLossRatio();
      }
      // have to update ratios before computing scores using those ratios.
      foreach player ( players ) {
         player.updateWeightedScores();
      }
   }
   updateWinLossRatio() {
      // want #wins / totalGames
      winLossRatio = victories.size() / (victories.size() + losses.size() );
      // add check for zero and stuff.
   }
   updateWeightedScore() {
      weightedWinLoss = 0;
      foreach opponent ( victories ) {
         weightedWinLoss += opponent.winLossRatio;
         // this sort of already reduces credit for weak opponents,
         // since their win ratio would be pretty small.
      }
      foreach opponent ( losses ) {
         weightedWinLoss -= opponent.winLossRatio;
         // might want to penalize by inverse of opponents strength.
         // e.g. losing to a super weak opponent should hurt more.
         // so maybe:
         //    weightedWinLoss -= 1 / opponent.winLossRatio;
      }
   }
}

如果我这样做,我想在我的测试数据上运行一些公式,绘制结果曲线并调整它直到看起来合理。您可能希望缩放分数,如果比率计算为log(wins)/ log(totalgames)或者你有什么,可能看起来更好。