smeet 2001-10-29 at 12:02pm ccf le casse tete de vero dans j'aio rien a dire.
Le defi est de trouver une configuration sur un echiquer comprenant 8 reines sans qu'aucune d'entre elle ne soit sous la menace d'etre prise.
Trouver une solution est facile.
Parviendrez vous a ecrire un algo efficace calculant TOUTES les solutions ?
Cinq font un et un font cinq : le tout est UNITE.
C'est dans l'incompréhension que je suscite que je trouve ma raison d'être.
Je suis moi, et je le suis parce que les autres ne le sont pas, et que ce sont eux qui forment ma personne.
Inconscience et déraison sont source d'imagination.
Au delà de ma conscience et de mon inconscient, mes rêves créent la réalité.
TiMad 2001-10-29 at 12:08pm je dirais meme plus:
trouver une solution est facile...
en trouver 4 aussi...
en trouver 8 aussi...
en trouver 16 un peut moins
En trouver 32 impossible (il me semble)
XLib v1.00 Powerrrrrrrrrrrrrrrrrrrr!
zewoo 2001-10-29 at 01:45pm TiMad: il y a 92 possibilité pour 8 reines!
Voici un algo pour N reines avec un echiqier de N*N:
#include <stdio.h>
int NombreReines;
int TableauReines[50];
int nonprenable(num){
int i;
if(num > 0)
for (i = 0 ; i < num ; i++)
if ((TableauReines[i] == TableauReines[num]) || (TableauReines[i] == TableauReines[num] + num - i) || (TableauReines[i]==TableauReines[num] - num + i))
return(0); //La reine peut prendre ou etre prise
return(1);
}
void placer(num){
int etat = 0;
int nonplacable = 0;
while ((nonplacable == 0) && (etat == 0)){
TableauReines[num]++;
if (TableauReines[num] > NombreReines){
TableauReines[num] = 0;
nonplacable = 1;
}
else
etat = nonprenable(num);
}
}
void main(void)
{
int Colonne = 0;
long int NombreSolutions = 0;
int i;
do{
printf("nnPlacer N reines en sécurité sur un echiquier de N*N...")
printf("nnCombien de reines ?")
scanf("%d", &NombreReines);
}while(NombreReines > 50); //Si vous voulez plus: modifier int TableauReines[50]!!
for (i = 0 ; i < NombreReines ; i++)
TableauReines[i] = 0;
do{
placer(Colonne);
if (TableauReines[Colonne] != 0){
if (Colonne < NombreReines - 1)
Colonne++;
else{
NombreSolutions++;
printf("%ld ",NombreSolutions);
for (i = 0 ; i < NombreReines ; i++)
printf(" %d",TableauReines[i]);
printf("n")
}
}
else
Colonne--;
}while (TableauReines[0] != 0);
printf("Il y a %ld solutions pour %d reines. ",NombreSolutions ,NombreReines);
}
Pour les courageux qui veulent tester avec bcp de reines: avec 13 reines dans un echiquier de 13*13 on a deja 73712 solutions...
La programmation est un art... Ne prétendons pas en être des virtuoses mais tout au plus des adeptes...
ASM Rulez!!
paxal 2001-10-29 at 02:27pm moi je l'aurai fait en CaML, mais paske j connais presque rien en C
Info: le Caml est en 2è position niveau calculs de maths derrière le C (ou troisième derrière le C++, je sais plus)
Miles 2001-10-29 at 02:52pm Une approche pour trouver une solution est la réparation. Je m'explique :
- Tu prends ta matrice N*N
- Tu place dans chaque colonne une reine
- Tu prends chaque colonne et tu testes
1 - pour chaque case de la colonne le nombre de reines qui peuvent l'atteindre, tant dans les colonnes qui précèdent que dans les colonnes qui suivent
2 - tu choisis la case ayant le nombre le plus faible
- Tu fait ça pour chaque colonne.
- En faisant ça, tu devrais trouver en bouclant.
- Malheureusement, il se peut qu'une solution ne puisse être atteinte par ce moyen, et il faut recommencer dans ce cas.
smeet 2001-10-29 at 04:15pm Les deux algos proposes ici marchent, mais ne me semblent pas efficaces.
La recursivite efficace de base, c'est le mieux, ici, non ?
Cinq font un et un font cinq : le tout est UNITE.
C'est dans l'incompréhension que je suscite que je trouve ma raison d'être.
Je suis moi, et je le suis parce que les autres ne le sont pas, et que ce sont eux qui forment ma personne.
Inconscience et déraison sont source d'imagination.
Au delà de ma conscience et de mon inconscient, mes rêves créent la réalité.
Miles 2001-10-29 at 04:30pm C'est-à-dire par récurrence ?
zewoo 2001-10-29 at 08:18pm smeet: je pense que ma solution est mieux que la recursivité: de toute façon, tu est obligé de tester quasiment toutes les possibilité... donc l'iterativité est mieux (de plus elle est presque toujours plus rapide...)
[edit]Edité par zewoo le 29-10-2001 à 23:50:18[/edit]
La programmation est un art... Ne prétendons pas en être des virtuoses mais tout au plus des adeptes...
ASM Rulez!!
Miles 2001-10-30 at 10:14am Kevin, ta solution teste tout, c'est ça ?
Elle est pas un peu trop lente ?
Miles 2001-10-30 at 05:24pm Elle est plus lente que la mienne, parce qu'elle est en N^8 et la mienne est plutôt en N.
zewoo 2001-11-01 at 12:27pm Miles: tu solution est en o(N)? bizarre ça: parce que avec 8 reines il y a 92 possibilités...
La programmation est un art... Ne prétendons pas en être des virtuoses mais tout au plus des adeptes...
ASM Rulez!!
La solution de Miles ne donnerait jamais toutes les 92 possibilités. Et la mienne, en effet, teste toutes les nCr(64,8)=4426165368 possibilités de placer 8 reines dans 64 cases de l'échiquier.
Au fait, voilà une solution meilleure, qui n'essayera pas de placer plusieurs reines dans la même ligne:
[i]unsigned char a[64],i,j,k,l,m,n,o,p,q,r,s;
for(i=0,i<8,i++)
for(j=8,j<16,j++)
for(k=16,j<24,k++)
for(l=24,j<32,l++)
for(m=32,j<40,m++)
for(n=40,j<48,n++)
for(o=48,j<56,o++)
for(p=56,j<64,p++)
{
memset(a,64,0);
a=a[j]=a[k]=a[l]=a[m]=a[n]=a[o]=a[p]=1;
for(q=0,q<8,q++) if(a[q]+a[q+8]+a[q+16]+a[q+24]+a[q+32]+a[q+40]+a[q+48]+a[q+56]>1) goto skip;
for(q=0,q<15,q++)
{
s=0;
for(r=0,r<=q,r++) s+=a[r*7+q];
if(s>1) goto skip;
s=0;
for(r=0,r<=q,r++) s+=a[r*9-q+7];
if(s>1) goto skip;
}
// afficher la solution
skip:
}
Cela ne testera que 8^8=16777216 possibilités, et de plus on a 8 tests de moins à faire (ceux qui testent s'il y a plusieurs reines sur la même ligne).
Encore une chose: cette solution est en O(n^n) et la précédente était en O((n²)^n)=O(n^(2n)) où n est le nombre de lignes (l'estimation O(n^8) pour la précédente était fausse même si on prend n comme étant le nombre d'éléments puisque le 8 n'est pas constant, c'est le nombre de lignes). Au fait, le O(n^(2n)) n'est pas une bonne estimation pour la solution précédente non plus... (le nombre exact de possibilités testées est nCr(n²,n)) Mais en tout cas, la nouvelle solution est clairement en O(n^n) parce que je teste n^n possibilités.
[edit]Edité par Kevin Kofler le 01-11-2001 à 23:21:41[/edit]
Miles 2001-11-04 at 10:58pm Mon but n'est jamais d'avoir toutes les solutions. J'avais fait ça pour un jeu très connu dont je ne siterais pas le nom que j'avais adapté plusieurs fois. Mais je ne fais plus ce genre de chose : vive l'IA.
ben c le but fixé par le createur d topic en tout cas !

pwet
Miles 2001-11-05 at 12:37pm D'accord, plantage de ma part. Mais il est possible de chopper les 92 solutions avec ce système - seulement qu'on aura peut-être plusieurs fois les mêmes
oxman 2001-11-05 at 01:30pm c un topic dans algo et optimisation non ? ;p
c pas du tout optimisé tont ruc :]
Miles 2001-11-06 at 10:18am Il devrait y avoir mieux que du n^n, puisqu'on sait qu'il n'y a qu'une seule reine par ligne et par colonne. On devrait pouvoir éliminer des cas pour qu'il ne reste plus autant à chercher.
jcop 2001-11-06 at 01:23pm l'algo de Bill-Bop me paraît être la solution la plus élégante.