首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >计算给定一些约束的所有可能的组合

计算给定一些约束的所有可能的组合
EN

Stack Overflow用户
提问于 2020-11-06 14:01:12
回答 2查看 261关注 0票数 1

我试图为一个个人项目解决这个算法问题。

  1. 在这次比赛中有8名选手。
  2. 他们玩2vs2
  3. 同时进行两场比赛(因此所有8名球员都在比赛)
  4. 每个球员必须和其他球员一起打7场比赛(在同一支球队)。
  5. 在比赛结束时,每个球员都打了7场比赛。
  6. 这次比赛共有14场比赛。
  7. 比赛的排列不算作新的比赛。(也就是说,锦标赛被定义为一组比赛)

这是A,B,C,D,E,F,G,H的一个例子:

代码语言:javascript
运行
AI代码解释
复制
Match  1 :   A, B  VS  C, D.                                Score = ____ : ____
Match  2 :   E, F  VS  H, G.                                Score = ____ : ____
Match  3 :   C, A  VS  B, D.                                Score = ____ : ____
Match  4 :   E, G  VS  H, F.                                Score = ____ : ____
Match  5 :   A, D  VS  C, B.                                Score = ____ : ____
Match  6 :   H, E  VS  F, G.                                Score = ____ : ____
Match  7 :   E, A  VS  B, F.                                Score = ____ : ____
Match  8 :   C, G  VS  H, D.                                Score = ____ : ____
Match  9 :   A, F  VS  E, B.                                Score = ____ : ____
Match 10 :   H, C  VS  D, G.                                Score = ____ : ____
Match 11 :   A, G  VS  H, B.                                Score = ____ : ____
Match 12 :   C, E  VS  D, F.                                Score = ____ : ____
Match 13 :   H, A  VS  B, G.                                Score = ____ : ____
Match 14 :   C, F  VS  E, D.                                Score = ____ : ____

请注意,Match iMatch i+1同时播放if i%2==1

问题:

有多少不同的比赛是可能的?这些比赛是什么?

我试过一种蛮力的方法,但太慢了。有没有更好的算法?

编辑:

密码是欢迎的。特别是蟒蛇

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-11-06 18:58:48

这个问题是高度对称的,让我把它写成更紧凑的形式。

代码语言:javascript
运行
AI代码解释
复制
AB CD + EF GH                              
AC BD + EG FH                              
AD BC + EH FG 
AE BF + CG DH
AF BE + CH DG
AG BH + CE DF
AH BG + CF DE

对于8名球员,有28支可能的两人队伍(AB,AC,AD.)所有的都出现在桌子上,每一次都是一次。AB和BA是同一支球队,我会选择第一种形式,因为这是字母顺序。AB CD和CD AB是相同的匹配,我会选择第一种形式。AB CD + EF GH和EF GH + AB CD只是配对的排列,我会选择第一种形式。在所有这些情况下,我们将问题简化为在此模式中填充21个单词。

代码语言:javascript
运行
AI代码解释
复制
AB __ + __ __
AC __ + __ __
AD __ + __ __
AE __ + __ __
AF __ + __ __
AG __ + __ __
AH __ + __ __

这样的话,每一行都包含所有的8个字母,每个都是一次。这很容易被蛮力所迫,计算时间约为15秒(没有将组合写入控制台),结果是10034775。

代码语言:javascript
运行
AI代码解释
复制
static bool SolutionIsOK(string[,] matchesTuples)
{
    for (int i = 1; i < 7; ++i)
    {
        for (int j = 0; j < i; ++j)
        {
            string a1 = matchesTuples[j, 2];
            string a2 = matchesTuples[i, 2];

            if (a1[0] > a2[0] || a1[0] == a2[0] && a1[1] > a2[1])
            {
                string b1 = matchesTuples[j, 3];
                string b2 = matchesTuples[i, 3];

                int check1 = (1 << (a1[0] - 'A')) |
                             (1 << (a1[1] - 'A')) |
                             (1 << (b1[0] - 'A')) |
                             (1 << (b1[1] - 'A'));
                int check2 = (1 << (a2[0] - 'A')) |
                             (1 << (a2[1] - 'A')) |
                             (1 << (b2[0] - 'A')) |
                             (1 << (b2[1] - 'A'));

                if (check1 == check2) { return false; }
            }
        }
    }
    return true;
}

static void WriteSolution(string[,] matchesTuples)
{
    for (int i = 0; i < 7; ++i)
    {
        Console.WriteLine(matchesTuples[i, 0] + " " + matchesTuples[i, 1] + " + "
            + matchesTuples[i, 2] + " " + matchesTuples[i, 3]);
    }
    Console.WriteLine("------------------------------");
}

static int counter = 0;

static void placeTeam(int level, string[] teams, string[,] matchesTuples, bool[,] presentPlayers)
{
    if (level == teams.Length)
    {
        if (!SolutionIsOK(matchesTuples)) { return; };
        WriteSolution(matchesTuples);
        counter++; // solution found
        return;
    }

    string team = teams[level++];
    for (int i = 0; i < 7; ++i)
    {
        if (presentPlayers[i, team[0] - 'A']
         || presentPlayers[i, team[1] - 'A'])
        {
            continue;
        }
        presentPlayers[i, team[0] - 'A'] = true;
        presentPlayers[i, team[1] - 'A'] = true;

        for (int j = 1; j < 4; ++j)
        {
            if (matchesTuples[i, j] != null) { continue; }
            if (j == 3 && (matchesTuples[i, 2] == null)) { continue; }
            matchesTuples[i, j] = team;

            placeTeam(level, teams, matchesTuples, presentPlayers);

            matchesTuples[i, j] = null;
        }

        presentPlayers[i, team[0] - 'A'] = false;
        presentPlayers[i, team[1] - 'A'] = false;
    }
}

static void Main(string[] args)
{
    string[,] matchesTuples = new string[7, 4]; // AE BF + CG DH 
    bool[,] presentPlayers = new bool[7, 8];  // ABCDEFGH
    string[] teams = new string[28]; // AB, AC, AD, ..., BC, BD, ..., GH

    int i = 0;
    for (char c1 = 'A'; c1 < 'H'; ++c1)
    {
        for (char c2 = c1; ++c2 <= 'H';)
        {
            teams[i] = c1.ToString() + c2;
            if (c1 == 'A')
            {
                matchesTuples[i, 0] = teams[i];
                presentPlayers[i, c1 - 'A'] = true;
                presentPlayers[i, c2 - 'A'] = true;
            }
            ++i;
        }
    }

    placeTeam(7, teams, matchesTuples, presentPlayers);

    Console.WriteLine("Found " + counter);
    Console.ReadKey();
}

唯一棘手的部分是SolutionIsOK函数。它解决了最后一个未被解决的对称性。这两种情况是平等的:

代码语言:javascript
运行
AI代码解释
复制
AC BD + EG FH
AD BC + EH FG


AC BD + EH FG
AD BC + EG FH

因为第二次匹配只发生了变异。只有当这些匹配包含相同的4个人时,才能进行第二次匹配。可以检测到这种情况,我们只能选择按字母顺序排列的情况。这正是SolutionIsOK所做的。

票数 1
EN

Stack Overflow用户

发布于 2020-11-06 14:20:33

你可以检查一下约束满足问题。它是关于SAT解算器或SMT解算器。

也许你的问题可以被定义为CS问题。

可以解决CS问题的示例库:

我知道我给你的是图书馆,不是算法,但也许没有必要重新发明轮子。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64722148

复制
相关文章
给定括号对数量,输出所有可能组合
如果给你一个题目,“给出一个正整数,表示一共有多少对括号,如何输出所有括号可能的组合?”,你会如何做呢?
孟君
2019/08/26
1.9K0
给定整数数组,输出所有和为S的可能组合
如果给你一个题目,“给定一个整数数组和一个目标数S,如何输出该数组中所有和为S的可能组合?”,你会如何做呢?
孟君
2019/08/26
2K0
PHP实现给定一列字符,生成指定长度的所有可能组合示例
本文实例讲述了PHP实现给定一列字符,生成指定长度的所有可能组合。分享给大家供大家参考,具体如下:
用户8675788
2021/07/13
9980
输出指定括号对数的所有可能组合
广度优先搜索的目的是先得到完整的括号对(), 这种情况下需要需要考虑如下两种情况:
孟君
2023/02/23
8860
输出指定括号对数的所有可能组合
Database、Table的所有约束
列出Database或Table的所有约束 很多时候我们想使用像 INSERT、UPDATE、DELETE 这样的DML命令。有时候因为某个表被设置约束,导致我们操作该表出现错。拿到一个新的数据库,如果不知道哪些表被设置约束,一定让人很痛苦。 如果我们能够列出所有的约束,很多错误就可以避免。下面有两个方法列出约束。 方法 一 使用 sys.objects 获得约束信息。 — 显示数据库中所有约束 SELECT * FROM sys.objects WHERE type_desc LIKE ‘%CONSTRA
数据分析
2018/03/01
6620
LeetCode - 所有可能的路径
我又重新开始更新LeetCode了,以后工作日更新LeetCode,周末更新东野圭吾的小说
晓痴
2019/07/24
7830
LeetCode - 所有可能的路径
Python使用筛选法计算小于给定数字的所有素数
代码思路:首先列出指定范围内所有候选数字,然后从前往后依次选择一个数字去除以后面所有数字,能够被整除的肯定不是素数,把这些数字过滤掉,然后重复这个过程,直到选择的除数大于最大数字的平方根为止。代码主要演示内置函数filter()和切片的用法,实际上这个算法的效率并不是很高。 def primes2(maxNumber): '''筛选法获取小于maxNumber的所有素数''' #待判断整数 lst = list(range(3, maxNumber, 2)) #最大整数的平方根 m =
Python小屋屋主
2018/04/16
1.6K0
矩阵组合matlab,matlab中矩阵的所有组合[通俗易懂]
X = perms(1:N); % # Permuations of column indices
全栈程序员站长
2022/08/01
1.5K0
LeetCode:所有可能的路径_797
给你一个有 n 个节点的 有向无环图(DAG),请你找出所有从节点 0 到节点 n-1 的路径并输出(不要求按特定顺序)
Yuyy
2022/06/28
3720
LeetCode:所有可能的路径_797
组合优化(二):换手约束下的最优模型
接着上一篇写,上篇结尾提到的一个点感兴趣的童鞋很多,就是信息分成快慢两期之后,怎么样进行合成。这边我列一个书里面的小例子供大家参考吧,学习思想。
量化小白
2023/03/19
5120
组合优化(二):换手约束下的最优模型
LeetCode-797-所有可能的路径
题目来自于力扣https://leetcode-cn.com/problems/all-paths-from-source-to-target
benym
2022/07/14
4550
给定一个罗马数字,将其转换成整数_计算并输出给定整数n的所有因子
例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII ,即为 X + II 。 27 写做 XXVII, 即为 XX + V + II 。 通常情况下,罗马数字中小的数字在大的数字的右边。 但也存在特例,例如 4 不写做 IIII,而是 IV。 数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。 同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况: I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。 X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。 C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。 给定一个整数,将其转为罗马数字。输入确保在 1 到 3999 的范围内。
全栈程序员站长
2022/11/10
5150
如何输出字符窜的所有组合
例如“abc”输出a,b,c,ab,ac,bc,abc #include<stdio.h> void DFS(char str[],char ss[],int pos,int cnt,int n) { if(n==pos) { ss[cnt]='\0'; if(cnt!=0) printf("%s\n",ss); return ; } ss[cnt]=str[pos]; DFS(str,ss,pos+1,cnt+1,n)
用户1624346
2018/04/17
1.2K0
计算给定多项式在给定点X处的值
//计算多项式求值 解答:多项式系数可以用数组来存储; POW 函数 原型:在TC2.0中原型为extern float pow(float x, float y); , 而在VC6.0中原型为double pow( double x, double y ); 头文件:math.h/cmath(C++中) 功能:计算x的y次幂。 返回值:x不能为负数且y为小数,或者x为0且y小于等于0,返回幂指数的结果。 返回类型:double型,int,float会给与警告! //计算多项式求值 f(x,n)=x-x^2
互联网金融打杂
2018/04/03
9020
问与答62: 如何按指定个数在Excel中获得一列数据的所有可能组合?
Q:数据放置在列A中,我要得到这些数据中任意3个数据的所有可能组合。如下图1所示,列A中存放了5个数据,要得到这5个数据中任意3个数据的所有可能组合,如列B中所示。如何实现?
fanjy
2019/08/13
6.1K0
问与答62: 如何按指定个数在Excel中获得一列数据的所有可能组合?
[世界杯]根据赔率计算各种组合可能性与赔率
其中0.9913为初步计算得到的体彩抽水率,实际不准确,该数值仅供初步计算,之后需要根据计算所得的概率进行相应修正。
机器学习AI算法工程
2022/12/13
1K0
[世界杯]根据赔率计算各种组合可能性与赔率
LeetCode 797. 所有可能的路径(DFS)
给一个有 n 个结点的有向无环图,找到所有从 0 到 n-1 的路径并输出(不要求按顺序)
Michael阿明
2020/07/13
7670
LeetCode 797. 所有可能的路径(DFS)
如何使用python计算给定SQLite表的行数?
计算 SQLite 表中的行数是数据库管理中的常见任务。Python凭借其强大的库和对SQLite的支持,为此目的提供了无缝的工具。
很酷的站长
2023/08/11
7240
如何使用python计算给定SQLite表的行数?
B - 组合数的计算【C++】
给定n组整数(a,b),计算组合数C(a,b)的值。如C(3,1)=3,C(4,2)=6。
来杯Sherry
2023/05/25
2990
点击加载更多

相似问题

计算给定列表中所有可能的组合

115

计算给定字符到给定长度的所有可能组合。

36

Java计算给定整型数组的所有可能组合

21

如何获得所有可能的约束组合?

30

计算所有可能的组合

10
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档