web-dev-qa-db-fra.com

Génération de triplés de Pythagore uniques et ordonnés

C’est un programme que j’ai écrit pour calculer les triplets de Pythagore. Lorsque j'exécute le programme, il imprime deux fois chaque groupe de triplets à cause de l'instruction if. Est-il possible de dire au programme de n'imprimer qu'une fois un nouvel ensemble de triplets? Merci.

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 __== '__main__':
    main()  
27
marc lincoln

Les triplets de Pythagore sont un bon exemple de revendication "forboucles considérées comme nuisibles ", parce que forboucles nous incitent à penser au comptage, souvent la partie la moins pertinente de la tâche. 

(Je vais m'en tenir au pseudo-code pour éviter les distorsions de langage et pour garder le pseudo-code rationalisé, je n'optimiserai pas plusieurs calculs, par exemple, x * x et y * y.)

Version 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
            }
        }
    }
}

est la pire solution. Il génère des doublons et traverse des parties de l’espace qui ne sont pas utiles (par exemple, chaque fois que z < y). Sa complexité temporelle est cubique sur Nname__.

La version 2 , la première amélioration, consiste à exiger que x < y < z soit titulaire, comme dans:

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
            }
        }
    }
}

ce qui réduit le temps d'exécution et élimine les solutions en double. Cependant, il est toujours cubique sur Nname__; l'amélioration est simplement une réduction du coefficient de Nname __-cubed.

Il est inutile de continuer à examiner les valeurs croissantes de zaprès que z * z < x * x + y * y ne soit plus valable. Ce fait motive Version 3 , premier pas de l'itération par force brute sur zname__:

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
        }
    }
}

Pour Nof 1000, cela est environ 5 fois plus rapide que la version 2, mais il s'agit de encore cubic sur Nname__.

La remarque suivante est que xet ysont les seules variables indépendantes; zdépend de leurs valeurs et la dernière zconsidérée pour la valeur précédente de yest une bonne valeur de recherche début pour la prochaine valeur de yname__. Cela conduit à Version 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
    }
}

qui autorise yet zà "balayer" les valeurs ci-dessus xune seule fois. Non seulement il est plus de 100 fois plus rapide pour Nof 1000, mais il est quadratique le Nname__, de sorte que la vitesse augmente à mesure que Naugmente.

J'ai rencontré ce type d'amélioration assez souvent pour me méfier de "compter les boucles" pour des utilisations autres que les plus triviales (par exemple, parcourir un tableau).

Mise à jour: Apparemment, j'aurais dû signaler quelques points faciles à oublier à propos de la V4.

  1. Les deux des boucles whilesont contrôlées par la valeur de z(l'une directement, l'autre indirectement par le carré de zname__). whileinterne accélère réellement le whileextérieur, au lieu d'être orthogonal à celui-ci. Il est important de regarder ce que font les boucles et pas seulement de compter le nombre de boucles.

  2. Tous les calculs dans V4 sont strictement arithmétiques entiers. La conversion vers/à partir de la virgule flottante, ainsi que les calculs en virgule flottante, sont coûteux en comparaison.

  3. V4 s'exécute en mémoire constante, ne nécessitant que trois variables entières. Il n'y a pas de tableaux ou de tables de hachage à allouer et à initialiser (et, potentiellement, à provoquer une erreur de mémoire insuffisante).

  4. La question initiale permettait à tous xname__, yet xde varier dans la même plage. V1..V4 a suivi ce modèle.

Vous trouverez ci-dessous un ensemble de minutages peu scientifiques (utilisation de Java sous Eclipse sur mon ordinateur portable ancien avec d'autres éléments en cours d'exécution ...), où "use x, y, z" a été implémenté en instanciant un objet Triple avec les trois valeurs et le mettre dans une ArrayList. (Pour ces exécutions, Na été défini sur 10 000, ce qui a généré 12 471 triples dans chaque cas.)

Version 4:           46 sec.
using square root:  134 sec.
array and map:      400 sec.

L'algorithme "array and map" est essentiellement:

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

L'algorithme "utilisant la racine carrée" est essentiellement:

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

Le code actuel de la V4 est:

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

Notez que x * xest calculé dans la boucle externe (bien que je n'ai pas pris la peine de mettre en cache z * z); des optimisations similaires sont effectuées dans les autres variantes.

Je serai heureux de fournir le code source Java sur demande pour les autres variations que j'ai chronométrées, au cas où je n'aurais pas implémenté quelque chose.

72
joel.neely

Sensiblement plus rapide que toutes les solutions proposées jusqu'à présent. Trouve les triplés via un arbre ternaire.

Wolfram dit:

Hall (1970) et Roberts (1977) prouvent qu'il s'agit d'un triple primitif de Pythagore, si et seulement si

(a,b,c)=(3,4,5)M

où M est un produit fini des matrices U, A, D.

Et là nous avons une formule pour générer chaque triple primitif.

Dans la formule ci-dessus, l'hypoténuse est en croissance constante, il est donc assez facile de vérifier sa longueur maximale.

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

Si vous voulez tous les triples et pas seulement les primitives:

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)) a mis 2,81 millisecondes à revenir avec 1593 éléments tandis que list(gen_all_pyth_trips(10**4)) a pris 19,8 millisecondes à revenir avec 12471 éléments

Pour référence, le réponse acceptée(en python) a pris 38 secondes pour 12471 éléments.

Juste pour le plaisir, fixer la limite supérieure à un million list(gen_all_pyth_trips(10**6)) revient en 2,66 secondes avec 1980642 éléments (près de 2 millions de triples en 3 secondes). list(gen_all_pyth_trips(10**7)) met mon ordinateur à genoux car la liste devient si longue qu'elle consomme le moindre morceau de bélier. Faire quelque chose comme sum(1 for _ in gen_all_pyth_trips(10**7)) contourne cette limitation et retourne en 30 secondes avec 23471475 éléments.

Pour plus d'informations sur l'algorithme utilisé, consultez les articles sur Wolfram et Wikipedia .

40
Kyle Gullion

Vous devriez définir x <y <z.

for x in range (1, 1000):
    for y in range (x + 1, 1000):
            for z in range(y + 1, 1000):

Une autre bonne optimisation serait d’utiliser uniquement x et y et de calculer zsqr = x * x + y * y. Si zsqr est un nombre carré (ou z = sqrt (zsqr est un nombre entier), il s'agit d'un triplet, sinon. De cette façon, vous n'avez besoin que de deux boucles au lieu de trois (pour votre exemple, c'est environ 1000 fois plus vite).

13
schnaader

Les algorithmes précédemment cités pour générer les triplets de Pythagore sont toutes des modifications de l'approche naïve dérivée de la relation de base a^2 + b^2 = c^2(a, b, c) est un triplet d'entiers positifs. Il s'avère que les triplets de Pythagore répondent à des relations assez remarquables qui peuvent être utilisées pour générer tous les triplés de Pythagore.

Euclid a découvert la première relation de ce type. Il a déterminé que pour chaque triple (a, b, c) de Pythagore, éventuellement après une réorganisation de a et b, il existe des entiers positifs relativement premiers m et n avec m > n, dont au moins un est pair, et un entier positif k tel que

a = k (2mn)
b = k (m^2 - n^2)
c = k (m^2 + n^2)

Ensuite, pour générer des triplets de Pythagore, générez des entiers positifs relativement premiers m et n de parité différente, ainsi qu'un entier positif k et appliquez la formule ci-dessus.

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

L'article de Wikipedia sur Formules permettant de générer des triples de Pythagore contient d'autres formules de ce type.

11
jason

Les algorithmes peuvent être ajustés pour la vitesse, l'utilisation de la mémoire, la simplicité, etc.

Voici un algorithme pythagore_triplets réglé pour la vitesse, au détriment de la mémoire et de sa simplicité. Si tout ce que vous voulez est la vitesse, cela pourrait être la voie à suivre.

Le calcul de list(pythagore_triplets(10000)) prend 40 secondes sur mon ordinateur, contre 63 secondes pour l'algorithme de Ω, et éventuellement plusieurs jours de calcul pour l'algorithme de Tafkas (et tous les autres algorithmes utilisant 3 boucles intégrées au lieu de 2).

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

Notez que si vous comptez calculer le premier milliard de triplets, cet algorithme se bloquera avant même de commencer, en raison d'une erreur de mémoire insuffisante. L'algorithme de ΤΖΩ probably est donc probablement un choix plus sûr pour les valeurs élevées de n.

BTW, voici l'algorithme de Tafkas, traduit en python pour les besoins de mes tests de performance. Son défaut est de requérir 3 boucles au lieu de 2.

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
8
MiniQuark
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)]

L'algorithme V.1 a des valeurs x croissantes de façon monotone.

MODIFIER

Il semble que cette question est toujours d'actualité :)
Depuis que je suis revenu et que j'ai revisité le code, j'ai essayé une deuxième approche presque quatre fois plus rapide (environ 26% du temps de calcul pour N = 10000) que ma suggestion précédente, car elle évite de nombreux calculs inutiles:

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

Notez que cet algorithme a des valeurs z croissantes.

Si l'algorithme était converti en C - là où, étant plus proches du métal, les multiplications prennent plus de temps que les additions - on pourrait minimiser les multiplications nécessaires, étant donné que le pas entre les carrés consécutifs est:

(x + 1) ² - x² = (x + 1) (x + 1) - x² = x² + 2x + 1 - x² = 2x + 1

de sorte que tous les x2= x*x et y2= y*y intérieurs seraient convertis en additions et soustractions comme ceci:

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

Bien sûr, en Python, le bytecode supplémentaire produit en réalité ralentit l’algorithme par rapport à la version 2, mais je parierais (sans vérifier :) que la V.3 est plus rapide en C.

Salut tout le monde :)

6
tzot

J'ai juste étendu la réponse de Kyle Gullion pour que les triples soient triés par hypothenuse, puis par le plus long côté.

Il n’utilise pas numpy, mais nécessite une SortedCollection (ou SortedList) telle que this one

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

le code est disponible dans le module math2 of ma librairie Python . Il est testé par rapport à certaines séries de l’OEIS (code ici en bas), ce qui m’a permis de trouver une erreur dans A121727 :-)

3
Dr. Goulu

J'ai écrit ce programme en Ruby et cela ressemble à l'implémentation de python. La ligne importante est:

if x*x == y*y + z*z && gcd(y,z) == 1:

Ensuite, vous devez implémenter une méthode qui renvoie le plus grand commun diviseur (gcd) de deux nombres donnés. Encore un exemple très simple en Ruby:

def gcd(a, b)
    while b != 0
      t = b
      b = a%b
      a = t
    end
    return a
end

La méthode complète Ruby pour trouver les triplés serait:

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
2
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)
1
Kaushik Nayak

Oui il y a.

Bon, maintenant vous voudrez savoir pourquoi. Pourquoi ne pas simplement le contraindre pour que z> y? Essayer 

for z in range (y+1, 1000)
1
Pitarou

Vieille question, mais je vais quand même saisir mes données. Il existe deux façons générales de générer des triples pythagoriciens uniques. L'un est par mise à l'échelle et l'autre en utilisant cette formule archaïque.

Quelle mise à l'échelle prend-elle fondamentalement une constante n, puis multiplie une base triple, disons 3,4,5 par n. Donc, si n est égal à 2, nous obtenons 6,8,10 notre prochain triple.

Mise à l'échelle

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

La méthode de la formule utilise le fait que si nous prenons un nombre x, calculons 2m, m ^ 2 + 1 et m ^ 2-1, ces trois seront toujours un triplet de Pythagore.

Formule

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
1

Version 5 à Joel Neely.

Puisque X peut avoir un maximum de 'N-2' et Y peut être un maximum de 'N-1' pour une plage de 1..N. Puisque Z max est N et Y max est N-1, X peut être max de Sqrt (N * N - (N-1) * (N-1)) = Sqrt (2 * N - 1) et peut commencer à 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
  }
 }
0
lakshmanaraj

Il convient de noter que pour a, b et c, vous n'avez pas besoin de boucler complètement jusqu'à N.

Pour a, il suffit de boucler de 1 à int(sqrt(n**2/2))+1, pour b, a+1 à int(sqrt(n**2-a**2))+1 et pour c de int(sqrt(a**2+b**2) à int(sqrt(a**2+b**2)+2.

0
user2557303

Tu peux essayer ça

  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)
0
Geetanjali

Je vérifie juste, mais j’utilise le code suivant pour créer des triples pythagoriciens. C'est très rapide (et j'ai essayé quelques exemples ici, bien que je les ai en quelque sorte appris et écrit le mien et que je sois revenu et vérifié ici (il y a 2 ans)). Je pense que ce code trouve correctement tous les triples pythagoriciens jusqu'à (nommez votre limite) et assez rapidement aussi. J'ai utilisé le C++ pour le faire.

ullong est unsigned long long et j'ai créé quelques fonctions pour square et root ma fonction root est fondamentalement dite si la racine carrée d'un nombre donné (après l'avoir converti en un nombre entier (entier)) ne correspond pas au nombre entier puis donne retour - 1 parce que ce n'est pas enracinable. _ square et _root agissent comme prévu à la description ci-dessus, je connais une autre façon de l'optimiser, mais je ne l'ai pas encore fait ni testé.

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

}

Faites-moi savoir ce que chacun de vous pensez. Il génère tous les triples primitifs et non primitifs en fonction de l'enseignant pour lequel je l'ai rendu. (elle a testé jusqu'à 100 si je me souviens bien).

Les résultats de la v4 fournie par un codeur précédent sont:

Vous trouverez ci-dessous un ensemble de minutages peu scientifiques (utilisation de Java sous Eclipse sur mon ordinateur portable ancien avec d'autres éléments en cours d'exécution ...), où "use x, y, z" a été implémenté en instanciant un objet Triple avec les trois valeurs et le mettre dans une ArrayList. (Pour ces exécutions, N a été fixé à 10 000, ce qui a produit 12 471 triples dans chaque cas.)

Version 4: 46 sec. Avec racine carrée: 134 sec. Matrice et carte: 400 sec.

Les résultats de la mienne sont Combien de triples générer: 10000

Veuillez patienter car des triples sont générés. Généré 12471 en 2 secondes.

C'est avant même que je commence à optimiser via le compilateur. (Je me souviens d’avoir eu jusqu’à présent 10 000 à 0 seconde avec des tonnes d’options spéciales). Mon code génère également tous les triples avec 100 000 comme limite de hauteur de côté1,2, hyp peut aller en 3,2 minutes (je pense que la limite de 1 000 000 prend une heure).

J'ai légèrement modifié le code et obtenu une limite de 10 000 points à 1 seconde (aucune optimisation). En plus de cela, en réfléchissant bien, le mien pourrait être divisé en morceaux et fileté sur des intervalles donnés (par exemple, 100 000 divisés en 4 morceaux égaux pour 3 cpu (1 supplémentaire pour consommer, espérons-le, du temps au cas par cas) avec des intervalles allant de 1 à 25 000. (commencez à 1 et limitez-le à 25 000), 25 000 à 50 000, 50 000 à 75 000 et 75 000 jusqu'à la fin. Je peux le faire et voir si cela accélère le processus (j'aurai des fils prédéfinis et je ne les inclurai pas dans le montant réel. Il me faudrait un chronomètre plus précis et un moyen de concaténer les vecteurs. Je pense que si 1 unité de commande à la vitesse de 3,4 GHz dispose de 8 Go de mémoire vive à sa disposition, elle peut faire 10 000 fois la limite en 1 seconde, puis 3 unités centrales. devrait le faire en 1/3 par seconde (et j'arrondis à la seconde plus haute comme est atm).

0
user270701
# 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))
0
Arun