|
Publicité ' | ||||||||||||||||||||||||
|
|
#21 | ||
|
Expert Confirmé Sénior
![]() ![]() ![]() Inscription : novembre 2005 Messages : 4 970 ![]() |
J'aurais vraissemblablement pas le temps de faire quelque chose de sérieux dans un proche avenir, donc voici mon code.
L'idée que j'aimerais explorer, c'est le fait que le DAG est symétrique si on impose que la feuille soit au niveau n. Ca devrait permettre d'éliminer a priori de ne pas calculer les feuilles qui sont aux niveaux inférieurs. Code C++ :
__________________
Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça. |
||
|
|
00
|
|
|
#22 | ||
![]() ![]() Xavier PhilippeauArchitecte système Inscription : décembre 2006 Messages : 9 815 ![]() |
La version récursive java ressemble ENORMEMENT, même dans le nom des variables
![]() Code java :
__________________
ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple. |
||
|
00
|
|
|
#23 |
|
Expert Confirmé Sénior
![]() ![]() ![]() Inscription : novembre 2005 Messages : 4 970 ![]() |
Si j'ai bien suivi, tu parcours tous les chemins du DAG, j'evite de le faire en utilisant de la programmation dynamique. Tu aurais le meme resultat en memorisant les resultats des appels a explore, sans oublie que cette fonction a un parametre cache.
__________________
Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça. |
|
|
00
|
|
|
#24 | |
![]() ![]() Xavier PhilippeauArchitecte système Inscription : décembre 2006 Messages : 9 815 ![]() |
Citation:
La version que j'ai postée ici (donc sans le cache) donne 250ms.
__________________
ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple. |
|
|
00
|
|
|
#25 | ||||
|
Expert Confirmé Sénior
![]() ![]() ![]() Inscription : novembre 2005 Messages : 4 970 ![]() |
Code :
Code shell :
__________________
Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça. |
||||
|
|
00
|
|
|
#26 | ||
|
Candidat au titre de Membre du Club
![]() Inscription : avril 2008 Messages : 10 ![]() |
J'ai découvert par hasard votre forum. Je réponds en Caml Light.
Pour éviter le débordement des entiers. La réponse est donnée sous forme d'un produit. Le dernier calcul pouvant être effectué est n=8, k=4 (environ 5 ks) sinon la réponse devient négative pour raison de débordement d'entier. J'ai effectué une permutation de la première colonne et aussi de la première ligne. Ce qui explique la multiplication non effectuée dans la réponse. Ma méthode consiste en deux fonctions récursives qui s'appellent mutuellement. On parcourt ainsi un graphe virtuel (programmation dynamique). Voici le code qui a l'avantage d'être court: Code :
|
||
|
|
00
|
|
|
#27 | |||
|
Expert Confirmé Sénior
![]() ![]() Frédéric Ingénieur développement logiciels Inscription : février 2006 Messages : 3 495 ![]() |
Moi aussi, j'ai découvert les défis hier et je viens de coder une soluce en Python
Citation:
En effet, imaginons une demande sur le couple (5, 3), on peut alors partir de l'hypothèse que chaque ligne n'aura que 3 jetons (comme l'a dit Jean-Marc). Mais si on part de la ligne "0 0 1 1 1", on s'aperçoit qu'il suffit d'incrémenter la ligne de 1 jusqu'à trouver la ligne suivante qui convient. Ainsi on passe par dessus "0 1 0 0 0", "0 1 0 0 1", "0 1 0 1 0" et on arrive jusqu'à "0 1 0 1 1". Ensuite si on regarde la matrice complète, alors elle démarre de cette façon 0 0 1 1 1 0 0 1 1 1 0 0 1 1 1 0 0 1 1 1 0 0 1 1 1 Ensuite il suffit d'incrémenter la matrice, c.a.d. incrémenter la 5° ligne. Dès que la 5° ligne a atteint son max, soit "1 1 1 0 0", alors on la repasse à "0 0 1 1 1" mais on incrémente la 4° ligne qui passe alors à 0 1 0 1 1". Et ainsi de suite. Chaque ligne qui ne convient pas s'incrémente automatiquement jusqu'à convenir. Et une fois qu'on arrive sur une position finalisée (où toutes les lignes conviennent), il suffit de regarder si la somme de chaque colonne convient. Et on termine dès que les 5 lignes sont à "1 1 1 0 0" Voici le code Python Code Python :
[EDIT]Bon, mauvais algo. Je trouve les bonnes valeurs pour (4, 2), (5, 2) et (6, 2) mais la recherche (6, 2) a pris 5 bonnes minutes. Je vais maintenant examiner la solution de Jean-Marc... 67950... [EDIT 2]Super mauvais algo. J'ai lancé (9, 4) il y a plus d'une heure et toujours pas de réponse...
__________________
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche. Tout ce qu'un individu reçoit sans rien faire pour l'obtenir, un autre individu a dû travailler pour le produire sans en tirer profit. Tout Pouvoir ne peut distribuer aux uns que ce qu'il a préalablement confisqué à d'autres car on n'accroît pas les biens en les divisant. Quand la moitié d'un peuple croit qu'il ne sert à rien de faire des efforts car l'autre moitié les fera pour elle, et quand cette dernière moitié se dit qu'il ne sert à rien d'en faire car ils bénéficieront à d'autres, cela s'appelle le déclin et la fin d'une nation. Dr. Adrian Rogers, 1931 |
|||
|
|
00
|
|
|
#28 |
|
Expert Confirmé Sénior
![]() ![]() ![]() Inscription : novembre 2005 Messages : 4 970 ![]() |
La réponse est 315 031 400 802 720, donc un algo qui génère les solutions et ne se contente pas de les compter en tenant compte de symétries diverses (ce que fait le mien) devrait en générer près de 10 milliards par seconde pour y arriver en une heure...
__________________
Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça. |
|
|
00
|
|
|
#29 |
|
Expert Confirmé Sénior
![]() ![]() Frédéric Ingénieur développement logiciels Inscription : février 2006 Messages : 3 495 ![]() |
Ou 1 milliard par seconde pour y arriver en 10h (mon pgm n'a toujours pas trouvé actuellement). Mais comme le problème parle d'une énumération de matrices je suis parti sur une génération individuelle (avec même une option d'affichage pour contrôle). Ca dépend évidemment de la façon qu'on a de définir le verbe "énumérer"...
__________________
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche. Tout ce qu'un individu reçoit sans rien faire pour l'obtenir, un autre individu a dû travailler pour le produire sans en tirer profit. Tout Pouvoir ne peut distribuer aux uns que ce qu'il a préalablement confisqué à d'autres car on n'accroît pas les biens en les divisant. Quand la moitié d'un peuple croit qu'il ne sert à rien de faire des efforts car l'autre moitié les fera pour elle, et quand cette dernière moitié se dit qu'il ne sert à rien d'en faire car ils bénéficieront à d'autres, cela s'appelle le déclin et la fin d'une nation. Dr. Adrian Rogers, 1931 |
|
|
00
|
|
|
#30 | ||
|
Candidat au titre de Membre du Club
![]() Inscription : avril 2008 Messages : 10 ![]() |
J'ai repris les idées déjà exposées par les brillants cerveaux de ce forum et j'en ai tiré un code Caml Light très rapide.
Ainsi, il calcule C(9,4) en environ 7s. L'idée est de bien suivre les permutations de colonnes possibles. Si on tient compte de la permutation des lignes sur la première colonne, on doit pouvoir encore gagner un facteur binomial(n-1,k-1) mais je ne l'ai pas fait. J'ai ouvert le module des grands nombres ce qui permet de faire sauter la limitation des entiers. Le programme tel qu'il est présenté est correct jusqu'à n=16 sinon il faut changer cette valeur dans le tableau des coefficients du binome. J'ai essayé de documenter mon programme mais ce n'est pas simple. Tout est récursif sauf la construction du tableau de Pascal Code :
num = 36574751938491748341360000 #- : temps = 12.375 compter 9 4 num = 315031400802720 #- : temps = 7.422*) |
||
|
|
00
|
|
|
#31 | ||
|
Candidat au titre de Membre du Club
![]() Inscription : avril 2008 Messages : 10 ![]() |
Pour tenir compte de la permutation possible des lignes sur la première colonne (mettre tous les 1 en bas à gauche), j'ai légèrement amélioré les deux dernières fonctions de mon précédent algorithme. J'édite ici les modifications (en Caml-Light) de deux ou trois dernières fonctions.
Code :
Voici quelques réponses pour k=2. n=11:num = 158815387962000 #- : temps = 0.047 n=12:num = 21959547410077200 #- : temps = 0.11 n=13:num = 3574340599104475200 #- : temps = 0.313 n=14:num = 676508133623135814000 #- : temps = 0.828 http://www.research.att.com/~njas/se...lish&go=Search. On y trouvera aussi de nombreuses références bibliographiques |
||
|
|
00
|
|
|
#32 | |||
|
Expert Confirmé Sénior
![]() ![]() Frédéric Ingénieur développement logiciels Inscription : février 2006 Messages : 3 495 ![]() |
Citation:
__________________
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche. Tout ce qu'un individu reçoit sans rien faire pour l'obtenir, un autre individu a dû travailler pour le produire sans en tirer profit. Tout Pouvoir ne peut distribuer aux uns que ce qu'il a préalablement confisqué à d'autres car on n'accroît pas les biens en les divisant. Quand la moitié d'un peuple croit qu'il ne sert à rien de faire des efforts car l'autre moitié les fera pour elle, et quand cette dernière moitié se dit qu'il ne sert à rien d'en faire car ils bénéficieront à d'autres, cela s'appelle le déclin et la fin d'une nation. Dr. Adrian Rogers, 1931 |
|||
|
|
00
|
|
|
#33 | ||
|
Invité de passage
![]() Inscription : décembre 2007 Messages : 4 ![]() |
Bonjour,
voici une version qui ne vaudra que pour sa relative concision et quelques singularités (par exemple, simplification des coefficients binomiaux, de sorte qu'il n'en reste aucun à calculer !). On repart du principe introduit par Jean-Marc : la matrice se voit divisée en blocs verticaux. A chaque nouvelle ligne, on injecte les k "1" (les "jetons") dans les différents blocs. Avec par exemple k=9, on décompose les solutions ainsi : - Insérer 9 jetons dans le 1er bloc, et 0 dans les autres. - Insérer 8 jetons dans le 1er bloc, et 1 dans les autres. - ... - Insérer 0 jeton dans le 1er bloc, et 9 dans les autres. Ceci se prête donc bien à une récursion où les blocs seront typiquement organisés en liste. En outre, l'itération 9, 8, 7... n'est pas implémentée en tant que boucle. La fonction d'insertion se charge de renvoyer le nouveau itérateur. Cela permet quelques raccourcis : - si le bloc ne fait que 3 de largeur, impossible d'insérer 9 jetons ! On en insère 3, et on renvoie 2 comme itérateur suivant. - si le bloc contient déjà trop de "1", on invalide le cas, et on fixe l'itérateur à 0. Bref, voici ce que cela donne : Code :
Le résultat est lent : - un des tests d'arrêt n'est pas effectué aussi tôt qu'il le pourrait (je laisse en guise d'exercice la détection de ce soucis !). Une autre version de ce programme corrige ce point, sans résoudre le problème de lenteur. - il s'agit de mon premier programme en Caml. Je mets peut-être en défaut la machine OCaml (pas de récursion terminale pour le parcours de l'arbre des solutions, par exemple ?). De toute façon, l'idéal serait de trouver les éventuelles relations de récurrence pour k>2. Yves |
||
|
|
00
|
|
|
#34 |
|
Membre éclairé
![]() Inscription : février 2007 Messages : 470 ![]() |
J'ai fait une version scheme a base de liste, mais le probleme c'est que je ne sais pas trop a quels endroit je pourrais eviter certaines enumérations. Il faut analyser plus finement le pb
|
|
|
00
|
|
|
#35 | ||||
|
Membre éclairé
![]() ![]() Inscription : juillet 2008 Messages : 152 ![]() |
Bien, voila qui a l'air interessant
Quelqu'un a parle d'une solution 'fractale' Je vais commencer par quelques observations: - On peut inverser les 0 et les 1, ce qui fait que defi4(n, k) = defi4(n, n-k) - Ce faisant il suffit de s'interesser aux grilles qui ont au moins autant de 0 que de 1 - Une solution triviale de (n, k) se compose d'une solution de (m, k) et une solution de (p, k) avec m+p = n et m>=k et p>=k. On remplit le reste de zeros. Par exemple (5, 2): Code :
- On peut echanger un 1 de [a] avec un 0 dans la zone des zeros, pour peu que l'on fasse de meme avec [b]. Par exemple: Code :
|
||||
|
|
00
|
|
|
#36 |
|
Membre éclairé
![]() Inscription : février 2007 Messages : 470 ![]() |
Ouai il doit y avoir des trucs de combinatoire comme ça qui évitent de tout énumérer. L'ennui avec les "trucs" c'est qu'on a vite fait d'oublier des solutions en route même si on gagne beaucoup en vitesse. Le seul truc pour lequel j'étais vraiment sur, c'est qu'il y a C_n^k facons de remplir la premiere ligne par exemple. Mais la combinatoire c'est moyennement mon fort, même si c'est un domaine que je trouve parmi les plus interessants.
__________________
La science est ce que nous comprenons suffisamment bien pour l'expliquer à un ordinateur. L'art, c'est tout ce que nous faisons d'autre. Donald E. Knuth |
|
|
00
|
Copyright © 2000-2013 - www.developpez.com