效率极低的python代码

时间:2013-08-14 14:15:49

标签: python geometry

我制作了一个程序,允许用户输入直角三角形的最大可能斜边,我的程序将列出三角形所有可能边的列表。问题是,当我输入10000这样的值时,程序会永远运行。有关如何提高程序效率的任何建议吗?

代码:

largest=0
sets=0
hypotenuse=int(input("Please enter the length of the longest side of the triangle"))
for x in range(3,hypotenuse):
    for y in range(4, hypotenuse):
        for z in range(5,hypotenuse):
            if(x<y<z):                   
                 if(x**2+y**2==z**2):
                     commonFactor=False
                     for w in range(2,x//2):
                         if (x%w==0 and y%w==0 and z%w==0):
                             commonFactor=True
                             break
                     if not(commonFactor):
                         print(x,y,z)
                         if(z>largest):
                             largest=z
                         sets+=1
print("Number of sets: %d"%sets)
print("Largest hypotenuse is %d"%largest)

谢谢!

3 个答案:

答案 0 :(得分:1)

像这样?

hypothenuse=10000
thesets=[]
for x in xrange(1, hypothenuse):
    a=math.sqrt(hypothenuse**2-x**2)
    if(int(a)==a):
        thesets.append([x,a])
print "amount of sets: ", len(thesets)
for i in range(len(thesets)):
    print thesets[i][0],thesets[i][1], math.sqrt(thesets[i][0]**2+ thesets[i][1]**2)

编辑:更改,这样你也可以打印这些集合(这个方法是在O(n)中,这是我猜的最快的方法吗?)注意:如果你想要集合的数量,每个都给出两次,例如:15 * 2 = 9 * 2 + 12 * 2 = 12 * 2 + 9 ** 2

不确定我是否正确理解你的代码,但如果你在12中给出,那么你是否希望所有可能的小三角形小于12的三角形?或者你想要知道可能性(据我所知)可以写12 * 2 = a * 2 + b ** 2?

如果你想要所有可能性,那么我会稍微编辑一下代码

对于* 2 + b * 2 = c ** 2的所有可能性,其中c <1。 hypothenuse (不确定这是否是你想要的东西):

hypothenuse=15
thesets={}
for x in xrange(1,hypothenuse):
    for y in xrange(1,hypothenuse):
        a=math.sqrt(x**2+y**2)
        if(a<hypothenuse and int(a)==a):
            if(x<=y):
                thesets[(x,y)]=True
            else:
                thesets[(y,x)]=True
print len(thesets.keys()) 
print thesets.keys()

这解决了O(n ** 2),如果hypothenuse = 15,你的解决方案甚至不起作用,你的解决方案给出了:

(3,4,5) (5,12,13) 套数:2

正确的是: 3 [(5,12),(3,4),(6,8)]

因为5 * 2 + 12 * 2 = 13 * 2,3 * 2 + 4 * 2 = 5 * 2, 6 * 2 + 8 * 2 = 10 ** 2,而您的方法没有给出第三个选项? 编辑:将numpy改为数学,我的方法也没有给出倍数,我只是说明为什么我得到3而不是2,(这3个不同的解决问题的方法不同,因此所有3个都是有效的,所以你的解决问题的方法是不完整的?)

答案 1 :(得分:1)

这是使用预先计算的正方形和缓存的平方根的快速尝试。可能有许多数学优化。

def find_tri(h_max=10):
  squares = set()
  sq2root = {}
  sq_list = []
  for i in xrange(1,h_max+1):
    sq = i*i
    squares.add(sq)
    sq2root[sq] = i
    sq_list.append(sq)
  #
  tris = []
  for i,v in enumerate(sq_list):
    for x in sq_list[i:]:
      if x+v in squares:
        tris.append((sq2root[v],sq2root[x],sq2root[v+x]))
  return tris

演示:

>>> find_tri(20)
[(3, 4, 5), (5, 12, 13), (6, 8, 10), (8, 15, 17), (9, 12, 15), (12, 16, 20)]

答案 2 :(得分:0)

一个非常简单的优化是任意决定x <= y。例如,如果(10,15,x)不是解决方案,则(15,10,x)也不是解决方案。这也意味着如果2x**2 > hypoteneuse**2,则可以终止算法,因为没有解决方案。