Python 迭代求解方程

Python 迭代求解方程,python,iteration,equation,brute-force,Python,Iteration,Equation,Brute Force,我想知道如何使用以下等式优化问题: R=A/B*C/D 其中R是输入值,A、B、C和D是整数列表中的一个值,例如[20,21,22,23,24,24,25,25,26,28,28,28,36,36,37,38,39,40,41,42,43] 目标是找到A、B、C和D中最接近R的值 我正在使用Cython来加快运行速度,但仍然需要几分钟才能解决 我不是在寻求解决方案,只是寻求一些帮助,用正确的词语为我指明正确的方向 编辑:回答一些问题 我是蛮力逼迫,因为我不知道其他的方法,我接受建议 列表中故

我想知道如何使用以下等式优化问题:

R=A/B*C/D
其中R是输入值,
A
B
C
D
是整数列表中的一个值,例如
[20,21,22,23,24,24,25,25,26,28,28,28,36,36,37,38,39,40,41,42,43]

目标是找到
A
B
C
D
中最接近
R
的值

我正在使用Cython来加快运行速度,但仍然需要几分钟才能解决

我不是在寻求解决方案,只是寻求一些帮助,用正确的词语为我指明正确的方向

编辑:回答一些问题

  • 我是蛮力逼迫,因为我不知道其他的方法,我接受建议
  • 列表中故意存在重复项,一种可能的解决方案是A=21、B=38、C=28、D=28
  • 该列表可以长达150个元素

    以下是我与Cython目前的情况:

    def __init__ (self, **kwargs) :
        self._arr           = (20,20,21,22,24,25,27,30,34,35,36,38,40,44,45,46,46,47,48,50,51,52,54,55,56,58,60,62,65,68,70,75,80,85,90,95,100,120,127) 
        self._desiredNumber = kwargs.get('desiredNumber', None)
    
    
    def doesFit(self, *set):
        # check values of A, B, C and D agains harcodded limits, 
        # if conditions met return true, else return false
        return true
    
    def solver(self, float desiredError = 0.00001):
        cdef float computedNumber, computedError
        computedNumber = 0
        computedError = 0
    
        cdef int arrSize, a, b, c, d
        a = 0
        b = 0
        c = 0
        d = 0
        arrSize = len (self._arr)
    
        cdef vector[float] arr = self._arr
    
        result = []
    
        for a from 0 <= a < arrSize:
            for b from 0 <= b < arrSize:
                for c from 0 <= c < arrSize:
                    for d from 0 <= d < arrSize:
                        computedNumber=arr[a]/arr[b]*arr[c]/arr[d]
                        computedError = fabs (self._desiredNumber - computedNumber)
                        if computedError<=desiredError and (a!=b and a!=c and a!=d and b!=c and b!=d and c!=d):
                            if self.doesFit(arr[a], arr[b], arr[c], arr[d]):
                                result.append(dict (A=arr[a], B=arr[b], C=arr[c], D=arr[d], desiredError=computedError, computedNumber=computedNumber))
    
        # remove results with duplicated values of A, B, C and D. 
        # A/B*C/D is the same as C/D*A/B, etc
        keyfunc = lambda d: (d['A'], d['B'], d['C'], d['D'])
        giter = groupby(sorted(result, key=keyfunc), keyfunc)
        result = [next(g[1]) for g in giter]
    
        # sort results by desiredError
        result = sorted(result, key=itemgetter('desiredError'))
    
        # returns just the 12 best results
        if len(result) > 12:    
            result = result[0:12]    
    
        return result
    
    def\uuuuu init\uuuuuuu(self,**kwargs):
    自我评价=(20,20,21,22,24,25,27,30,34,35,36,38,40,44,45,46,46,47,48,50,51,52,54,55,56,58,60,62,65,68,70,75,80,85,90,95100120127)
    self.\u desiredNumber=kwargs.get('desiredNumber',无)
    def doesFit(自身,*设置):
    #检查A、B、C和D的值是否符合硬编码限值,
    #如果条件满足,则返回true,否则返回false
    返回真值
    def解算器(自身,浮点期望误差=0.00001):
    cdef浮点计算数,计算错误
    computedNumber=0
    computedError=0
    cdef int arrSize,a、b、c、d
    a=0
    b=0
    c=0
    d=0
    arrSize=透镜(自聚焦)
    cdef向量[float]arr=self.\u arr
    结果=[]
    
    对于一个from 0的函数,我相信你要的是一个蛮力函数。正如在评论中所建议的那样,我确实实施了一个独特的数组来加速算法

    arr = [20,21,22,23,24,24,25,25,26,28,28,28,36,36,37,38,38,39,40,40,41,42,42,43]
    
    def iterSolvePython(arr, desiredNumber):
        arr = list(sorted(set(arr)))
        best = {'a':arr[0],'b':arr[0],'c':arr[0],'d':arr[0], 'r': 1}
        for a in arr:
            for b in arr:
                for c in arr:
                    for d in arr:
                        r = float(a)/b*c/d
                        if abs(desiredNumber-r) < abs(desiredNumber-best['r']):
                            best = {
                                'a':a,
                                'b':b,
                                'c':c,
                                'd':d,
                                'r':r
                            }
        return best
    
    print(iterSolvePython(arr, 25))
    
    arr=[20,21,22,23,24,24,25,25,26,28,28,36,36,37,38,38,39,40,40,41,42,43]
    def iterSolvePython(arr,desiredNumber):
    arr=列表(已排序(集合(arr)))
    best={'a':arr[0],'b':arr[0],'c':arr[0],'d':arr[0],'r':1}
    对于arr中的a:
    对于arr中的b:
    对于arr中的c:
    对于arr中的d:
    r=浮动(a)/b*c/d
    如果abs(desiredNumber-r)
    Cython中的几分钟?我很确定MS Excel中的
    解算器
    会很快收敛到这一点。我认为,即使是cython之前的python代码也有助于了解这个问题。你是在强逼吗?名单有多大?你发布的名单有好几份重复。您可能想使用,比如,
    list(sorted(set(values)))
    来首先解决这个问题(如果没有其他原因,为了最小化您必须使用暴力的空间;))您当前的解决方案是什么样子的?我确实将a强制转换为浮点,所以我们现在可以获得浮点值,但是,请考虑一下。。。我们的最大值为43/21*43/21,约为4。该数据集的最大值为(约)4.43/20*22/21,无争议地小于43/21*43/21