Algorithm 在列表中查找值的最小和以形成目标因子

Algorithm 在列表中查找值的最小和以形成目标因子,algorithm,sum,Algorithm,Sum,我一直在思考如何制作一个算法,从一个列表中找到元素的组合,其中这些因子的总和是尽可能低的,而这些数字的因子是一个预定的目标值 例如,列表: (2,5,7,6,8,2,3) 以及目标值: 12 将导致以下因素: (2,2,3) and (2,6) 但最佳组合是: (2,2,3) 因为它的和较低,所以首先从列表中删除所有不是n的因子的数字。因此,在您的示例中,您的列表将减少到2,6,2,3。然后我会对列表进行排序。所以你有2,2,3,6。如果达到n停止,则开始从左向右乘以元素。如果超过n,则

我一直在思考如何制作一个算法,从一个列表中找到元素的组合,其中这些因子的总和是尽可能低的,而这些数字的因子是一个预定的目标值

例如,列表:

(2,5,7,6,8,2,3)
以及目标值:

12
将导致以下因素:

(2,2,3) and (2,6)
但最佳组合是:

(2,2,3)

因为它的和较低,所以首先从列表中删除所有不是n的因子的数字。因此,在您的示例中,您的列表将减少到2,6,2,3。然后我会对列表进行排序。所以你有2,2,3,6。如果达到n停止,则开始从左向右乘以元素。如果超过n,则找到下一个最小的数字排列并重复。这将是2, 2, 6,3的C++函数,找到下一个排列。这将保证找到最小和的乘法,因为我们正在按从最小和到最大的顺序检查乘积。这和你的列表阶乘一样大,但我认为这是你能得到的最好结果。这个问题听起来像NP难


通过修剪排列,您可以做得稍微好一点。假设你在找24个,你的名单是2,4,8,12。唯一的子集是2,12。但下一个排列将是2,4,12,8,你甚至不需要生成它,因为你知道2*4太小,2*4*8太大,用8替换12只会增加2*4*8。这样,您就不必测试这种排列。

首先从列表中删除所有不是n的因子的数字。因此,在您的示例中,您的列表将减少到2,6,2,3。然后我会对列表进行排序。所以你有2,2,3,6。如果达到n停止,则开始从左向右乘以元素。如果超过n,则找到下一个最小的数字排列并重复。这将是2, 2, 6,3的C++函数,找到下一个排列。这将保证找到最小和的乘法,因为我们正在按从最小和到最大的顺序检查乘积。这和你的列表阶乘一样大,但我认为这是你能得到的最好结果。这个问题听起来像NP难


通过修剪排列,您可以做得稍微好一点。假设你在找24个,你的名单是2,4,8,12。唯一的子集是2,12。但下一个排列将是2,4,12,8,你甚至不需要生成它,因为你知道2*4太小,2*4*8太大,用8替换12只会增加2*4*8。这样,您就不必测试这种排列。

您应该能够递归地分解问题。你有一组多个势因子S={n_1,n_2,…,n_k}。设fS,n为最大和n_i_1+n_i_2+…+n_i_j,其中n_i_l是多集的不同元素,n_i_1*。*n_i_j=n。然后fS,n=max_i{n_i+fS-{n_i},n/n_i,其中n_i除以n}。换句话说,fS,n可以递归计算。再多做一点工作,你就可以得到算法,吐出实际的n_就是这项工作。时间复杂度可能不好,但你没有说你在这方面的目标是什么。

你应该能够递归地分解问题。你有一组多个势因子S={n_1,n_2,…,n_k}。设fS,n为最大和n_i_1+n_i_2+…+n_i_j,其中n_i_l是多集的不同元素,n_i_1*。*n_i_j=n。然后fS,n=max_i{n_i+fS-{n_i},n/n_i,其中n_i除以n}。换句话说,fS,n可以递归计算。再多做一点工作,你就可以得到算法,吐出实际的n_就是这项工作。时间复杂度可能不好,但你不能说你在这方面的目标是什么。

以下是你在Haskell中可以做到的:

def primes(n):
    primfac = []
    d = 2
    while d*d <= n:
        while (n % d) == 0:
            primfac.append(d)  # supposing you want multiple factors repeated
            n //= d
        d += 1
    if n > 1:
       primfac.append(n)
    return primfac

def get_factors_list(dividend, ceiling = float('infinity')):
    """ Yield all lists of factors where the largest is no larger than ceiling """
    for divisor in range(min(ceiling, dividend - 1), 1, -1):
        quotient, mod = divmod(dividend, divisor)
        if mod == 0:
            if quotient <= divisor:
                yield [divisor, quotient]
            for factors in get_factors_list(quotient, divisor):
                yield [divisor] + factors

def print_factors(x):
    factorList = []
    if x > 0:
        for factors in get_factors_list(x):
            factorList.append(list(map(int, factors)))
    return factorList
import Data.List(sortBy, subsequences)
import Data.Function(on)

lowestSumTargetFactor :: (Ord b, Num b) => [b] -> b -> [b]
lowestSumTargetFactor xs target = do
    let l =  filter (/= []) $ sortBy (compare `on` sum) 
            [x | x <- subsequences xs, product x == target]
    if l == []
        then error $ "lowestSumTargetFactor: " ++ 
            "no subsequence product equals target."
        else head l
下面是正在发生的事情:

[x | x[b]->b->[b]部分只是函数的类型签名。这意味着函数接受由b组成的列表,第二个参数b,并返回由b组成的另一个列表,b是完全有序数据类型的Ord类和基本数值类Num类的成员


Obs3:我还是一个初学者。一个更有经验的程序员可能会更高效、更优雅地完成这项工作。

以下是如何在Haskell中完成这项工作:

import Data.List(sortBy, subsequences)
import Data.Function(on)

lowestSumTargetFactor :: (Ord b, Num b) => [b] -> b -> [b]
lowestSumTargetFactor xs target = do
    let l =  filter (/= []) $ sortBy (compare `on` sum) 
            [x | x <- subsequences xs, product x == target]
    if l == []
        then error $ "lowestSumTargetFactor: " ++ 
            "no subsequence product equals target."
        else head l
下面是正在发生的事情:

[x | x[b]->b->[b]部分只是函数的类型签名。这意味着函数接受由b组成的列表,第二个参数b,并返回由b组成的另一个列表,b是完全有序数据类型的Ord类和基本数值类Num类的成员


Obs3:我还是一个初学者。一个更有经验的程序员可能会更高效、更优雅地完成这项工作。

这听起来像是一个欧拉问题:欧拉问题?只是一些上下文,我试图在一个数学游戏中获得最大的分数。是的,欧拉问题是一个数学游戏。你应该去看看。你需要处理的列表有多大?你的目标值有多大
这听起来像是欧拉问题:欧拉问题?只是一些背景知识,我试图在一个数学游戏中最大化我的分数。是的,欧拉问题是一个数学游戏。你应该去看看。你要处理的清单有多大?你需要处理的目标值有多大?在花了很多时间研究和阅读你的见解之后,我想出了一个递归的方法来做这件事,我将把它作为一个答案在花了很多时间研究和阅读你的见解之后,我想出了一个递归的方法来做这件事,我将把它作为一个答案