当可以将角色组合到其他角色时,如何从列表中获取所有角色组合

时间:2019-05-23 21:11:32

标签: c# algorithm permutation combinatorics

上下文:考虑一个具有N个6面骰子的游戏。骰子的每一面都代表滚动:命令(COM),科学(SCI),工程师(ENG),医疗(MED),安全性(SEC),以及未用于此问题的一面。游戏的目标是在挑战卡上使用骰子,其中列出了解决挑战所需的不同角色。例如,我的挑战卡可能需要1个COM,1个SCI和1个MED。因此,如果我掷骰子并获得1个COM,1个SCI和1个MED,则可以将它们应用于挑战卡以解决挑战。

其他规则:除了骰子角色与挑战卡要求的1:1映射外,骰子还可以通过以下方式组合以更改

  1. 2 MED可以成为1 SCI; 2 SCI可以成为1 MED。
  2. 2 ENG可以成为1 SEC; 2 SEC可以变成1 ENG。
  3. COM角色+任何其他角色都可以成为任何角色。这样COM + SEC可以成为ENG。
  4. 任何三个角色都可以成为不同的角色。因此COM + SEC + ENG可以成为MED。

问题:我想生成挑战卡要求的所有可能骰子组合的列表。例如,假设挑战卡需要1 SCI,1 ENG和1 MED。手动,我看到我需要:

如果完成1次SCI,1次ENG和1次MED(A,B,C)
如果完成1个SCI,1个ENG和2个SCI(A,B,D)
如果完成1个SCI,1个ENG和COM等(A,B,E)
如果1个SCI,1个ENG和另外3个已完成(A,B,F)

如果完成1次SCI,2秒SEC和1次MED(A,G,C)
如果完成1个SCI,2个SEC和2个SCI(A,G,D)
如果完成1次SCI,2次SEC和COM等(A,G,E)
如果完成1次SCI,2次SEC和3次其他(A,G,F)

如果已完成(A,E,C),则完成1个SCI,COM​​和其他,以及1个MED
如果1个SCI,COM​​和其他,以及2个SCI已完成(A,E,D)
如果1个SCI,COM​​和其他,以及COM和其他,则已完成(A,E,E)
如果1个SCI,COM​​和其他以及3个其他已完成(A,E,F)

如果已完成(A,F,C),则完成1个SCI,3个其他和1个MED
如果1个SCI,3个其他SCI和2个SCI已完成(A,F,D)
如果1个SCI,3个其他,COM等,则完成(A,F,E)
如果1个SCI,3个其他和3个其他完成(A,F,F)

此外,我需要将初始的1个SCI替换为2个MED,COM​​ +其他设备以及具有相同分组的其他3个设备。

问题:尽管有这些示例,但我仍在努力寻找可以针对其进行编码的算法。有人可以提供一种算法,该算法可以将其他角色的交换角色合并为所有有效组合列表的一部分吗?

1 个答案:

答案 0 :(得分:1)

您可以将其表示为语法。您的起始状态是名义(直接)挑战要求。您的边缘代表从该状态到另一状态的有效过渡,每个过渡都显示相反的过渡。

例如,对于您的卡(SCI,ENG,MED),将从三个元素的状态开始。现在,您将包括每个转换规则可达到的状态(组合):

SCI => [MED, MED]
MED => [SCI, SCI]
b => [COM, a] for any (a, b), where a != b
d => [a, b, c] for any (a, b, c, d) where a, b, c, != d

您可以将每个规则表示为一个函数。保留已达到的状态(组合)列表。将问题视为图遍历,并使用标准算法从给定的起始状态查找图的闭合。对于初学者:

(SCI, ENG, MED)
apply rule 1
(ENG, MED^3) push this to your `search` list
apply rule 2
(SCI^3, ENG) push this to your `search` list
apply rule 3 to "SCI"
(a, COM, ENG, MED) for all `a` != "SCI"; push these ...

看看这是怎么回事?

每次通过时,您将第一项从列表中删除,使用规则将其更改为环,将所有新状态推入列表。您需要跟踪已处理的状态,并检查每个状态中的元素是否超过N个。

您可以按照该大纲进行工作吗?