2013-03-31 2 views
1

Je travaille sur un problème de théorie des graphes théorique qui consiste à prendre des combinaisons d'hypercharges dans un hypergrapha pour analyser les différents cas.en utilisant cython ou PyPy pour optimiser les tuples/listes (algorithme de la théorie des graphes implémenté en python)

J'ai implémenté une version initiale de l'algorithme principal en Python, mais en raison de sa structure combinatoire (et probablement de ma mise en œuvre), l'algorithme est assez lent.

L'un des moyens que j'utilise est d'accélérer PyPy ou Cython.

En regardant la documentation, il semble que Cython n'offre pas une grande rapidité en ce qui concerne les tuples. Cela peut être problématique pour l'implémentation, puisque je représente les hypercharges comme des tuples - donc la majorité de l'algorithme est dans la manipulation des tuples (cependant ils sont tous de la même longueur, environ len 6 chacun). Comme mes compétences C et Python sont assez minimes, j'apprécierais que quelqu'un puisse vous conseiller sur la meilleure façon de procéder pour optimiser le code étant donné sa dépendance aux tuples/listes. Existe-t-il une documentation sur l'utilisation de listes/tuples avec Cython (ou PyPy)?

+0

Il est difficile de suggérer des améliorations sans voir le code, car le problème n'est peut-être pas ce que vous pensez. Dans _general_, la meilleure réponse à l'amélioration de la vitesse est de penser à un meilleur algorithme ... –

+0

Cython peut fonctionner avec des tableaux C et des structures, et vous permet de définir des types d'extension. N'importe lequel d'entre eux pourrait être une alternative aux tuples. –

+0

@Roland, l'algorithme est en fait NP (il est lié à la correspondance en hypergraphes), donc je ne peux pas espérer un algorithme plus optimal que celui que j'ai déjà implémenté. Cependant, je ne suis intéressé que par un cas très spécifique. J'estime le temps d'exécution de mon implémentation naïve en Python, si je peux la faire fonctionner 100 fois plus vite, ce qui la ferait finir dans un délai acceptable (environ 2 semaines). – nsimplex

Répondre

1

quelle serait la meilleure façon de procéder à l'optimisation du code ...

Profile first. Il y a un module standard cProfile qui fait très bien le profilage simple. L'optimisation de votre code avant le profilage est inutile. En outre, pour les graphiques, vous pouvez essayer d'utiliser l'excellent module networkx. En outre, si vous traitez avec de longues listes triées, vous pouvez jeter un oeil aux modules bisect et heapq.

+0

Merci Jakub. le profiler est utile, je l'ai fait fonctionner avant, en l'utilisant, j'estime que j'ai besoin de faire une fonction 100x plus rapide pour que le code se termine dans un temps acceptable pour mon but. J'ai aussi jeté un coup d'œil sur les progiciels de théorie des graphes que vous avez mentionnés et ils sont en effet excellents. Cependant, je ne les ai pas utilisées car en termes d'algorithmes de la théorie des graphes, je n'avais besoin que de correspondance dans les hypergraphes, et j'ai dû l'implémenter de manière spécifique afin de pouvoir utiliser quelques raccourcis. – nsimplex

1

Si votre algorithme est mauvais en termes de complexité de calcul, alors vous ne pouvez pas être sauvé, vous devez l'écrire mieux. Consulter un bon livre de théorie des graphes ou wikipedia, c'est généralement relativement facile, bien qu'il y en ait qui ont des algorithmes à la fois non triviaux et fous. Cela ressemble à une chose que PyPy peut accélérer de manière significative, mais seulement par un facteur constant, mais cela n'implique aucune modification de votre code. Cython n'accélère pas tellement votre code sans les déclarations de type et il semble que ce genre de problème ne peut pas être vraiment accéléré par les types. La partie constante est ce qui est crucial ici - si la complexité de l'algorithme s'est développée comme, disons, 2^n (ce qui est typique pour un algorithme naïf), alors ajouter un nœud supplémentaire au graphique double votre temps. Cela signifie que 10 nœuds ajoutent 1024 fois le temps, 20 nœuds 1024 * 1024 etc. Si vous êtes super chanceux, PyPy peut accélérer votre algorithme de 100x, mais cela reste constant sur la taille du graphique (et vous vous retrouvez rapidement hors de l'univers temps d'une manière ou d'une autre). Pouvez-vous envoyer votre code et mettre en évidence les parties qui sont lentes?

+0

Merci fjal. En effet, tout ce dont j'ai besoin est une accélération de 100x. Ma question est évoquée au point que vous avez soulevé concernant les types de données. Comment puis-je déclarer les tuples python en C pour obtenir une accélération maximale. Et des exemples sur la façon de le faire seraient très appréciés. – nsimplex

+0

vous confondez les choses. Beaucoup. Utilisez simplement PyPy. PyPy n'est pas comme Cython - vous n'avez rien à définir, ça devrait marcher. – fijal

Questions connexes