n == 1 (A)
n == 2 (AB)
n == 3 (AB)C , A(BC)
n== 4 ((AB)C)D, (A(BC))D, A((BC)D), A(B(CD)), (AB)(CD)
我的初始代码在下面,由
调用 possible_groupings(4) #4 matrices
def possible_groupings(n):
print("Possible Groupings : ")
total = 0
if(n==1):
print('A')
total = total + 1
elif(n==2):
print('(AB)')
total = total + 1
else:
a = 2
while(a <= n-1):
b = 0
while((b+a) <= (n )):
c = b
d = 0
substr = ''
while (d < c):
substr = substr + chr(65 + d)
d = d + 1
if substr != '':
if len(substr) == 1:
print( substr, end = '')
else:
print('(' + substr + ')', end = '')
print('(', end = '')
while (c < (b +a)):
print(chr(65 + c), end = '');
c = c + 1
print(')', end = '')
e = b+a
substr = ''
while (e < n):
substr = substr + chr(65 + e)
e = e + 1
if substr != '':
if len(substr) == 1:
print( substr, end = '')
else:
print('(' + substr + ')', end = '')
print('')
total = total + 1
b = b + 1
a = a + 1
print('Total : ' + str(total))
当我的inout为4个矩阵时,以上代码的输出为:
(AB)(CD)
A(BC)D
(AB)(CD)
(ABC)D
A(BCD)
如何修改我的代码。矩阵数必须在1-26的范围内。我现在头疼。请帮忙。
答案 0 :(得分:6)
这是一种递归方案,可从头到尾使用。
它被实现为生成器part
,以 last 乘法开始。最后的乘法必须在两个因子之间,两个因子的左边是第一个 j (下面代码中的变量cut
)乘积(“左块”)的乘积,而右边是是剩余矩阵(“右图块”)上的乘积。 j 可以是1到 N -1之间的任何值,其中 N 是链中矩阵的数量。
因此,要枚举所有分组,我们必须遍历 j 。对于每个 j ,我们必须将左侧块的每个分组与右侧块的每个分组进行组合。为了枚举块的分组,我们使用part
本身,即递归。
def part(names, top=True):
lr = ('', '') if top else '()'
if len(names) <= 1:
yield names
elif len(names)==2:
yield names.join(lr)
else:
for cut in range(1, len(names)):
for left in part(names[:cut], False):
for right in part(names[cut:], False):
yield (left+right).join(lr)
相同的逻辑可用于最小化器。这可以利用functools.lru_cache
提供的备忘录:
from functools import lru_cache
from string import ascii_uppercase
@lru_cache(None)
def _min_no_mult(dims):
if len(dims) == 2:
return 0, 'x'
elif len(dims)==3:
return dims[0]*dims[1]*dims[2], 'xx'.join('()')
cuts = ((cut, *_min_no_mult(dims[:cut+1]), *_min_no_mult(dims[cut:]))
for cut in range(1, len(dims)-1))
return min((mnl + mnr + dims[0]*dims[-1]*dims[cut], (nml+nmr).join('()'))
for cut, mnl, nml, mnr, nmr in cuts)
def min_no_mult(dims, names=None):
mn, argmn = _min_no_mult(tuple(dims))
names = iter(ascii_uppercase if names is None else names)
argmn = argmn[1:-1] if len(dims) > 2 else argmn
argmn = ''.join(next(names) if a=='x' else a for a in argmn)
return mn, argmn
演示:
>>> for i, j in enumerate(part(ascii_uppercase[:6])):
... print(i, j)
...
0 A(B(C(D(EF))))
1 A(B(C((DE)F)))
2 A(B((CD)(EF)))
3 A(B((C(DE))F))
4 A(B(((CD)E)F))
...
38 ((A((BC)D))E)F
39 (((AB)(CD))E)F
40 (((A(BC))D)E)F
41 ((((AB)C)D)E)F
由于具有记忆力,最小化器可以轻松处理大量尺寸:
>>> import numpy as np
>>> dims = np.clip(np.arange(-1, 26), 1, None)
>>> np.random.shuffle(dims)
>>> dims
array([ 5, 25, 1, 4, 14, 24, 7, 15, 2, 12, 11, 9, 18, 8, 19, 13, 23,
17, 1, 22, 21, 1, 16, 6, 3, 20, 10])
>>> min_no_mult(dims)
(3383, '(AB)((((((((((CD)E)F)G)H)(I(J(K(L(M(N(O(P(QR))))))))))((ST)U))((VW)X))Y)Z)')
我们可以查询一些基本的缓存统计信息:
>>> _min_no_mult.cache_info()
CacheInfo(hits=5450, misses=351, maxsize=None, currsize=351)
这可能看起来并不令人印象深刻,但请记住,每次点击都将剪切整个子树。
实际上,我们可以再次使用循环计划并计算包围次数:
@lru_cache(None)
def count(n):
if n <= 2:
return 1
else:
return sum(count(cut) * count(n-cut) for cut in range(1, n))
对于26个矩阵,可以使用多种方法将其括起来:
>>> print(f"{count(26):,d}")
4,861,946,401,452
答案 1 :(得分:3)
您似乎想将字符集划分为所有可能的子集,尽管您似乎没有考虑非连续的分组(例如(AC)(DB))。如果是这样,则存在众所周知的解决方案的一个众所周知的问题。例如,请参见How to find all partitions of a set。
答案 2 :(得分:3)
有Catalan(nmatrices-1)
个组合,我们可以使用简单的平衡括号算法来生成预组合。这是获取括号(用于比较)和矩阵预组合的代码。
但是我还没有找到设置闭合括号的简明方法(cx参数是我尝试计算乘法并推导出给定点的闭合括号的数量)。
也许有人可能会看到简单的公式/定律来得出最终结果。
def genparens(s, maxlen, l, r):
if l + r == maxlen * 2:
print(s)
return
if l < maxlen:
genparens(s + '(', maxlen, l + 1, r)
if r < l:
genparens(s + ')', maxlen, l, r + 1)
alpha = "ABCDEFGHIJK"
def genmatparens(s, n, l, r, ci, cx):
if l + r == n * 2:
s = s + alpha[ci] # + ")" * cx
print(s)
return
if l < n:
genmatparens(s + '(', n, l + 1, r, ci, cx + 1)
if r < l:
s += alpha[ci]
#s += ")" * cx
s += "x"
genmatparens(s, n, l, r + 1, ci + 1, 1)
genparens("", 3, 0, 0)
print()
genmatparens("", 3, 0, 0, 0, 0)
((()))
(()())
(())()
()(())
()()()
current should be
(((AxBxCxD (((AxB)xC)xD)
((Ax(BxCxD ((Ax(BxC))xD)
((AxBx(CxD ((AxB)x(CxD))
(Ax((BxCxD (Ax((BxC)xD))
(Ax(Bx(CxD (Ax(Bx(CxD)))