Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/340.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_Mathematical Optimization - Fatal编程技术网

Python 将正整数表示为三个数的和

Python 将正整数表示为三个数的和,python,mathematical-optimization,Python,Mathematical Optimization,正整数n可以以多少种方式表示为三个不同正整数的总和。如果一个方法包含另一个方法不包含的数字,则这两种方法是不同的 我已经设法让下面的脚本将写入n的方法的数量计算为三个数字的总和,但它没有考虑其他条件 def nways(n): 如果(n你可以使用蛮力,还有一些作品: 检查三个术语是否不同 存储一组唯一的术语 该集合的长度是您的结果 def方式(n): 元组\和\集=集() 对于范围(1,n+1)内的i: 对于范围(1,n+1)内的j: 对于范围(1,n+1)内的k: 如果i+j+k==n且l

正整数
n
可以以多少种方式表示为三个不同正整数的总和。如果一个方法包含另一个方法不包含的数字,则这两种方法是不同的

我已经设法让下面的脚本将写入
n
的方法的数量计算为三个数字的总和,但它没有考虑其他条件

def nways(n):

如果(n你可以使用蛮力,还有一些作品:

  • 检查三个术语是否不同
  • 存储一组唯一的术语
  • 该集合的长度是您的结果
def方式(n):
元组\和\集=集()
对于范围(1,n+1)内的i:
对于范围(1,n+1)内的j:
对于范围(1,n+1)内的k:
如果i+j+k==n且len(set([i,j,k])==3:
tuple\u sum\u set.add(tuple(排序([i,j,k]))
打印(元组和集)
返回len(元组和集)
印刷(方式(8))

演示:

一种非常不同的方法是使用约束解算器。以下是一个示例:

import constraint as con

n = 8

p = con.Problem()
p.addVariables(['x','y','z'],range(1,n-2))
p.addConstraint(con.ExactSumConstraint(n))
p.addConstraint(lambda a, b, c : a < b < c, ("x", "y", "z"))
sols = p.getSolutions()

print(len(sols))
sols

我不知道有一个简单的公式可以预测解决方案的数量。

您可以对@hgb123已经很好的答案进行一些非常重要的优化,以继续使用蛮力,但要聪明一点:

def ways(n):
  tuple_sum_set = set()

  for i in range(1, n-2):
    for j in range(i+1, n-2):
      for k in range(j+1, n-2):
        if i + j + k == n:
          tuple_sum_set.add((i,j,k))

  print(tuple_sum_set)
  return len(tuple_sum_set)
(如果您投票支持此答案,请投票支持@hgb123,这是他的答案的派生)

解决方案 该算法消耗
O(N)
时间和
O(1)
空间

解释 让我们将这三个正数表示为
i
j
k

由于它们都是不同的,这三个数必须大于或小于彼此。我们假设最小的数是
i
,中间的数是
j
,最大的数是
k
。那么关系就是
i

n=18
为例

  • 我们从
    i=1
    开始,然后
    j+k
    应该是
    17
    • 所以
      (j,k)
      可以从
      (2,12)
      (3,14)
      ,…到
      (8,9)

    • 注意,
      (j,k)
      不可能是
      (9,8)
      (10,7)
      ,因为
      jTry是反向工作的;用3强制一个解决方案循环,测试它的数字3到10,然后根据这些结果计算出数学公式
      
      def ways(n):
        tuple_sum_set = set()
      
        for i in range(1, n-2):
          for j in range(i+1, n-2):
            for k in range(j+1, n-2):
              if i + j + k == n:
                tuple_sum_set.add((i,j,k))
      
        print(tuple_sum_set)
        return len(tuple_sum_set)
      
      def nways(n):
          nways = 0
          for i in range(1, n-2):
              min_j, max_j = i+1, (n-i-1)//2
              nways += (max_j - min_j + 1) if max_j >= min_j else 0
          return nways