Forum de mathématiques - Bibm@th.net
Vous n'êtes pas identifié(e).
- Contributions : Récentes | Sans réponse
Pages : 1
#1 01-06-2012 12:17:28
- amady89
- Membre
- Inscription : 01-06-2012
- Messages : 8
programmation scilab
Bonjour,
Il y a un exercice que je n'arrive pas à faire, voici l'énoncé
1)Ecrire une fonction Scilab calculant, pour deux entiers n et K > 1, la suite
des valeurs v(k) definies par v0 = n et pour 0 k < K
v(k+1) =3uk + 1 si uk est impair
et 1/2uk si uk est pair
2) Pour n = 89, calculer uk pour k = 0;.... ;K = 20.
Pouvez vous m'aider ?
Merci par avance.
Hors ligne
#2 01-06-2012 13:56:50
- yoshi
- Modo Ferox
- Inscription : 20-11-2005
- Messages : 17 385
Re : programmation scilab
Bonjour,
Bienvenue à bord...
Je ne connais pas Scilab (je tâcherai de regarder de plus près la syntaxe de ce langage)...
Par contre, je peux essayer de te faire ça en pseudo-code à charge pour toi d'adapter en Scilab.
Le problème est que je trouve cet énoncé très confus et que je serais vraiment surpris que ce soit là une copie conforme de l'énoncé qui a été donné....
Questions.
Tu écris :
des valeurs v(k) definies par v0 = n et pour 0 k < K
v(k+1) =3uk + 1 si uk est impair
et 1/2uk si uk est pair
Tu voulais probablement écrire :
des valeurs vk définies par
v0 = n
et pour 0 < k < K
[tex]v_{k+1}=\begin{cases}3u_k+1, & \text{ si }u_k \text{ est impair}\\\frac{u_k}{2}, & \text{ si }u_k \text{ est pair }\end{cases}[/tex]
Sinon, définir vk par rapport à uk ce serait classique à condition de connaître une définition de uk, d'autant que ta 2e question demande de calculer uk...
Il faut calculer uk ? Et non vk ?
Or je le répète sans ton énoncé, je ne trouve aucune trace de ce qu'est uk...
Je suis peut-être bouché, mais je ne vois donc pas comment calculer ce uk et par suite vk.
Ton exercice est une sorte de variation sur la suite de Syracuse.
@+
Dernière modification par yoshi (01-06-2012 14:01:32)
En ligne
#4 01-06-2012 19:38:29
- yoshi
- Modo Ferox
- Inscription : 20-11-2005
- Messages : 17 385
Re : programmation scilab
Salut,
Bon, c'est vu, il s'agit bien de la suite de Syracuse.
Donc avec Scilab, ça doit être quelque chose comme ce qui suit.
v=n
for k=1:K
reste=modulo(v,2)
if reste =0 then v=v/2
else v=3*v+1
end
end function
n=89
K=20
syracuse(n,K)
disp v
J'ai utilisé une indentation (décalage à gauche) comme en Python pour la clarté.
On fournit en entrée à la fonction syracuse les variables n et K, on attend en retour la valeur de v.
Dans la fonction on initialise v avec la valeur n (c'est le v0)
Puis on écrit une boucle for d'indice k dans laquelle k va parcourir toutes les caleurs de 1 à K.
reste = modulo(v,2) calcule le reste de la division de v par 2.
Si reste = 0 alors v=v/2 (v est pair)
sinon v = 3*v+1 (parce que dans ce cas v est impair)
le end pour marquer la fion de la boucle
le end function pour marquer la fin de la fonction
Fin de la question 1
Pour la question 2 à la suite de la fonction on initiale n à 89 et k à 20.
Et on appelle la fonction syracuse en lui passant en paramètres ces variables n et K
Puis par disp v on affiche le résultat.
Je te reprécise que c'est la première fois que j'utilise Scilab : je ne cinnaissais pas sa syntaxe il y a encore 1 h...
Alors sois indulgente si ça ne marche pas du premier coup : tu corrigeras bien toi-même parce que tu as eu des cours de Scilab...
@+
En ligne
#5 01-06-2012 20:17:37
- amady89
- Membre
- Inscription : 01-06-2012
- Messages : 8
Re : programmation scilab
Merci pour ton aide, j'ai essayé de corriger quelques détails mais en vain, voici mon programme final:
function [v]=syracuse(n,K)
v=n
for k=1:K
reste=modulo(v,2)
if (reste =0) then v=v/2
else v=3*v+1
end; disp [v];
endfunction
Avec ces instructions, scilab répond lorsque je tape syracuse(5,5) ou [v] qu'ils ne sont pas définis.
Hors ligne
#6 02-06-2012 10:06:15
- yoshi
- Modo Ferox
- Inscription : 20-11-2005
- Messages : 17 385
Re : programmation scilab
Bonsoir,
Bon, j'ai quand même été obligé d'installer Scilab.
Ça fonctionne, mais avec quelque chose d'étrange pour moi...
Pour que le programme affiche les 20 valeurs de k = 1 à k=20, à la fin je suis obligé de demander à poursuivre le calcul, une fois, puis après à l'arrêter.
1. Test d'égalité. Ce n'est pas : if reste =0 mais if reste == 0
2. Une série de tests conditionnels se termine par end. Le end manquait.
3. Une boucle for se termine par end. Le end manquait.
4. Je n'aurais pas dû écrire [v]=.... c'est un peu spécial : [v] est un "vecteur" si j'ai bien compris.
5. Il y a bien une indentation à respecter avec Scilab aussi. L'éditeur s'en charge.
Voilà :
v=n
for k=1:K
reste=modulo(v,2)
if reste==0 then v=v/2
else v=3*v+1
end
disp (v)
end
endfunction
suite(89,20)
J'ai enregistré ce code sous le nom de syracuse.sci (n'importe quel autre nom conviendrait).
Dans la console je fais Fichier --> Exécuter et je sélectionne syracuse.sci
L'écran se présente ainsi :
___________________________________
scilab-5.3.3
Consortium Scilab (DIGITEO)
Copyright (c) 1989 - 2011 (INRIA)
Copyright (c) 1989 - 2007 (ENPC)
___________________________________Initialisation :
loading initial environment268.
134.
67.
202.
101.
304.
152.
76.
38.
19.
[Continuer à afficher? n (no) pour arrêter, autre touche pour continuer]
J'appuie sur une touche, il continue et me donne :
58.
29.
88.
44.
22.
11.
34.
17.
52.
26.
ans =
[Continuer à afficher? n (no) pour arrêter, autre touche pour continuer]
Là je réappuie :
26.
Exécution terminée.
Bizarre ! Pourquoi seulement 10 résultats à la fois ?
Je serais curieux de savoir ce qui se passe...
@+
En ligne
#7 02-06-2012 12:15:10
- amady89
- Membre
- Inscription : 01-06-2012
- Messages : 8
Re : programmation scilab
Effectivement j'ai le même problème avec ces instructions mais j'ai réussi à résoudre le problème en programmant de cette manière:
function V = Suite(n,K)
V = [n];
TermeActuel = n;
for i = 1:K-1
if ( modulo(TermeActuel,2) == 0 ) then
TermeActuel = TermeActuel / 2;
else TermeActuel = 3*TermeActuel + 1;
end
V = [V,TermeActuel];
end
endfunction;
Le problème est que ensuite je dois trouver pour K=1000 ou K est le nombre de termes de la suite et pour n=57,89,1253 et 8571 la valeur T(n) qui est la plus petite valeur de k si elle existe pour laquelle u(k)=1 et si elle n'existe pas T(n)=-1
j'ai construit cette fonction qui ne marche pas:
function k=T(n)
a=Suite(n,1000)(1);
k=1;
for k=1:K
if (a >1) then k=k+1; else a=-1;
a=k;
end;
endfunction;
Hors ligne
#9 02-06-2012 14:15:35
- yoshi
- Modo Ferox
- Inscription : 20-11-2005
- Messages : 17 385
Re : programmation scilab
Bonjour,
Plusieurs remarques.
D'abord, le problème de l'affichage est lié à la taille de la fenêtre de console : il suffit d'utiliser la taille maximale et l'affichage ne pose plus de problèmes... Pas besoin de compliquer, ce que j'ai fait marche très bien.
Tu as une boucle contrôlée par l'indice k et dans ta boucle tu utilises un compteur lui aussi nommé k : ça ne pas.
Si tu veux absolument un compteur appelle le donc h (ou autrement) et remplace au début ton k=1; par h=1;
Ensuite je me demande ce que tu fais. On cherche la valeur k minimum entre n=57,89,1253 et 8571.
Ces valeurs sont respectivement
32, 30, 132, 171
Le minimum cherché est donc k=30 pour n=89
Je l'ai fait en Python : ça marche.
Avec Scilab, je butte sur extraire un élément d'une liste à chaque itération d'une boucle : j'ai un message d'erreur. Je cherche.
@+
En ligne
#10 02-06-2012 15:41:56
- yoshi
- Modo Ferox
- Inscription : 20-11-2005
- Messages : 17 385
Re : programmation scilab
Re,
Bon, c'est fait
mini=K+1
for v =list(57,89,1253,8571)
vd=v
for k=1:K
reste=modulo(v,2)
if reste==0 then v=v/2
else v=3*v+1
end
if v==1 then ...
mini1=mini
mini=min(mini,k)
if mini<mini1 then ...
vi=vd
end
end
end
end
printf("k mini=%i, n=%i",mini,vi)
endfunction
val_min(1000)
qui donne en sortie :
___________________________________________
scilab-5.3.3Consortium Scilab (DIGITEO)
Copyright (c) 1989-2011 (INRIA)
Copyright (c) 1989-2007 (ENPC)
___________________________________________
Initialisation :
loading initial environment
k mini=30, n=89
Exécution terminée.
Je commence par initialiser mon minimum à K+1 pour être sûr que le minimum de départ mini sera bien récupéré dès la première itération.
J'utilise deux boucles imbriquées :
* La première contrôlée par v sert à donner à v les valeurs successives de la liste 57,89,1253,8571
J'ai besoin de stocker chacune des valeurs v de départ (v va changer à chaque k) : vd = v
* Puis pour chacune des valeurs de v je vais tester - en théorie - 1000 valeurs de k. En fait, je vais casser (break) la boucle, en sortir dès que v==1 puisqu'on cherche un minimum.
Le début de cette 2e boucle est sans surprise jusqu'au premier en.
Là j'ai besoin de vérifier si v==1 pour sortir de la boucle.
Si c'est le cas, avant de sortir, je stocke le minimum en cours dans mini1 et je cherche le minimum du k en cours et du mini en cours.
Si le nouveau minimum est inférieur à l'ancien alors je stocke la valeur correspondante de v de départ (celle de vd).
S'ensuit une succession de end fermant les if et les boucles for.
J'affiche ensuite sur la même ligne k min et n dont je précise que ce sont des entiers (C'est nécessaire : affichage dit "formatté". Si je ne le fais pas : message d'erreur !)
En ligne
#11 02-06-2012 16:57:02
- amady89
- Membre
- Inscription : 01-06-2012
- Messages : 8
Re : programmation scilab
En fait il faut calculer pour chaque n le 1er terme u(k) pour lequel u(k)=1 et non le minimum pour tous les n parmi (57 89 1253 8571)
il faut donc trouver un programme qui donne k=30 pour n=89, k=32 pour n=57 k=132 pour n=1253 et k= 171 pour n=8571
Hors ligne
#12 02-06-2012 18:43:16
- yoshi
- Modo Ferox
- Inscription : 20-11-2005
- Messages : 17 385
Re : programmation scilab
Salut,
Dit comme ça, c'est clair !
Bon, bin, c'est bien plus simple...
for v =list(57,89,1253,8571)
vd=v
for k=1:K
reste=modulo(v,2)
if reste==0 then v=v/2
else v=3*v+1
end
if v==1 then ...
printf("Pour n = %i, k mini = %i",vd,k)
disp('')
break
end
end
end
endfunction
val_min(1000)
Ce qui donne
___________________________________________
scilab-5.3.3Consortium Scilab (DIGITEO)
Copyright (c) 1989-2011 (INRIA)
Copyright (c) 1989-2007 (ENPC)
___________________________________________
Initialisation :
loading initial environment
Pour n = 57, k mini = 32
Pour n = 89, k mini = 30
Pour n = 1253, k mini = 132
Pour n = 8571, k mini = 171
Exécution terminée.
@+
En ligne
#13 02-06-2012 19:02:50
- yoshi
- Modo Ferox
- Inscription : 20-11-2005
- Messages : 17 385
Re : programmation scilab
RE,
Affichage plus "propre" :
for v =list(57,89,1253,8571)
vd=v
for k=1:K
reste=modulo(v,2)
if reste==0 then v=v/2
else v=3*v+1
end
if v==1 then ...
printf("Pour n = % i, la première valeur de k est %i \n", vd,k)
break
end
end
end
endfunction
val_min(1000)
Voilà le travail :
___________________________________________
scilab-5.3.3Consortium Scilab (DIGITEO)
Copyright (c) 1989-2011 (INRIA)
Copyright (c) 1989-2007 (ENPC)
___________________________________________
Initialisation :
loading initial environment
Pour n = 57, la première valeur de k est 32
Pour n = 89, la première valeur de k est 30
Pour n = 1253, la première valeur de k est 132
Pour n = 8571, la première valeur de k est 171
@+
En ligne
#14 02-06-2012 19:05:39
- amady89
- Membre
- Inscription : 01-06-2012
- Messages : 8
Re : programmation scilab
Oui effectivement, désolé pour le manque de clarté...
Je dois maintenant calculer le max toujours pour K=1000 et n=57, n=89, n=1253 et n=8571
Je ne vois pas trop pourquoi avec cet algorithme j'ai le max mais dans une liste avec des 0 avant:
function M=M(n)
A=Suite(n,1000)
M(n)=max(A)
endfunction
Hors ligne
#15 02-06-2012 20:09:20
- yoshi
- Modo Ferox
- Inscription : 20-11-2005
- Messages : 17 385
Re : programmation scilab
Bonsoir,
Je dois maintenant calculer le max
Le max ? le max de quoi ?
A partir du moment du moment où tu es tombée sur 1, la suite est 4 2 1 4 2 1 4 2 1 4 2 1...
Peut-être veux-tu dire "l'altitude" maxi ? c'est à dire la plus grande valeur atteinte par v ?
Soit :
196 pour v0 = 57
304 pour v0 = 89
9232 pour v0 =1253
43396 pour v0 = 8571
@+
(peut-être demain)
En ligne
Pages : 1







