Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/358.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 将一个数分解成大致相等的因子_Python_Algorithm_Math - Fatal编程技术网

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,这个怎么样:

  • 得到n的最大因子小于n的立方根,称之为f1
  • 将n除以f1,称之为g
  • 找到g的“大致相等因子”,如m=2示例中所示
  • 对于336,比336的立方根小的最大因子是6(我认为)。将336除以6得到56(另一个因子,见图!)对56进行同样的计算,并寻找两个因子,我们得到7和8

    请注意,这不适用于因子小于3的任何数字。这种方法可以扩展到m>3的情况

    如果这是正确的,并且我不是太疯狂,那么解决方案将是递归函数:

    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);