Python 将一个数分解成大致相等的因子
我想把一个数字分解成一个大小尽可能接近的数字元组,其乘积就是初始数字。输入是我们想要的因子数Python 将一个数分解成大致相等的因子,python,algorithm,math,Python,Algorithm,Math,我想把一个数字分解成一个大小尽可能接近的数字元组,其乘积就是初始数字。输入是我们想要的因子数n和所需因子数m 对于双因子情况(m==2),查找小于平方根的最大因子就足够了,所以我可以这样做 def get_factors(n): i = int(n**0.5 + 0.5) while n % i != 0: i -= 1 return i, n/i 因此,使用120调用此函数将导致10,12 我意识到这些数字“大小相近”的含义有些模糊。我不介意这是否被解释为最小化∑(x_I
n
和所需因子数m
对于双因子情况(m==2
),查找小于平方根的最大因子就足够了,所以我可以这样做
def get_factors(n):
i = int(n**0.5 + 0.5)
while n % i != 0:
i -= 1
return i, n/i
因此,使用120
调用此函数将导致10,12
我意识到这些数字“大小相近”的含义有些模糊。我不介意这是否被解释为最小化∑(x_I-x_avg)
或∑(x_I-x_avg)^2
或其他类似的东西
对于m==3
的情况,我希望336
产生6,7,8
和729
产生9,9
理想情况下,我想要一个通用m
的解决方案,但如果有人对m==3
有想法,我将不胜感激。我也欢迎一般的启发法
编辑:我更喜欢最小化这些因素的总和。仍然对上述内容感兴趣,但如果有人有办法计算出最佳的m
值,使因子之和最小,那就太好了 对于m=3和一些n,这个怎么样:
factors=[]
n=336
m=3
def getFactors(howMany, value):
if howMany < 2:
return value
root=getRoot(howMany, value) # get the root of value, eg square root, cube, etc.
factor=getLargestFactor(value, root) # get the largest factor of value smaller than root
otherFactors=getFactors(howMany-1, value / factor)
otherFactors.insert(factor)
return otherFactors
print getFactors(n, m)
因子=[]
n=336
m=3
def getFactors(数量、值):
如果数量<2:
返回值
root=getRoot(多少,值)#获取值的根,如平方根、立方体等。
factor=getLargestFactor(value,root)#获取小于root的值的最大因子
otherFactors=getFactors(数量-1,值/因子)
其他因素。插入(因素)
返回其他因素
打印系数(n,m)
我懒得为其余的代码编写代码,但这应该可以做到。您可以从相同的原则开始:查找小于或等于
m
次方根的数字,它们是因子。然后您可以递归找到其余的因子
def get_factors(n, m):
factors = []
factor = int(n**(1.0/m) + .1) # fudged to deal with precision problem with float roots
while n % factor != 0:
factor = factor - 1
factors.append(factor)
if m > 1:
factors = factors + get_factors(n / factor, m - 1)
return factors
print get_factors(729, 3)
为了回答第二个问题(即
m
使因子之和最小化),最好将数字拆分为素数因子。事实上,对于除4
外的任何正复合数,其素因子之和小于该数本身,因此任何具有复合数的拆分都可以通过将该复合数拆分为其素因子来改进
为了回答您的第一个问题,其他人建议的贪婪方法将不起作用,正如我在注释4104
中指出的那样,贪婪将立即提取8
作为第一个因素,然后将被迫将剩余的数字拆分为[3,9,19]
,无法找到更好的解决方案[6,6,6,19]
。然而,一个简单的DP可以找到最佳解决方案。DP的状态是我们试图计算的数字,以及我们想要得到的因子数,DP的值是可能的最佳和。与下面代码的行文类似。可以通过更智能地进行因子分解来优化
n=int(原始输入()
左=整数(原始输入()
备忘录={}
def dp(n,左):#返回元组(成本,[因子])
如果备忘录中有(n,左):返回备忘录[(n,左)]
如果左==1:
返回(n,[n])
i=2
最佳=n
最佳元组=[n]
当我
你会得到:
答案=1.495
然后
1.495*1.495*1.495*1.495=5
在C#
您可以尝试生成所有素因子,然后生成m
的每个组合,以找到最小误差。对于4104,您将得到(3,8,9,19),而(6,6,6,19)使用任一损失函数都更好。我喜欢这种贪婪的方法解决问题。它可以归结为在解决方案树中进行深度优先搜索,在每个深度上首先探索最大可能的因子。但是,如果没有(多少-x)个因子,算法也应该能够返回“无解”。或者,如果在达到所需深度之前遇到素数,它可以简单地返回“1”,并且具有“1”因子的解决方案可能被认为是不好的。换句话说,不需要调用getFactors(多少个-1,值/因子)如果value/factor是prime,递归的下一个深度不是最终深度。Op使用的是整数,而不是double。Op也使用python,而不是C#。
[In] 4104
[In] 4
[Out] [6, 6, 6, 19]
m=5 n=4 then m^(1/n)
double Result = Math.Pow(m,1/(double)n);