python - 整数数学推导(运算顺序)

标签 python algorithm search

我现在正在用Python工作,我遇到了一个问题,我不知道在哪里捕获救命稻草。请原谅我,如果这在某个初始算法 CS 类(class)中有所介绍,我的背景实际上是经济学。我正在处理财务数据,我知道输出和输入,只是不知道如何获取操作顺序。

例如,我的最终市盈率为 2,但输入为 10(价格)和 5( yield )。看看这个,我就知道 10/5 等于 2。但是,问题是运算顺序......这可能是加法、乘法、除法和平方根。

如果我有的话,这部分似乎是可行的

inputs = [10,5]
output = 2

def deduction_int(inputs, output):
    initial_output = 0
    while initial_output != output:
    try adding, try subtracting (inverse), try dividing(inverse)

当它自己弄清楚或有答案时打印“yay”

上面的代码看起来很明显而且很快,但是,当您向其中添加 3 个变量时......

输入:10、5、7 输出:2.14

以及 (10 + 5)/7 = 2.14 等情况。

我遇到了数字可能以不同顺序运行的情况。例如,在除以 7 之前先运行 10+5。这是常见的算法类型问题吗?如果是这样,我究竟在哪里寻找教科书描述(算法名称、教科书)?

谢谢!

最佳答案

这是一个暴力算法。

from __future__ import division
import itertools as IT
import operator

opmap = {operator.add: '+',
         operator.mul: '*',
         operator.truediv: '/'}
operators = opmap.keys()

def deduction_int(inputs, output):
    iternums = IT.permutations(inputs, len(inputs))
    iterops = IT.product(operators, repeat=len(inputs)-1)
    for nums, ops in IT.product(iternums, iterops):
        for result, rstr in combine(nums, ops):
            if near(result, output, atol=1e-3):
                return rstr

def combine(nums, ops, astr=''):
    a = nums[0]
    astr = astr if astr else str(a)
    try:
        op = ops[0]
    except IndexError:
        return [(a, astr)]
    # combine a op (...)
    result = []
    for partial_val, partial_str in combine(nums[1:], ops[1:]):
        r = op(a, partial_val)
        if len(nums[1:]) > 1:
            rstr = '{}{}({})'.format(astr, opmap[op], partial_str)
        else:
            rstr = '{}{}{}'.format(astr, opmap[op], partial_str)
        assert near(eval(rstr), r)
        result.append((r, rstr))
    # combine (a op ...)
    b = nums[1]
    astr = '({}{}{})'.format(astr,opmap[op], b)
    for partial_val, partial_str in combine((op(a, b),)+nums[2:], ops[1:],
                                            astr):
        assert near(eval(partial_str), partial_val)
        result.append((partial_val, partial_str))
    return result

def near(a, b, rtol=1e-5, atol=1e-8):
    return abs(a - b) < (atol + rtol * abs(b))

def report(inputs, output):
    rstr = deduction_int(inputs, output)
    return '{} = {}'.format(rstr, output)

print(report([10,5,7], (10+5)/7))
print(report([1,2,3,4], 3/7.))
print(report([1,2,3,4,5], (1+(2/3)*(4-5))))

产量

(10+5)/7 = 2.14285714286
(1+2)/(3+4) = 0.428571428571
(1+5)/((2+4)*3) = 0.333333333333

主要思想是简单地枚举输入值的所有顺序以及运算符的所有顺序。例如,

In [19]: list(IT.permutations([10,5,7], 3))
Out[19]: [(10, 5, 7), (10, 7, 5), (5, 10, 7), (5, 7, 10), (7, 10, 5), (7, 5, 10)]

然后将输入值的每个顺序与运算符的每个顺序配对:

In [38]: list(IT.product(iternums, iterops))
Out[38]: 
[((10, 5, 7), (<built-in function add>, <built-in function mul>)),
 ((10, 5, 7), (<built-in function add>, <built-in function truediv>)),
 ((10, 5, 7), (<built-in function mul>, <built-in function add>)),
 ((10, 5, 7), (<built-in function mul>, <built-in function truediv>)),
 ...

combine函数接受 nums 的排序和 ops 的排序,并枚举 nums 和 ops 的所有可能分组: 在[65]中:combine((10,5,7),(operator.add,operator.mul))

Out[65]: [(45, '10+(5*7)'), (45, '10+((5*7))'), (105, '(10+5)*7'), (105, '((10+5)*7)')]

它返回一个元组列表。每个元组都是由数值和字符串表示形式 rstr 组成的 2 元组。 ,计算结果为该值的分组操作。

因此,您只需循环遍历所有可能性并返回 rstr当评估时,会产生一个接近 output 的数字。 .

for nums, ops in IT.product(iternums, iterops):
    for result, rstr in combine(nums, ops):
        if near(result, output, atol=1e-3):
            return rstr

一些有用的引用:

关于python - 整数数学推导(运算顺序),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19169000/

相关文章:

python - 在 Django 中将表分为两部分

python - 如何让 'list' (players/) 和 'detail' (players/{id}) 有不同的结果?

java - 根据长度对数组中的字符串进行排序

java - 无法获取数组中的第二大值

python - Python 中的函数类似于 Stata 中 egenmore 的 xtile()

python - 为什么 Python 中的某些列表方法仅适用于已定义的变量?

algorithm - 网格上二维正方形的非分离矩形边缘覆盖

algorithm - 计算给定 k 模和的子序列数

javascript - 如何在使用 Jquery 搜索时隐藏标签和复选框?

c# - 如何执行完整的递归目录和文件扫描?