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:我还是一个初学者。一个更有经验的程序员可能会更高效、更优雅地完成这项工作。这听起来像是一个欧拉问题:欧拉问题?只是一些上下文,我试图在一个数学游戏中获得最大的分数。是的,欧拉问题是一个数学游戏。你应该去看看。你需要处理的列表有多大?你的目标值有多大
这听起来像是欧拉问题:欧拉问题?只是一些背景知识,我试图在一个数学游戏中最大化我的分数。是的,欧拉问题是一个数学游戏。你应该去看看。你要处理的清单有多大?你需要处理的目标值有多大?在花了很多时间研究和阅读你的见解之后,我想出了一个递归的方法来做这件事,我将把它作为一个答案在花了很多时间研究和阅读你的见解之后,我想出了一个递归的方法来做这件事,我将把它作为一个答案