我正在寻找一种二维组合算法......如果这是正确的措辞。我对 PHP 非常有经验,但对算法和高级数学没有经验,所以请多多包涵。
我有一组元素,我想将它们与另一组元素组合并计算所有可能的组合,以便之后进行分析。集合中元素的数量永远不会改变,两个集合总是有五个元素:
$set1= array('A', 'B', 'C', 'D', 'E');
$set2= array('One', 'Two', 'Three', 'Four', 'Five');
不知道这是否是正确的措辞,但我想查看Set 1 项目的所有组合,在 Set 2 的项目之间进行划分。两个集合中的所有元素只能在每种可能性中使用一次,并且 Set 1 元素可以在 Set 2 元素中组合在一起,因此我得到一个看起来像这样的结果数组(一些随机值作为示例):
$possibilities= array(
0 => array(
'One' => array('A'),
'Two' => array('B'),
'Three' => array('C'),
'Four' => array('D'),
'Five' => array('E'),
),
1 => array(
'One' => array('A', 'B', 'C'),
'Two' => array('D'),
'Three' => array('E'),
'Four' => array(),
'Five' => array(),
),
2 => array(
'One' => array('C'),
'Two' => array(),
'Three' => array('A'),
'Four' => array('B'),
'Five' => array('D', 'E'),
),
3 => array(
'One' => array(),
'Two' => array(),
'Three' => array('A', 'B', 'C', 'D', 'E'),
'Four' => array(),
'Five' => array(),
),
);
等等……那些价值观。欢迎对此提出任何反馈,特别是:
- 如何在 PHP 中编写这样的代码?通过递归函数?我是否使用笛卡尔积算法?
- 有多少种组合可能?5^10 ?
- 根据前一点:在 Web 应用程序中实时处理这些数据是否可行?如果我有 1000 万个组合,我想我可能需要事先进行计算,保存结果分析并在实时应用程序执行期间使用它?
- 有一些限制(例如:Set 2 items 'One', 'Two' and 'Three' should always have at least one item from Set 1)但无用的组合将在之后的分析过程中被丢弃,因此无需将其包含在组合算法,除非它可以通过在那时构建这些来减少计算时间?
我的问题可能不是很清楚,所以请问我是否需要提供更多或更好的信息。
提前致谢
2012 年 2 月 28 日更新
我已经尝试了我在互联网上找到的 Power Set 和笛卡尔积函数的 PHP 实现(这种东西有点超出我自己尝试和编码的能力)。所以当我执行这段代码时:
$powerset= powerSet(array('A', 'B', 'C'));
$cartesian = cartesian(array(
'Set1' => $powerset,
'Set2' => array('One', 'Two', 'Three')
));
这是 powerSet 函数在 $powerset 中的内容:
Array (
[0] => Array ()
[1] => Array (
[0] => A
)
[2] => Array (
[0] => B
)
[3] => Array (
[0] => B
[1] => A
)
...
这就是笛卡尔函数返回的内容:
Array (
[0] => Array (
[Set1] => Array ()
[Set2] => One
)
[1] => Array (
[Set1] => Array (
[0] => A
)
[Set2] => One
)
[2] => Array (
[Set1] => Array (
[0] => B
)
[Set2] => One
)
[3] => Array (
[Set1] => Array (
[0] => B
[1] => A
)
[Set2] => One
)
...
所以它有点像我想要的,但不是最难的部分。它“单独”考虑组合并且不在 Set2 中分配 Set1,确保所有三个 Set2 项目都使用所有 Set1 项目。
- 我是否误解了这两个功能的使用?我想这是我对如何结合 Power Set 和笛卡尔积来实现我的结果没有正确理解的东西。我应该在 cartesian() 函数中调用 powerSet() 函数吗?
- 也许那些特定的 PHP 函数不能完全满足我的目的?我在这里找到了它们:
另一个更新:在没有编程参考的情况下重述问题
这个问题与我为战略游戏创建的分析工具有关。每次使用该工具时,玩家可以从大量单位中选择 5 个不同的单位。这些单元可以以多种方式与其他(静态)实体(我们称这些“池”)组合。如果将这些单位与某些池相结合,这些单位具有可能会或可能不会改善玩家策略的特征。例如:
- A单元喜欢在1号池,但不喜欢在2号池
- 单元 B 讨厌在池 1 中,除非单元 A 也在那里
- ETC..
该工具的目的是找到哪些单元进入哪个池的最佳组合。这些是规则:
- 从大约 50 个集合中总是选择 5 个不同的单元。所有这些单元都有不同的特性。
- 总是有相同的 5 个池。它们具有不同的特征,但池不是从更大的集合中选择的,它们总是相同的。
- 每个池可以包含多个单元,从 0 到 5。
- 每个单元只能在一个池中。
输入是:
- 5 个变量单位的列表:A、B、C、D、E
- 5 个静态池的列表:Pool1、Pool2、Pool3、Pool4、Pool5
根据上述规则,输出应该是这两个列表之间的所有可能组合。一些例子:
组合1
- 池 1:A
- 池 2:B
- 池 3:C
- 池 4:D
- 池 5:E
组合2
- 池 1:A、B、C
- 池 2:D
- 池 3:E
- 池 4:
- 池 5:
组合3
- 池 1:C
- 池 2:
- 池 3:A
- 池 4:B
- 第 5 组:D、E
组合4
- 池 1:
- 池 2:
- 第 3 组:A、B、C、D、E
- 池 4:
- 池 5:
ETC...
所以我想做的是:
- 采用存在的所有可能的单元和池组合。
- 遍历它们并根据单元和池之间的协同作用为组合分配“战略价值”。
- 选取“策略价值”最高的前 10 个组合
第 2 步和第 3 步没有问题。我遇到的问题是生成池中单元的所有可能组合。
希望这是对问题的更清晰的描述