Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 是否有从一组公式中提取最小笛卡尔积数的算法?_Algorithm_Math_Cartesian Product - Fatal编程技术网

Algorithm 是否有从一组公式中提取最小笛卡尔积数的算法?

Algorithm 是否有从一组公式中提取最小笛卡尔积数的算法?,algorithm,math,cartesian-product,Algorithm,Math,Cartesian Product,例如,我们有一组公式如下: B*2*j B*3*i B*3*j C*2*j C*3*i C*3*j D*2*i D*2*j D*3*i D*3*j 我们可以用三个笛卡尔积来表示上面的公式: D*(2+3)*(i+j) (B+c)*3*(i+j) (B+C)*2*j 所以总数是3。我们还可以: 3*(B+C+D)*(i+j) 2*(B+C)*D 2*D*(i+j) 这也是3 我想问,有没有一种算法可以从一组公式中确定笛卡尔积的最小数目?还有这些产品吗?首先,我将编写一组公式,作为用+分隔的术

例如,我们有一组公式如下:

B*2*j
B*3*i
B*3*j
C*2*j
C*3*i
C*3*j
D*2*i
D*2*j
D*3*i
D*3*j
我们可以用三个笛卡尔积来表示上面的公式:

D*(2+3)*(i+j)
(B+c)*3*(i+j)
(B+C)*2*j
所以总数是3。我们还可以:

3*(B+C+D)*(i+j)
2*(B+C)*D
2*D*(i+j)
这也是3


我想问,有没有一种算法可以从一组公式中确定笛卡尔积的最小数目?还有这些产品吗?

首先,我将编写一组公式,作为用
+
分隔的术语,因为您所寻找的转换在代数上是有意义的(除了您不想将
2+3
这样的数字组合成
5

您可以使用的基本操作是分解:将两个术语(如
ABC+ABD)组合成
AB(C+D)
。根据您的评论,您只能生成由一系列单因子项组成的新因子,如上例中的
C+D
;不允许将例如
ABCD+ABDE
分解为
AB(CD+DE)

当且仅当两个k因子项完全共享k-1因子时,您可以对其进行因子分解。(例如,在我的
ABC+ABD
示例中,k=3)。每次这样的因子分解都会将集合中的项数减少1:2,然后删除2,再添加1

当组合3个或3个以上术语时,多次这样做是有效的:
ABC+ABD+ABE
可以首先分解为
AB(C+D)+ABE
,然后这2个术语再次分解为
AB(C+D+E)
。请注意,我们以何种顺序列出总和中的项或产品中的因子并不重要,在构建包含3个或更多项的因子时,我们以何种顺序执行因子分解步骤也不重要

然后,我们可以将问题框架化为图中的搜索问题,其中起始顶点对应于原始公式(
B*2*j+B*3*i+…+D*3*j
),并且从每个顶点v向其子顶点发射弧,每个弧对应于对v执行某些因式分解的结果。v将有一个子顶点用于每个可能在其上执行的因式分解;如果v中有m个项,那么这意味着在最坏的情况下,它最多可以有m(m-1)/2个子项,因为可能所有m个项都共享k-1因子的完整补充,这意味着它们中的任何一对都可以组合

如果一个顶点没有一对可以通过因子分解组合的项,那么它就是一个“叶子”——它没有子项,不能进一步处理。我们想要找到的是一个具有最少项数的叶顶点。因为每一个因子分解,对应于图中的一个弧,减少了1个项的数量,这相当于搜索一个可能最深的顶点。这可以使用DFS或BFS完成。但是请注意,使用这种方法可以多次生成相同的表达式(顶点),因此维护记录所有已处理表达式的哈希表
seen
,对于性能至关重要;然后,如果我们访问一个顶点,尝试为它生成一个子对象,并且看到这个子对象已经在
中看到了
,我们将避免再次访问这个子对象

为了避免同一表达式通过同一组factorsation的多个不同顺序生成的现象,您可以添加一条规则:以某种方式排列v的子factorsation,这样,如果有n个子元素,它们对应于此顺序中的factorsation 1、2、…、n,并记录在单独的“已跳过”中每个子顶点中的字段是为生成此子顶点而跳过的一组早期(在排序中)因式分解。然后,在访问顶点时,避免将其任何“已跳过”的因式分解生成为子代,因为这样做会创建一个与其他现有顶点相同的顶点(通过以相反顺序执行相同的操作对)


可能还有其他可用的加速功能可以减少最初生成的重复顶点的数量,但这应该足以获得小问题的结果。

以矩阵形式写下求和。然后你需要的是矩阵的秩,以及相应的并矢积分解。这种分解远非独一无二

            [ 3  5 ]   [ i ] 
[ B C D ] * | 3  5 | * [ j ]
            [ 5  5 ]   

正如我们所看到的,中间的矩阵具有满秩2</p>。



如果您打算将2和3也用作变量,那么您需要将3阶张量分解为最少数量的分解项,即向量的张量积。

您可能需要将其发布。谢谢。我不知道。。如果你想把一个问题转移到另一个网站上,你可以标记它并要求它被迁移,或者干脆删除它并在适当的网站上重新提问。我希望我的问题出现在两个网站上。因为,这个问题在计算机科学中可能有一个相关的算法。如果你真的想把数字(2和3)当作不可组合的量,请将它们重命名为字母(例如x和y)。目前,它们只是通过看起来可以组合来混淆问题(例如,如果你的公式是一个总和,
B*2*j
B*3*j
可以组合成
B*5*j
,乘积公式
D*(2+3)*(i+j)
可以简化为
D*5*(i+j)
).这个算法的时间复杂度是多少?看起来每个顶点都有很多分支。@injoy:如果有n个可能的(部分)因式分解,那么如果没有“已跳过”的概念,它应该访问每个顶点一次,但它还花费时间为每个节点生成多达O(m^2)个子节点,所有这些子节点都可能会因为以前见过而被丢弃。n可能与m叶上标记树的数量一样大。使用“已跳过”,应该可以避免生成被