Python迭代唯一的交换方程

Python迭代唯一的交换方程,python,commutativity,Python,Commutativity,受到的数学启发,我很好奇得到一个数字n需要多长时间,在这个数字n中,我可以使用数字1,以及一些像加法和减法这样的运算,在二进制基数中。目前,我有这样的编码: import itertools as it def brute(m): out = set() for combo in it.product(['+','*','|'], repeat=m): x = parse(combo) if type(x) == int and 0 < x

受到的数学启发,我很好奇得到一个数字n需要多长时间,在这个数字n中,我可以使用数字1,以及一些像加法和减法这样的运算,在二进制基数中。目前,我有这样的编码:

import itertools as it

def brute(m):
    out = set()
    for combo in it.product(['+','*','|'], repeat=m):
        x = parse(combo)
        if type(x) == int and 0 < x-1:
            out.add(x)
    return out

def parse(ops):
    eq = ""
    last = 1
    for op in ops:
        if op == "|":
            last *= 2
            last += 1
        else:
            eq += str(last)
            eq += op
            last = 1
    eq += str(last)
    return eval(eq)
如果我把事情记下来,这将是相当不错的,但我不确定是否有比这更通灵或有效的方法。此外,如果我决定在像减法这样的运算中添加更多的运算,这也不能完全概括

我希望能够深入了解是否有一些模块或简单方法可以有效地迭代操作组合。目前,
itertools.product
的复杂性为0(3^m)。然而,通过记忆和使用
brute2
方法,我似乎可以将事情的复杂性降低到O(| brute(m-1)|),这似乎是渐进的~O(1.5^m)。虽然我对第二种方法比较满意,但如果有一种更通用的方法可以扩展到任意数量的操作,其中一些操作是可交换的,那就太好了

更新:

我现在已经把第二个想法编码好了。有了这个,当我的旧代码在20次操作后被卡住数小时时,我能够快速地在42次操作中获得所有可访问的数字。以下是新代码:

memo1 = {0:{1}}
def brute1(m):
    if m not in memo1:
        out = set(brute2(m+1))
        for i in range(m):
            for a,b in it.product(brute1(i),brute2(m-i)):
                out.add(a+b)
        memo1[m] = set(out)
    return memo1[m]
    
memo2 = {0:{1}}
def brute2(m):
    if m not in memo2:
        out = set()
        for i in range(m):
            for x in brute2(i):
                out.add(x*(2**(m-i)-1))
        memo2[m] = set(out)
    return memo2[m]
我要概括一下,你对所有的交换运算,[op_1,op_2,…op_x]进行排序,让brute(n,0)返回所有能用n个非交换运算得到的数,然后得到:

def brute(m):
    out = set()
    for k in range(m):
       for a,b in it.product(brute(k),brute2(m-k)):
           out.add(a+b)
memo = {}
def brute(n,i):
    if (n,i) not in memo:
        out = brute(n,i-1) #in case I don't use op_i
        for x in range(1,n): #x is the number of operations before my last use of op_i, if combo = (op_i,"|","+","+","*","+",op_i,"*","|"), this case would be covered when x = 6
            for a,b in it.product(brute(x,i),brute(n-x-1,i-1)):
                out.add(a op_i b)
        memo[(n,i)] = out
    return memo[(n,i)]

但是,您必须小心操作顺序。如果我做加法和乘法,事情会完全不同,这会说不同的事情。如果有一个像pEdDas这样的层次结构,并且你不想考虑括号,我相信你只是列出了按优先级递减顺序的操作,即OPY1是你做的第一个操作。如果你允许一般括号,那么你应该有这样的东西:我相信:

memo = {0:1}
def brute(m, ops):
    if m not in memo:
        out = set()
        for i in range(m):
            for a,b in it.product(brute(i),brute(m-i-1)):
                for op in ops:
                    out.add( op(a,b) )
        memo[m] = out
    return memo[m]

我更感兴趣的是,我们有某种PEMDAS系统,括号是由操作顺序暗示的,但对任何一种情况的有效性/效率的反馈仍然是受欢迎的。

导致“10958”的有趣视频问题。你是否试图创建一个例程,在输入是数字1的情况下生成Teneja的结果?或多或少,我现在用二进制和较少的操作来做,并且观察到增长率似乎收敛到一个特定的指数。然而,上下文或多或少只是我的问题的一个框架,即如何有效地生成交换唯一的操作组合。请提供一些示例来描述您期望实现的目标。我知道您只想生成
+
+
中的一个;不太直接的等价物呢,比如三项表达式?你试过用记忆化或转换语法做什么吗?我还没有实现记忆化,我倾向于开始纠结于此。然而,我不熟悉转换语法和三项表达式。有趣的视频导致了“10958”问题。你是否试图创建一个例程,在输入是数字1的情况下生成Teneja的结果?或多或少,我现在用二进制和更少的操作来做,我观察到增长率似乎收敛到一个特定的指数。然而,上下文或多或少只是我的问题的一个框架,即如何有效地生成交换唯一的操作组合。请提供一些示例来描述您期望实现的目标。我知道您只想生成
+
+
中的一个;不太直接的等价物呢,比如三项表达式?你试过用记忆化或转换语法做什么吗?我还没有实现记忆化,我倾向于开始纠结于此。但是,我不熟悉转换语法和三项表达式。