Python 算术运算中的蛮力搜索算法

Python 算术运算中的蛮力搜索算法,python,algorithm,math,Python,Algorithm,Math,因为我是Python初学者,所以我正在尝试学习一些网站上的代码。我在GitHub中发现了一种算法,它对算术表达式进行了优化。代码是: #!python import operator import itertools from fractions import Fraction operations = dict() operations['+'] = operator.add operations['-'] = operator.sub operations['/'] = operator.

因为我是Python初学者,所以我正在尝试学习一些网站上的代码。我在GitHub中发现了一种算法,它对算术表达式进行了优化。代码是:

#!python
import operator
import itertools
from fractions import Fraction

operations = dict()
operations['+'] = operator.add
operations['-'] = operator.sub
operations['/'] = operator.truediv
operations['*'] = operator.mul

def solve(target, numbers):
    """List ways to make target from numbers."""
    numbers = [Fraction(x) for x in numbers]
    return solve_inner(target, numbers)

def solve_inner(target, numbers):
    if len(numbers) == 1:
        if numbers[0] == target:
            yield str(target)
        return

    # combine a pair of numbers with an operation, then recurse
    for a,b in itertools.permutations(numbers, 2):
        for symbol, operation in operations.items():
            try:
                product = operation(a,b)
            except ZeroDivisionError:
                continue

            subnumbers = list(numbers)
            subnumbers.remove(a)
            subnumbers.remove(b)
            subnumbers.append(product)

            for solution in solve_inner(target, subnumbers):
                # expand product (but only once)
                yield solution.replace(str(product), "({0}{1}{2})".format(a, symbol, b), 1)

if __name__ == "__main__":
    numbers = [1, 5, 6, 7]
    target = 5
    solutions = solve(target, numbers)
    for solution in solutions:
        print("{0}={1}".format(target, solution))
#!python
import operator
import itertools
from fractions import Fraction

operations = dict()
operations['+'] = operator.add
operations['-'] = operator.sub
operations['/'] = operator.truediv
operations['*'] = operator.mul

def solve(target, numbers):
    """List ways to make target from numbers."""
    numbers = [Fraction(x) for x in numbers]
    return solve_inner(target, numbers)

def solve_inner(target, numbers):
    if len(numbers) == 1:
        num = numbers[0]
        yield str(num), num == target
        return

    # combine a pair of numbers with an operation, then recurse
    for a,b in itertools.permutations(numbers, 2):
        for symbol, operation in operations.items():
            try:
                product = operation(a,b)
            except ZeroDivisionError:
                continue

            subnumbers = list(numbers)
            subnumbers.remove(a)
            subnumbers.remove(b)
            subnumbers.append(product)

            for solution, truth in solve_inner(target, subnumbers):
                # expand product (but only once)
                yield solution.replace(str(product),
                    "({0}{1}{2})".format(a, symbol, b), 1), truth

if __name__ == "__main__":
    numbers = [1, 5, 6, 7]
    target = 5
    solutions = solve(target, numbers)
    for solution, truth in solutions:
        print("{0}={1}? {2}".format(target, solution,
              'True' if truth else ''))
它只需使用我的
数字
尝试任何算术表达式,然后打印得到
目标
作为结果的表达式(我得到的结果)

#!python
import operator
import itertools
from fractions import Fraction

operations = dict()
operations['+'] = operator.add
operations['-'] = operator.sub
operations['/'] = operator.truediv
operations['*'] = operator.mul

def solve(target, numbers):
    """List ways to make target from numbers."""
    numbers = [Fraction(x) for x in numbers]
    return solve_inner(target, numbers)

def solve_inner(target, numbers):
    if len(numbers) == 1:
        num = numbers[0]
        yield str(num), num == target
        return

    # combine a pair of numbers with an operation, then recurse
    for a,b in itertools.permutations(numbers, 2):
        for symbol, operation in operations.items():
            try:
                product = operation(a,b)
            except ZeroDivisionError:
                continue

            subnumbers = list(numbers)
            subnumbers.remove(a)
            subnumbers.remove(b)
            subnumbers.append(product)

            for solution, truth in solve_inner(target, subnumbers):
                # expand product (but only once)
                yield solution.replace(str(product),
                    "({0}{1}{2})".format(a, symbol, b), 1), truth

if __name__ == "__main__":
    numbers = [1, 5, 6, 7]
    target = 5
    solutions = solve(target, numbers)
    for solution, truth in solutions:
        print("{0}={1}? {2}".format(target, solution,
              'True' if truth else ''))
我想知道,当表达式没有作为我设置的
目标的结果时,如何使它打印脚本尝试的任何解决方案

#!python
import operator
import itertools
from fractions import Fraction

operations = dict()
operations['+'] = operator.add
operations['-'] = operator.sub
operations['/'] = operator.truediv
operations['*'] = operator.mul

def solve(target, numbers):
    """List ways to make target from numbers."""
    numbers = [Fraction(x) for x in numbers]
    return solve_inner(target, numbers)

def solve_inner(target, numbers):
    if len(numbers) == 1:
        num = numbers[0]
        yield str(num), num == target
        return

    # combine a pair of numbers with an operation, then recurse
    for a,b in itertools.permutations(numbers, 2):
        for symbol, operation in operations.items():
            try:
                product = operation(a,b)
            except ZeroDivisionError:
                continue

            subnumbers = list(numbers)
            subnumbers.remove(a)
            subnumbers.remove(b)
            subnumbers.append(product)

            for solution, truth in solve_inner(target, subnumbers):
                # expand product (but only once)
                yield solution.replace(str(product),
                    "({0}{1}{2})".format(a, symbol, b), 1), truth

if __name__ == "__main__":
    numbers = [1, 5, 6, 7]
    target = 5
    solutions = solve(target, numbers)
    for solution, truth in solutions:
        print("{0}={1}? {2}".format(target, solution,
              'True' if truth else ''))
编辑:

#!python
import operator
import itertools
from fractions import Fraction

operations = dict()
operations['+'] = operator.add
operations['-'] = operator.sub
operations['/'] = operator.truediv
operations['*'] = operator.mul

def solve(target, numbers):
    """List ways to make target from numbers."""
    numbers = [Fraction(x) for x in numbers]
    return solve_inner(target, numbers)

def solve_inner(target, numbers):
    if len(numbers) == 1:
        num = numbers[0]
        yield str(num), num == target
        return

    # combine a pair of numbers with an operation, then recurse
    for a,b in itertools.permutations(numbers, 2):
        for symbol, operation in operations.items():
            try:
                product = operation(a,b)
            except ZeroDivisionError:
                continue

            subnumbers = list(numbers)
            subnumbers.remove(a)
            subnumbers.remove(b)
            subnumbers.append(product)

            for solution, truth in solve_inner(target, subnumbers):
                # expand product (but only once)
                yield solution.replace(str(product),
                    "({0}{1}{2})".format(a, symbol, b), 1), truth

if __name__ == "__main__":
    numbers = [1, 5, 6, 7]
    target = 5
    solutions = solve(target, numbers)
    for solution, truth in solutions:
        print("{0}={1}? {2}".format(target, solution,
              'True' if truth else ''))
这是我尝试的代码:

#!python
import operator
import itertools
from fractions import Fraction

operations = dict()
operations['+'] = operator.add
operations['-'] = operator.sub
operations['/'] = operator.truediv
operations['*'] = operator.mul

def solve(target, numbers):
    """List ways to make target from numbers."""
    numbers = [Fraction(x) for x in numbers]
    return solve_inner(target, numbers)

def solve_inner(target, numbers):
    if len(numbers) == 1:
        num = numbers[0]
        yield str(num), num == target
        return

    # combine a pair of numbers with an operation, then recurse
    for a,b in itertools.permutations(numbers, 2):
        for symbol, operation in operations.items():
            try:
                product = operation(a,b)
            except ZeroDivisionError:
                continue

            subnumbers = list(numbers)
            subnumbers.remove(a)
            subnumbers.remove(b)
            subnumbers.append(product)

            for solution, truth in solve_inner(target, subnumbers):
                yield solution.replace(str(product),
                    "{0}=({1}{2}{3})".format(product, a, symbol, b), 1), truth


if __name__ == "__main__":
    numbers = [1, 5, 6, 7]
    target = 5
    solutions = solve(target, numbers)
    for solution, truth in solutions:
        print("{0}? {1}".format(solution,
              'True' if truth else ''))
#!python
import operator
import itertools
from fractions import Fraction

operations = dict()
operations['+'] = operator.add
operations['-'] = operator.sub
operations['/'] = operator.truediv
operations['*'] = operator.mul

def solve(target, numbers):
    """List ways to make target from numbers."""
    numbers = [Fraction(x) for x in numbers]
    return solve_inner(target, numbers)

def solve_inner(target, numbers):
    if len(numbers) == 1:
        num = numbers[0]
        yield str(num), num == target
        return

    # combine a pair of numbers with an operation, then recurse
    for a,b in itertools.permutations(numbers, 2):
        for symbol, operation in operations.items():
            try:
                product = operation(a,b)
            except ZeroDivisionError:
                continue

            subnumbers = list(numbers)
            subnumbers.remove(a)
            subnumbers.remove(b)
            subnumbers.append(product)

            for solution, truth in solve_inner(target, subnumbers):
                # expand product (but only once)
                yield solution.replace(str(product),
                    "({0}{1}{2})".format(a, symbol, b), 1), truth

if __name__ == "__main__":
    numbers = [1, 5, 6, 7]
    target = 5
    solutions = solve(target, numbers)
    for solution, truth in solutions:
        print("{0}={1}? {2}".format(target, solution,
              'True' if truth else ''))
我得到的结果是实际产品,但我得到的结果是表达式中的小操作:

42=(7*6)/5=(42/5)=(1*42/5)
#!python
import operator
import itertools
from fractions import Fraction

operations = dict()
operations['+'] = operator.add
operations['-'] = operator.sub
operations['/'] = operator.truediv
operations['*'] = operator.mul

def solve(target, numbers):
    """List ways to make target from numbers."""
    numbers = [Fraction(x) for x in numbers]
    return solve_inner(target, numbers)

def solve_inner(target, numbers):
    if len(numbers) == 1:
        num = numbers[0]
        yield str(num), num == target
        return

    # combine a pair of numbers with an operation, then recurse
    for a,b in itertools.permutations(numbers, 2):
        for symbol, operation in operations.items():
            try:
                product = operation(a,b)
            except ZeroDivisionError:
                continue

            subnumbers = list(numbers)
            subnumbers.remove(a)
            subnumbers.remove(b)
            subnumbers.append(product)

            for solution, truth in solve_inner(target, subnumbers):
                # expand product (but only once)
                yield solution.replace(str(product),
                    "({0}{1}{2})".format(a, symbol, b), 1), truth

if __name__ == "__main__":
    numbers = [1, 5, 6, 7]
    target = 5
    solutions = solve(target, numbers)
    for solution, truth in solutions:
        print("{0}={1}? {2}".format(target, solution,
              'True' if truth else ''))

而实际上,我试图在字符串的开头只得到42。

如果num[0]等于target,则递归将通过生成str(num[0])而终止,否则将一无所获。如果产生了某些内容,字符串表达式将建立在连续的产量上。为了得到所有的表达,必须总是做出一些让步。我还选择给出是否达到了目标。相反,可以在打印之前对表达式求值

#!python
import operator
import itertools
from fractions import Fraction

operations = dict()
operations['+'] = operator.add
operations['-'] = operator.sub
operations['/'] = operator.truediv
operations['*'] = operator.mul

def solve(target, numbers):
    """List ways to make target from numbers."""
    numbers = [Fraction(x) for x in numbers]
    return solve_inner(target, numbers)

def solve_inner(target, numbers):
    if len(numbers) == 1:
        num = numbers[0]
        yield str(num), num == target
        return

    # combine a pair of numbers with an operation, then recurse
    for a,b in itertools.permutations(numbers, 2):
        for symbol, operation in operations.items():
            try:
                product = operation(a,b)
            except ZeroDivisionError:
                continue

            subnumbers = list(numbers)
            subnumbers.remove(a)
            subnumbers.remove(b)
            subnumbers.append(product)

            for solution, truth in solve_inner(target, subnumbers):
                # expand product (but only once)
                yield solution.replace(str(product),
                    "({0}{1}{2})".format(a, symbol, b), 1), truth

if __name__ == "__main__":
    numbers = [1, 5, 6, 7]
    target = 5
    solutions = solve(target, numbers)
    for solution, truth in solutions:
        print("{0}={1}? {2}".format(target, solution,
              'True' if truth else ''))

原稿中有个小毛病。产品追加到末尾,但替换与前面产品匹配的第一个数字。我相信结果可能是省略了表达式,在这种情况下,算法是不完整的。由于不能从末尾开始更换,因此应将产品放在前面(
子编号。插入(0,产品)
),以便更换的是产品。我会让你试验一下这有什么不同。但我相信如果编写正确,代码会更容易理解。

Terry,有什么建议吗?如何确保
产品
是整个算术表达式中正确的一个<代码>子编号。插入(0,产品))
应放在最后一个递归中。插入应替换当前的
子编号。追加(产品)
#!python
import operator
import itertools
from fractions import Fraction

operations = dict()
operations['+'] = operator.add
operations['-'] = operator.sub
operations['/'] = operator.truediv
operations['*'] = operator.mul

def solve(target, numbers):
    """List ways to make target from numbers."""
    numbers = [Fraction(x) for x in numbers]
    return solve_inner(target, numbers)

def solve_inner(target, numbers):
    if len(numbers) == 1:
        num = numbers[0]
        yield str(num), num == target
        return

    # combine a pair of numbers with an operation, then recurse
    for a,b in itertools.permutations(numbers, 2):
        for symbol, operation in operations.items():
            try:
                product = operation(a,b)
            except ZeroDivisionError:
                continue

            subnumbers = list(numbers)
            subnumbers.remove(a)
            subnumbers.remove(b)
            subnumbers.append(product)

            for solution, truth in solve_inner(target, subnumbers):
                # expand product (but only once)
                yield solution.replace(str(product),
                    "({0}{1}{2})".format(a, symbol, b), 1), truth

if __name__ == "__main__":
    numbers = [1, 5, 6, 7]
    target = 5
    solutions = solve(target, numbers)
    for solution, truth in solutions:
        print("{0}={1}? {2}".format(target, solution,
              'True' if truth else ''))