多种组合记忆问题的笛卡尔积

时间:2015-12-16 01:52:11

标签: c# memory combinations combinatorics

哟,

我遇到了一个小问题。我有一些"玩家"我试图运行一些概率预测。有112名球员。在这些球员中,以下是真实的:

  • 64可以击球。
  • 66可以碗。
  • 10可以是wicket keepers
  • 任何玩家都可以做任何两个碗/蝙蝠/检票口,但至少有一个。

团队由以下人员组成:

  • 7名可以击球的球员。
  • 7名可以参赛的球员。
  • 2名可以检票的球员。
  • 团队中不能有重复的玩家。
  • 即使玩家有两个角色,玩家也只能履行一个角色。(击球手/投球手必须蝙蝠或投球不是两个)

现在问题

我有以下代码。

var allBattingCombos = new Combinations<int>(players.Where(player => player.inRoundCanBat).Select(player => player.fantasyID).ToList(), 7);
var allBowlingCombos = new Combinations<int>(players.Where(player => player.inRoundCanBowl).Select(player => player.fantasyID).ToList(), 7);
var allWKTCombos = new Combinations<int>(players.Where(player => player.inRoundCanWkt).Select(player => player.fantasyID).ToList(), 2);

var allCombos = new List<Combinations<int>>() { allBowlingCombos , allBowlingCombos, allWKTCombos };
var allTeamCombos = allCombos.CartesianProduct().ToList();

CartesianProduct(来自Finding all combinations from sets of possibilities)=

public static IEnumerable<IEnumerable<T>> CartesianProduct<T>(this IEnumerable<IEnumerable<T>> sequences)
{
    // Default object
    IEnumerable<IEnumerable<T>> emptyProduct = new[] { Enumerable.Empty<T>() };

    return sequences.Aggregate(
        emptyProduct,
        (accumulator, sequence) =>
        from accseq in accumulator
        from item in sequence
        select accseq.Concat(new[] { item }));
}

我得到以下值:

allBattingCombos count = 621216192
allBowlingCombos count = 778789440
allWKTCombos count = 45

所有团队组合锁定我的电脑,最终它因内存不足而死机。当我在等待我的计算运行时,我做了一些数学运算。根据{{​​3}}列表中每个int 4个字节的最小值,这样:

4 bytes * 
15 member ids in a team * 
621216192 batting combos * 
778789440 bowling combos *
45 wkt combos

= 1.34E+21 bytes

or 13400000000000 gigaBytes

Yikes,没有人像dat一样没有ram。

让我更可怕的是我需要运行9次,每轮1次。

一旦我拥有团队的可能性,我需要在每个团队中运行这样的事情。

Team highestScoringTeam = null;

foreach (var team in allTeamCombos)
{
    var teamobj = new Team();
    teamobj.BattersList = team[0].ToList();
    teamobj.BowlersList = team[1].ToList();
    teamobj.WktKeepersList = team[2].ToList();
    if (highestScoringTeam == null)
    {
        highestScoringTeam = teamobj;
    }
    else if (teamobj.TeamIsValid && teamobj.TotalScoreForRound > highestScoringTeam.TotalScoreForRound)
    {
        highestScoringTeam = teamobj;
    }
}

有谁知道我如何解决我的ram问题/看到更好的方法来实现我的目标?

----更新1 ----

经过一番思考后我不需要整个列表对象,我可以在笛卡尔计算中使用它。代替allTeamCombos,我使用以下内容。

foreach (var battingCombo in allBattingCombos)
{
    foreach (var bowlingCombo in allBowlingCombos)
    {
        foreach (var WktCombo in allWKTCombos)
        {
            var team = new Team();

            team.BattersList = battingCombo.Select(id => players.First(p => p.fantasyID == id)).ToList();
            team.BowlersList = bowlingCombo.Select(id => players.First(p => p.fantasyID == id)).ToList();
            team.WktKeepersList = WktCombo.Select(id => players.First(p => p.fantasyID == id)).ToList();
            if (highestScoringTeam == null)
            {
                highestScoringTeam = team;
            }
            else if (team.TeamIsValid && team.TotalScoreForRound > highestScoringTeam.TotalScoreForRound)
            {
                highestScoringTeam = team;
                Console.WriteLine("new highScore = " + team.TotalScoreForRound);
            }

            combinationsParsed++;
            if(combinationsParsed % 10000 == 0)
                Console.WriteLine("combinationsParsed = " + combinationsParsed);
        }
    }

我认为这解决了公羊问题,我也认为我应该关闭这个问题。

0 个答案:

没有答案