【发布时间】:2012-03-16 21:25:08
【问题描述】:
我正在寻找一种二维组合算法..如果这是正确的措辞。我对 PHP 非常有经验,但对算法和高级数学不熟悉,所以请多多包涵。
我有一组元素,我想将它们与另一组元素组合并计算所有可能的组合,以便之后进行分析。集合中元素的数量永远不会改变,两个集合总是有五个元素:
$set1= array('A', 'B', 'C', 'D', 'E');
$set2= array('One', 'Two', 'Three', 'Four', 'Five');
不知道这是否是正确的措辞,但我想查看第 1 组项目的所有组合,在第 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 万个组合,我可能需要提前进行计算,保存结果分析并在实时应用执行期间使用它?
- 有一些限制(例如:设置 2 项“一”、“二”和“三”应始终至少包含一组 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 也在那里
- 等等..
该工具的目的是找出哪些单位进入哪个池的最佳组合。这些是规则:
- 总是从大约 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 号池:
等等……
所以我想做的事情是:
- 采用存在的所有可能的单元和池组合。
- 遍历它们并根据单元和池之间的协同作用为组合分配“战略价值”。
- 选取“策略价值”最高的前 10 个组合
第 2 步和第 3 步没问题。 我遇到的问题是生成池中所有可能的单元组合。
希望这是对问题的更清晰的描述
【问题讨论】:
-
“设置 2 项“一”、“二”和“三”应始终至少包含一组 1 中的一项”,那么这不应该反映在您的示例中吗?
-
这让我想起了几年前读到的一个组合数学问题。我感觉有 5 个元素的解决方案,但没有已知的解决方案 6... 或类似的东西。您可能需要扩展您想要实现的确切目标。也许你根本不需要编写获奖算法:)
-
在分割数组中排序是否重要?例如对于这个问题,array('A','B','C') 是否认为与 array('B','C','A') 相同?
-
@Ward Muylaert:如前所述,这不是必需的。分析过程中会丢弃无用的结果。
-
@Pete:是一款策略游戏的分析工具。单元(第 1 组)及其位置(第 2 组)的组合将根据与这些位置相关的单元特征产生不同的值(在分析期间)。可能性的数量有点压倒性,所以我想采取所有可能性,分析集合,分配一个值,然后选择前 3 个可能性。
标签: php algorithm combinations cartesian-product divide