C# 多重组合的笛卡尔积记忆问题

C# 多重组合的笛卡尔积记忆问题,c#,memory,combinations,combinatorics,C#,Memory,Combinations,Combinatorics,哟, 我遇到了一个小问题。我有一个“玩家”的选择,我试图运行一些概率预测。有112名球员。在这些参与者中,以下是正确的: 64可以击球 66罐碗 10人可以担任边门守门员 任何球员都可以完成任意两个保龄球/球拍/边门,但至少一个 团队由以下人员组成: 7名能击球的球员 7个能打保龄球的球员 2名球员可以担任边门守门员 一个团队中不能有重复的球员 一名球员只能扮演一个角色,即使他们能够扮演两个角色。(击球手/投球手必须击球或保龄球,而不是两者兼而有之) 现在来谈谈问题 我有以下代码 var

哟,

我遇到了一个小问题。我有一个“玩家”的选择,我试图运行一些概率预测。有112名球员。在这些参与者中,以下是正确的:

  • 64可以击球
  • 66罐碗
  • 10人可以担任边门守门员
  • 任何球员都可以完成任意两个保龄球/球拍/边门,但至少一个
团队由以下人员组成:

  • 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();
所有团队组合都会锁定我的电脑,最终它会随着我的内存耗尽而死掉。当我在等待计算的时候,我做了一些数学题。根据列表中每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
哎呀,没有人能像达特那样拥有公羊

更可怕的是我需要跑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----

经过一些思考,我在任何时候都不需要整个列表对象,我可以在笛卡尔计算期间使用它。我使用以下方法代替所有团队组合

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);
        }
    }

我认为这解决了ram的问题,我也认为我应该结束这个问题。

写下这一切有很大帮助。它让我思考是否需要存储ID列表。嗯,我想需要更多的思考。为什么要投反对票您的要求没有解决方案:
2可以是边门守门员
7个可以是边门守门员的球员。
-您缺少5个边门守门员:)此外,对于基于数学的SE站点来说,这可能是一个好问题。主要的问题是,也许你不需要计算这些组合。如果玩家相同(他们拥有相同的能力),你可以将他们从组合集中排除,只需为唯一的玩家添加权重。我认为您首先需要从逻辑上找出如何解决问题,然后实现代码。有很多方法可以减少内存的使用量,但是你会被这样一个事实所困扰,那就是你需要为击球手运行
621216192
组合。@rob Your total correct,my bad我已经解决了这个问题。关于集合唯一性,我认为以编程方式检查角色组合之间的唯一参与者的唯一方法是在笛卡尔积计算点,而不是以前。我想我可能已经解决了我的记忆问题,而这一点可能是没有意义的。我会详细更新我的问题。
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;
    }
}
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);
        }
    }