これは私がピタゴラストリプレットを計算するために書いたプログラムです。プログラムを実行すると、ifステートメントのためにトリプレットの各セットが2回出力されます。新しいトリプレットのセットを1回だけ印刷するようにプログラムに指示する方法はありますか?ありがとう。
import math
def main():
for x in range (1, 1000):
for y in range (1, 1000):
for z in range(1, 1000):
if x*x == y*y + z*z:
print y, z, x
print '-'*50
if __name__ == '__main__':
main()
ピタゴラストリプルは、 "for
ループは有害と見なされます"を主張する良い例です。for
ループは、タスクの最も無関係な部分であることが多いカウントについて考えるように私たちを誘惑するからです。 。
(言語の偏りを回避し、疑似コードを合理化するために、疑似コードを使用します。たとえば、x * x
やy * y
などの複数の計算を最適化することはしません。)
バージョン1:
for x in 1..N {
for y in 1..N {
for z in 1..N {
if x * x + y * y == z * z then {
// use x, y, z
}
}
}
}
最悪の解決策です。重複を生成し、役に立たないスペースの部分をトラバースします(たとえば、z < y
の場合)。その時間計算量はN
で3次です。
バージョン2、最初の改善点は、次のようにx < y < z
を保持する必要があることによるものです。
for x in 1..N {
for y in x+1..N {
for z in y+1..N {
if x * x + y * y == z * z then {
// use x, y, z
}
}
}
}
これにより、実行時間が短縮され、重複するソリューションが排除されます。ただし、N
ではまだ3次です。改善は、N
- cubedの係数の単なる減少です。
z * z < x * x + y * y
が保持されなくなった後、z
の値の増加を調べ続けることは無意味です。その事実が動機付けになりますバージョン、z
でのブルートフォース反復からの最初のステップ:
for x in 1..N {
for y in x+1..N {
z = y + 1
while z * z < x * x + y * y {
z = z + 1
}
if z * z == x * x + y * y and z <= N then {
// use x, y, z
}
}
}
1000のN
の場合、これはバージョン2の約5倍高速ですが、N
ではstillキュービックです。 。
次の洞察は、x
とy
が唯一の独立変数であるということです。 z
はそれらの値に依存し、z
の前の値に対して考慮された最後のy
値は適切なstartingy
の次の値の値を検索します。それはバージョン4につながります:
for x in 1..N {
y = x+1
z = y+1
while z <= N {
while z * z < x * x + y * y {
z = z + 1
}
if z * z == x * x + y * y and z <= N then {
// use x, y, z
}
y = y + 1
}
}
これにより、y
とz
はx
より上の値を1回だけ「スイープ」できます。 N
が1000の場合は100倍以上高速であるだけでなく、N
では2次式であるため、N
が大きくなるにつれて速度が向上します。
この種の改善に頻繁に遭遇したため、最も些細な用途(配列のトラバースなど)以外では「ループのカウント」に不信感を抱くことがありました。
更新:どうやら私はV4について見落としがちないくつかのことを指摘すべきでした。
両方while
ループの値は、z
の値によって制御されます(一方は直接、もう一方はz
の2乗を介して間接的に)。内側のwhile
は、実際には外側のwhile
に直交するのではなく、速度を上げています。 ループの数を数えるだけでなく、ループが何をしているのかを調べることが重要です。
V4の計算はすべて、厳密に整数演算です。浮動小数点への/からの変換、および浮動小数点の計算は、比較するとコストがかかります。
V4は定数メモリで実行され、必要な整数変数は3つだけです。割り当てて初期化する(そして、潜在的にメモリ不足エラーを引き起こす)配列やハッシュテーブルはありません。
元の質問では、x
、y
、およびx
のすべてが同じ範囲で変化することが許可されていました。 V1..V4はそのパターンに従いました。
以下は、「use x、y、z」が実装された、あまり科学的ではないタイミングのセットです(Javaを使用して、古いラップトップで他のものを実行している古いラップトップで...) Tripleオブジェクトを3つの値でインスタンス化し、それをArrayListに配置します(これらの実行では、N
は10,000に設定され、それぞれ12,471のトリプルが生成されました)。
Version 4: 46 sec.
using square root: 134 sec.
array and map: 400 sec.
「配列とマップ」アルゴリズムは本質的に:
squares = array of i*i for i in 1 .. N
roots = map of i*i -> i for i in 1 .. N
for x in 1 .. N
for y in x+1 .. N
z = roots[squares[x] + squares[y]]
if z exists use x, y, z
「平方根を使用する」アルゴリズムは本質的にです:
for x in 1 .. N
for y in x+1 .. N
z = (int) sqrt(x * x + y * y)
if z * z == x * x + y * y then use x, y, z
V4の実際のコードは次のとおりです。
public Collection<Triple> byBetterWhileLoop() {
Collection<Triple> result = new ArrayList<Triple>(limit);
for (int x = 1; x < limit; ++x) {
int xx = x * x;
int y = x + 1;
int z = y + 1;
while (z <= limit) {
int zz = xx + y * y;
while (z * z < zz) {++z;}
if (z * z == zz && z <= limit) {
result.add(new Triple(x, y, z));
}
++y;
}
}
return result;
}
x * x
isは外側のループで計算されることに注意してください(ただし、z * z
をキャッシュする必要はありませんでした)。他のバリエーションでも同様の最適化が行われます。
何かを誤って実装した場合に備えて、タイミングを合わせた他のバリエーションについては、リクエストに応じてJavaソースコードを提供させていただきます。
これまでのどのソリューションよりも大幅に高速です。三分木を介してトリプレットを検索します。
Wolfram 言います:
Hall(1970)とRoberts(1977)は、それが原始ピタゴラストリプルであると証明しました。
_
(a,b,c)=(3,4,5)M
_ここで、Mは行列U、A、Dの有限積です。
そして、すべてのプリミティブトリプルを生成する式があります。
上記の式では、斜辺が増え続けているため、最大長を確認するのは非常に簡単です。
Pythonの場合:
_import numpy as np
def gen_prim_pyth_trips(limit=None):
u = np.mat(' 1 2 2; -2 -1 -2; 2 2 3')
a = np.mat(' 1 2 2; 2 1 2; 2 2 3')
d = np.mat('-1 -2 -2; 2 1 2; 2 2 3')
uad = np.array([u, a, d])
m = np.array([3, 4, 5])
while m.size:
m = m.reshape(-1, 3)
if limit:
m = m[m[:, 2] <= limit]
yield from m
m = np.dot(m, uad)
_
プリミティブだけでなく、すべてのトリプルが必要な場合:
_def gen_all_pyth_trips(limit):
for prim in gen_prim_pyth_trips(limit):
i = prim
for _ in range(limit//prim[2]):
yield i
i = i + prim
_
list(gen_prim_pyth_trips(10**4))
は1593要素で戻るのに2.81ミリ秒かかりましたが、list(gen_all_pyth_trips(10**4))
は12471要素で戻るのに19.8ミリ秒かかりました
参考までに、 受け入れられた回答(Pythonで) 12471要素に対して38秒かかりました。
楽しみのために、上限を100万に設定するとlist(gen_all_pyth_trips(10**6))
は、1980642要素で2.66秒で返されます(3秒でほぼ200万トリプル)。 list(gen_all_pyth_trips(10**7))
は、リストが非常に大きくなり、RAMの最後のビットをすべて消費するため、コンピューターをひざまずかせます。 sum(1 for _ in gen_all_pyth_trips(10**7))
のようなことをすると、その制限を回避し、23471475要素で30秒で戻ります。
X <y <zを定義する必要があります。
for x in range (1, 1000):
for y in range (x + 1, 1000):
for z in range(y + 1, 1000):
もう1つの優れた最適化は、xとyのみを使用し、zsqr = x * x + y * yを計算することです。 zsqrが平方数の場合(またはz = sqrt(zsqr)が整数の場合)、それはトリプレットです。それ以外の場合はそうではありません。そうすれば、必要なループは3つではなく2つだけです(たとえば、これは約1000倍高速です)。
ピタゴラストリプレット を生成するための前述のアルゴリズムはすべて、基本的な関係a^2 + b^2 = c^2
から派生した単純なアプローチの変更です。ここで、(a, b, c)
は正の整数のトリプレットです。ピタゴラストリプレットは、すべてのピタゴラストリプレットを生成するために使用できるかなり注目に値する関係を満たしていることがわかります。
Euclid 最初のそのような関係を発見しました。彼は、すべてのピタゴラストリプル(a, b, c)
について、おそらくa
とb
を並べ替えた後、互いに素な正の整数m
とn
があると判断しました。 m > n
(少なくとも1つは偶数)と正の整数k
を使用して、
a = k (2mn)
b = k (m^2 - n^2)
c = k (m^2 + n^2)
次に、ピタゴラストリプレットを生成するには、異なるパリティの互いに素な正の整数m
とn
、および正の整数k
を生成し、上記の式を適用します。
struct PythagoreanTriple {
public int a { get; private set; }
public int b { get; private set; }
public int c { get; private set; }
public PythagoreanTriple(int a, int b, int c) : this() {
this.a = a < b ? a : b;
this.b = b < a ? a : b;
this.c = c;
}
public override string ToString() {
return String.Format("a = {0}, b = {1}, c = {2}", a, b, c);
}
public static IEnumerable<PythagoreanTriple> GenerateTriples(int max) {
var triples = new List<PythagoreanTriple>();
for (int m = 1; m <= max / 2; m++) {
for (int n = 1 + (m % 2); n < m; n += 2) {
if (m.IsRelativelyPrimeTo(n)) {
for (int k = 1; k <= max / (m * m + n * n); k++) {
triples.Add(EuclidTriple(m, n, k));
}
}
}
}
return triples;
}
private static PythagoreanTriple EuclidTriple(int m, int n, int k) {
int msquared = m * m;
int nsquared = n * n;
return new PythagoreanTriple(k * 2 * m * n, k * (msquared - nsquared), k * (msquared + nsquared));
}
}
public static class IntegerExtensions {
private static int GreatestCommonDivisor(int m, int n) {
return (n == 0 ? m : GreatestCommonDivisor(n, m % n));
}
public static bool IsRelativelyPrimeTo(this int m, int n) {
return GreatestCommonDivisor(m, n) == 1;
}
}
class Program {
static void Main(string[] args) {
PythagoreanTriple.GenerateTriples(1000).ToList().ForEach(t => Console.WriteLine(t));
}
}
ピタゴラストリプルを生成するための式 に関するウィキペディアの記事には、他のそのような式が含まれています。
アルゴリズムは、速度、メモリ使用量、単純さなどに合わせて調整できます。
これは、メモリ使用量と単純さを犠牲にして、速度を調整した_pythagore_triplets
_アルゴリズムです。あなたが望むのがスピードだけなら、これは行く方法かもしれません。
list(pythagore_triplets(10000))
の計算は私のコンピューターでは40秒かかりますが、ΤΖΩΤΖΙΟΥのアルゴリズムでは63秒、Tafkasのアルゴリズム(および2つではなく3つの埋め込みループを使用する他のすべてのアルゴリズム)では数日かかる可能性があります。
_def pythagore_triplets(n=1000):
maxn=int(n*(2**0.5))+1 # max int whose square may be the sum of two squares
squares=[x*x for x in xrange(maxn+1)] # calculate all the squares once
reverse_squares=dict([(squares[i],i) for i in xrange(maxn+1)]) # x*x=>x
for x in xrange(1,n):
x2 = squares[x]
for y in xrange(x,n+1):
y2 = squares[y]
z = reverse_squares.get(x2+y2)
if z != None:
yield x,y,z
>>> print list(pythagore_triplets(20))
[(3, 4, 5), (5, 12, 13), (6, 8, 10), (8, 15, 17), (9, 12, 15), (12, 16, 20)]
_
最初の10億個のトリプレットを計算する場合、メモリ不足エラーのため、このアルゴリズムは開始する前にクラッシュすることに注意してください。したがって、ΤΖΩΤΖΙΟΥのアルゴリズムは、nの値が高い場合におそらくより安全な選択です。
ところで、これがTafkasのアルゴリズムで、パフォーマンステストの目的でpythonに変換されています。その欠点は、2つではなく3つのループが必要になることです。
_def gcd(a, b):
while b != 0:
t = b
b = a%b
a = t
return a
def find_triple(upper_boundary=1000):
for c in xrange(5,upper_boundary+1):
for b in xrange(4,c):
for a in xrange(3,b):
if (a*a + b*b == c*c and gcd(a,b) == 1):
yield a,b,c
_
def pyth_triplets(n=1000):
"Version 1"
for x in xrange(1, n):
x2= x*x # time saver
for y in xrange(x+1, n): # y > x
z2= x2 + y*y
zs= int(z2**.5)
if zs*zs == z2:
yield x, y, zs
>>> print list(pyth_triplets(20))
[(3, 4, 5), (5, 12, 13), (6, 8, 10), (8, 15, 17), (9, 12, 15), (12, 16, 20)]
V.1アルゴリズムでは、x
値が単調に増加しています。
この質問はまだ生きているようです:)
戻ってコードを再検討したので、以前の提案のほぼ4倍の速度(N = 10000の場合はCPU時間の約26%)である2番目のアプローチを試しました。これにより、多くの不要な計算が回避されます。
def pyth_triplets(n=1000):
"Version 2"
for z in xrange(5, n+1):
z2= z*z # time saver
x= x2= 1
y= z - 1; y2= y*y
while x < y:
x2_y2= x2 + y2
if x2_y2 == z2:
yield x, y, z
x+= 1; x2= x*x
y-= 1; y2= y*y
Elif x2_y2 < z2:
x+= 1; x2= x*x
else:
y-= 1; y2= y*y
>>> print list(pyth_triplets(20))
[(3, 4, 5), (6, 8, 10), (5, 12, 13), (9, 12, 15), (8, 15, 17), (12, 16, 20)]
このアルゴリズムではz
値が増加していることに注意してください。
アルゴリズムがCに変換された場合(金属に近いため、乗算は加算よりも時間がかかります)、連続する正方形間のステップが次のとおりであるという事実を考えると、必要な乗算を最小限に抑えることができます。
(x + 1)²-x²=(x + 1)(x + 1)-x²=x²+ 2x +1--x²= 2x + 1
したがって、すべての内部x2= x*x
およびy2= y*y
は、次のように加算と減算に変換されます。
def pyth_triplets(n=1000):
"Version 3"
for z in xrange(5, n+1):
z2= z*z # time saver
x= x2= 1; xstep= 3
y= z - 1; y2= y*y; ystep= 2*y - 1
while x < y:
x2_y2= x2 + y2
if x2_y2 == z2:
yield x, y, z
x+= 1; x2+= xstep; xstep+= 2
y-= 1; y2-= ystep; ystep-= 2
Elif x2_y2 < z2:
x+= 1; x2+= xstep; xstep+= 2
else:
y-= 1; y2-= ystep; ystep-= 2
もちろん、Python実際に生成された余分なバイトコード遅くなるバージョン2と比較してアルゴリズムですが、V.3の方が速いと思います:) Cで。
みんな乾杯:)
カイル・ガリオンの答えを拡張して、トリプルが斜辺、次に最長の辺でソートされるようにしました。
Numpyは使用しませんが、 this one などのSortedCollection(またはSortedList)が必要です。
def primitive_triples():
""" generates primitive Pythagorean triplets x<y<z
sorted by hypotenuse z, then longest side y
through Berggren's matrices and breadth first traversal of ternary tree
:see: https://en.wikipedia.org/wiki/Tree_of_primitive_Pythagorean_triples
"""
key=lambda x:(x[2],x[1])
triples=SortedCollection(key=key)
triples.insert([3,4,5])
A = [[ 1,-2, 2], [ 2,-1, 2], [ 2,-2, 3]]
B = [[ 1, 2, 2], [ 2, 1, 2], [ 2, 2, 3]]
C = [[-1, 2, 2], [-2, 1, 2], [-2, 2, 3]]
while triples:
(a,b,c) = triples.pop(0)
yield (a,b,c)
# expand this triple to 3 new triples using Berggren's matrices
for X in [A,B,C]:
triple=[sum(x*y for (x,y) in Zip([a,b,c],X[i])) for i in range(3)]
if triple[0]>triple[1]: # ensure x<y<z
triple[0],triple[1]=triple[1],triple[0]
triples.insert(triple)
def triples():
""" generates all Pythagorean triplets triplets x<y<z
sorted by hypotenuse z, then longest side y
"""
prim=[] #list of primitive triples up to now
key=lambda x:(x[2],x[1])
samez=SortedCollection(key=key) # temp triplets with same z
buffer=SortedCollection(key=key) # temp for triplets with smaller z
for pt in primitive_triples():
z=pt[2]
if samez and z!=samez[0][2]: #flush samez
while samez:
yield samez.pop(0)
samez.insert(pt)
#build buffer of smaller multiples of the primitives already found
for i,pm in enumerate(prim):
p,m=pm[0:2]
while True:
mz=m*p[2]
if mz < z:
buffer.insert(Tuple(m*x for x in p))
Elif mz == z:
# we need another buffer because next pt might have
# the same z as the previous one, but a smaller y than
# a multiple of a previous pt ...
samez.insert(Tuple(m*x for x in p))
else:
break
m+=1
prim[i][1]=m #update multiplier for next loops
while buffer: #flush buffer
yield buffer.pop(0)
prim.append([pt,2]) #add primitive to the list
コードは math2 module of my Python library で入手できます。一連のOEISに対してテストされています(コード ここ 下部)、これで私は A121727で間違いを見つける :-)
私はそのプログラムをRubyで作成し、pythonの実装に似ています。重要な行は次のとおりです。
if x*x == y*y + z*z && gcd(y,z) == 1:
次に、指定された2つの数値の最大公約数(gcd)を返すメソッドを実装する必要があります。 Rubyの非常に単純な例:
def gcd(a, b)
while b != 0
t = b
b = a%b
a = t
end
return a
end
トリプレットを見つけるための完全なRuby methonは、次のようになります。
def find_triple(upper_boundary)
(5..upper_boundary).each {|c|
(4..c-1).each {|b|
(3..b-1).each {|a|
if (a*a + b*b == c*c && gcd(a,b) == 1)
puts "#{a} \t #{b} \t #{c}"
end
}
}
}
end
from math import sqrt
from itertools import combinations
#Pythagorean triplet - a^2 + b^2 = c^2 for (a,b) <= (1999,1999)
def gen_pyth(n):
if n >= 2000 :
return
ELEM = [ [ i,j,i*i + j*j ] for i , j in list(combinations(range(1, n + 1 ), 2)) if sqrt(i*i + j*j).is_integer() ]
print (*ELEM , sep = "\n")
gen_pyth(200)
はいあります。
さて、今あなたは理由を知りたいでしょう。 z> yになるように制約しないのはなぜですか?試してみてください
for z in range (y+1, 1000)
古い質問ですが、私はまだ自分のものを入力します。ユニークなピタゴラストリプルを生成する一般的な方法は2つあります。 1つはスケーリングによるもので、もう1つはこの古風な式を使用することによるものです。
基本的にどのようなスケーリングを行うかは、定数nを取り、次にベーストリプルを乗算します。たとえば、3,4,5にnを掛けます。したがって、nを2とすると、次のトリプルは6,8,10になります。
スケーリング
def pythagoreanScaled(n):
triplelist = []
for x in range(n):
one = 3*x
two = 4*x
three = 5*x
triple = (one,two,three)
triplelist.append(triple)
return triplelist
公式の方法では、数値xを取り、2m、m ^ 2 + 1、およびm ^ 2-1を計算すると、これら3つは常にピタゴラストリプレットになるという事実を使用します。
式
def pythagoreantriple(n):
triplelist = []
for x in range(2,n):
double = x*2
minus = x**2-1
plus = x**2+1
triple = (double,minus,plus)
triplelist.append(triple)
return triplelist
ユークリッドのピタゴラストリプレットの証明を使用する必要があります。以下に従ってください...
Uは、ゼロより大きい任意の数を選択できます。たとえば、_m,n
_
Euclidによると、トリプレットはa(m*m-n*n)
、b(2*m*n)
、c(m*m+n*n)
になります。
次に、この式を適用してトリプレットを見つけます。トリプレットの1つの値が6であるとすると、他の2つですか。 Ok解決しましょう...
a(m*m-n*n)
、b(2*m*n)
、c(m*m+n*n)
b(2*m*n)
が明らかに偶数であることは確かです。だから今
_(2*m*n)=6 =>(m*n)=3 =>m*n=3*1 =>m=3,n=1
_
Uは、3と1以外の任意の値を取ることができますが、これら2つの値は、3 _(m*n=3)
_である2つの数値の積を保持する必要があります。
さて、_m=3
_と_n=1
_のとき、
a(m*m-n*n)=(3*3-1*1)=8
、c(m*m-n*n)=(3*3+1*1)=10
6,8,10は価値のトリプレットであり、これはトリプレットの生成方法を視覚化したものです。
与えられた数が_(9)
_のように奇数の場合、b(2*m*n)
のため、ここでわずかに変更されます
決して奇妙になることはありません。だから、ここで私たちは取らなければなりません
a(m*m-n*n)=7
、_(m+n)*(m-n)=7*1
_、つまり、_(m+n)=7
_、_(m-n)=1
_
ここからmとnを見つけてから、他の2つの値を見つけます。
わからない場合は、もう一度よくお読みください。
これに従ってコードを実行すると、個別のトリプレットが効率的に生成されます。
JoelNeelyのバージョン5。
1..Nの範囲では、Xは最大で「N-2」、Yは最大で「N-1」になる可能性があるためです。 Z maxがNで、Y maxがN-1であるため、XはSqrt(N * N-(N-1)*(N-1))= Sqrt(2 * N-1)の最大値であり、3から開始できます。 。
MaxX = ( 2 * N - 1 ) ** 0.5
for x in 3..MaxX {
y = x+1
z = y+1
m = x*x + y*y
k = z * z
while z <= N {
while k < m {
z = z + 1
k = k + (2*z) - 1
}
if k == m and z <= N then {
// use x, y, z
}
y = y + 1
m = m + (2 * y) - 1
}
}
A、b、およびcの場合、Nまでループする必要はないことに注意してください。
Aの場合は1からint(sqrt(n**2/2))+1
に、bの場合は_a+1
_からint(sqrt(n**2-a**2))+1
に、cの場合はint(sqrt(a**2+b**2)
からint(sqrt(a**2+b**2)+2
。
あなたはこれを試すことができます
triplets=[]
for a in range(1,100):
for b in range(1,100):
for c in range(1,100):
if a**2 + b**2==c**2:
i=[a,b,c]
triplets.append(i)
for i in triplets:
i.sort()
if triplets.count(i)>1:
triplets.remove(i)
print(triplets)
確認するだけですが、私は次のコードを使用してピタゴラストリプルを作成しています。それは非常に高速です(そして私はここでいくつかの例を試しましたが、私はそれらを学び、自分で書き、戻ってきてここでチェックしました(2年前))。このコードは、(制限に名前を付ける)までのすべてのピタゴラストリプルを正しく検出し、かなり迅速に検出すると思います。私はそれを作るためにC++を使用しました。
ullongはunsignedlong longであり、ルート関数を2乗してルート化する関数をいくつか作成しました。基本的に、指定された数の平方根(整数(整数)にした後)の2乗が等しくない場合は、1を返します。ルート可能。 _squareと_rootは上記の説明のように期待どおりに動作します。それを最適化する別の方法を知っていますが、まだ実行もテストもしていません。
generate(vector<Triple>& triplist, ullong limit) {
cout<<"Please wait as triples are being generated."<<endl;
register ullong a, b, c;
register Triple trip;
time_t timer = time(0);
for(a = 1; a <= limit; ++a) {
for(b = a + 1; b <= limit; ++b) {
c = _root(_square(a) + _square(b));
if(c != -1 && c <= limit) {
trip.a = a; trip.b = b; trip.c = c;
triplist.Push_back(trip);
} else if(c > limit)
break;
}
}
timer = time(0) - timer;
cout<<"Generated "<<triplist.size()<<" in "<<timer<<" seconds."<<endl;
cin.get();
cin.get();
}
みなさんのご意見をお聞かせください。それは私がそれを提出した先生に従ってすべての原始的および非原始的なトリプルを生成します。 (私が正しく覚えていれば、彼女はそれを100までテストしました)。
ここで以前のコーダーによって提供されたv4からの結果は次のとおりです。
以下は、「use x、y、z」が実装された、あまり科学的ではないタイミングのセットです(Javaを使用して、古いラップトップで他のものを実行している古いラップトップで...) Tripleオブジェクトを3つの値でインスタンス化し、それをArrayListに配置します(これらの実行では、Nは10,000に設定され、それぞれ12,471のトリプルが生成されました)。
バージョン4:46秒平方根を使用:134秒。配列とマップ:400秒。
私の結果は、生成するトリプルの数です:10000
トリプルが生成されるまでお待ちください。 2秒で12471を生成しました。
それは私がコンパイラーを介して最適化を始める前です。 (以前は、たくさんの特別なオプションなどを使用して、10000を0秒に短縮したことを覚えています)。私のコードはまた、side1,2、hypが3.2分でどれだけ高くなることができるかの制限として100,000ですべてのトリプルを生成します(1,000,000の制限は1時間かかると思います)。
コードを少し変更して、10,000の制限を1秒に減らしました(最適化なし)。その上、慎重に考えると、私のものはチャンクに分割され、1〜25,000の範囲の特定の範囲(たとえば、100,000が3つのCPU(念のためにCPU時間を消費するために1つ余分に)に対して4つの等しいチャンクに分割されます) (1から開始して25,000に制限)、25,000から50,000、50,000から75,000、および75,000で終了します。これを実行して、速度が上がるかどうかを確認します(スレッドは事前に作成されており、実際の量には含まれていません)より正確なタイマーとベクトルを連結する方法が必要です。13.4GHZcpuと8gb ramを自由に使用できる場合、1秒で10,000 as lim、次に3cpusを実行できると思います。 1/3秒でそれを行う必要があります(そして私はatmのように高い秒に丸めます)。
# To find all pythagorean triplets in a range
import math
n = int(input('Enter the upper range of limit'))
for i in range(n+1):
for j in range(1, i):
k = math.sqrt(i*i + j*j)
if k % 1 == 0 and k in range(n+1):
print(i,j,int(k))