Page 1 sur 2
trouver le nombre le plus proche parmi plusieurs
Publié : mar. 14/nov./2017 16:16
par blendman
salut
Voilà un exemple de code :
Code : Tout sélectionner
; notre tableau de couleur
Global Dim valeur(4)
valeur(0) = 8429776
valeur(1) = 7377072
valeur(2) = 7377088
valeur(3) = 6324384
valeur(4) = 5324384
Procedure FindNearValue(number.i)
For i= 0 To ArraySize(valeur())-1
u = number/valeur(i)
v = number/valeur(i+1)
If u = 0 And v=1
Debug "le nombre : "+number+" est entre "+valeur(i)+" et "+valeur(i+1)
a = Abs(number-valeur(i))
b = Abs(number-valeur(i+1))
j = i
d = a
If a > b
j = i+1
d = b
EndIf
Debug "le nombre : "+number+" est le plus proche de "+valeur(j)+" (à "+d+" près)"
Break
EndIf
Next
EndProcedure
; je vais chercher les couleurs les plus proche de ces deux-ci
FindNearValue(7107020)
FindNearValue(6207020)
ça vous semble ok comme technique ?
Connaissez-vous une autre technique plus rapide ou mieux pour trouver l'élément le plus proche de notre nombre (dans un tableau de nombre) ?
En fait, c'est pour remplacer des couleurs proches entre elles par une autre couleur indexée

.
Re: trouver le nombre le plus proche parmi plusieurs
Publié : mar. 14/nov./2017 17:17
par MLD
@ blendman
Après réflexion J'ai pas mieux
Re: trouver le nombre le plus proche parmi plusieurs
Publié : mar. 14/nov./2017 17:32
par falsam
Il y a mieux car je pense que le code de Blend est comment dire ...... faux
debug a écrit :le nombre : 7107020 est entre 7377088 et 6324384
J'aurais dit

le nombre : 7107020 est entre
7377072 et 6324384
Re: trouver le nombre le plus proche parmi plusieurs
Publié : mar. 14/nov./2017 17:48
par falsam
Normalement c'est juste.
Code : Tout sélectionner
; notre tableau de couleur
Global Dim valeur(4)
valeur(0) = 8429776
valeur(1) = 7377072
valeur(2) = 7377088
valeur(3) = 6324384
valeur(4) = 5324384
SortArray(valeur(), #PB_Sort_Ascending)
Procedure FindNearValue(number.i)
Protected p0 = -1, p1, i0, i1
For i = 0 To ArraySize(valeur())
If number >= valeur(i) And p0 = -1
p0 = valeur(i)
i0 = Number - valeur(i)
EndIf
If number <= valeur(i) And p0 <> -1
p1 = valeur(i)
i1 = Valeur(i) - Number
EndIf
If p0 * p1 > 0
Debug "le nombre : "+number+" est entre " + p0 +" et " + p1
If i0 > i1
Swap p0, p1
Swap i0, i1
EndIf
Debug "le nombre : "+number+" est plus proche de " + p0 + " (à "+ i0 + " près)"
Break
EndIf
Next
EndProcedure
; je vais chercher les couleurs les plus proche de ces deux-ci
FindNearValue(7107020)
FindNearValue(6207020)

Ton code fonctionne aussi si tu inseres un
SortArray(valeur(), #PB_Sort_Descending)
Re: trouver le nombre le plus proche parmi plusieurs
Publié : mar. 14/nov./2017 18:03
par MLD
@blendman
j'ai réfléchi un peu plus et j'ai trouvé ceci.
Code : Tout sélectionner
Global Dim valeur(4)
valeur(0) = 8429776
valeur(1) = 7377072
valeur(2) = 7377088
valeur(3) = 6324384
valeur(4) = 5324384
Procedure FindNearValue(number.D)
R.D = 100
For x = 0 To 4
Z.D = number/valeur(x)
If Z < 1
ZZ.D = 1/ Z
Else
ZZ.D = Z
EndIf
If ZZ.D < R
R = ZZ.D: T = x
EndIf
Next
Debug "la valeur la plus proche est " + StrD(valeur(T))
EndProcedure
; je vais chercher les couleurs les plus proche de ces deux-ci
FindNearValue(7107020)
FindNearValue(6207020)
Je ne sais pas si c'est ce que tu cherche
Re: trouver le nombre le plus proche parmi plusieurs
Publié : mar. 14/nov./2017 18:12
par blendman
Merci pour vos réponses.
@falsam :
ton code ne marche pas du tout, tu ne l'as pas testé lol

.
Non, seulement il plante, mais il ne donne pas la bonne valeur
@MLD : le problème avec ton code c'est qu'il n'y a pas de break dans la boucle

.
On ne sait pas quand on doit s'arrêter. (si mon tableau contient 500 couleurs et que je fais l'opération sur chaque pixel d'une image, ça va être super long ^^
Re: trouver le nombre le plus proche parmi plusieurs
Publié : mar. 14/nov./2017 18:20
par celtic88
Code : Tout sélectionner
; notre tableau de couleur
Global Dim valeur(4)
valeur(0) = 8429776
valeur(1) = 7377072
valeur(2) = 7377088
valeur(3) = 6324384
valeur(4) = 5324384
Procedure FindNearValue(number.i)
SortArray(valeur(),#PB_Sort_Ascending)
For i= 0 To ArraySize(valeur())-1
If number < valeur(i)
Debug "le nombre : "+number+" est entre "+valeur(i)+" et "+valeur(i-1)
Break
EndIf
Next
EndProcedure
; je vais chercher les couleurs les plus proche de ces deux-ci
FindNearValue(7107020)
FindNearValue(6207020)
Re: trouver le nombre le plus proche parmi plusieurs
Publié : mar. 14/nov./2017 18:25
par falsam
blendman a écrit :@falsam :
ton code ne marche pas du tout, tu ne l'as pas testé lol .
Non, seulement il plante, mais il ne donne pas la bonne valeur
je sais bien que je suis dans un mauvais bad trip (merci Ar-s ^-^) mais je pense que tu as trop fumé de pixels Blendman.
Monsieur Blendman est prié de reprendre son tableau
Code : Tout sélectionner
valeur(0) = 8429776
valeur(1) = 7377072
valeur(2) = 7377088
valeur(3) = 6324384
valeur(4) = 5324384
Si avec ton code, on cherche la valeur 7107020, le debug répond
le nombre : 7107020 est entre 7377088 et 6324384
Regarde bien ton tableau et dis moi si rien ne te gène ?
7377072 ne te semble pas plus proche de 7107020 ? Donc ton résultat est faux.
Avant de dire que mon code est faux, met toi une paire de lunette sur les yeux Blendman.
@Celtic : Hello. Tu n'as pas l'impression que ton code est le même que celui que je propose ? En moins bien car tu as tu as supprimé la notion " ...est le plus proche de ...."
@MLD : le problème avec ton code c'est qu'il n'y a pas de break dans la boucle
Il fonctionne trés bien son code et en plus il donne le même résultat que celui que je propose.
Re: trouver le nombre le plus proche parmi plusieurs
Publié : mar. 14/nov./2017 18:52
par MLD
@blenman
un mélange du code a celtic et le mien
Code : Tout sélectionner
; notre tableau de couleur
Global Dim valeur(4)
valeur(0) = 8429776
valeur(1) = 7377072
valeur(2) = 7377088
valeur(3) = 6324384
valeur(4) = 5324384
Procedure FindNearValue(number.i)
SortArray(valeur(),#PB_Sort_Ascending)
For i= 0 To ArraySize(valeur())-1
If number < valeur(i)
Debug "le nombre : "+number+" est entre "+valeur(i)+" et "+valeur(i-1)
Debug i
Break
EndIf
Next
R.D = 100
For x = i-1 To i
Z.D = number/valeur(x)
If Z < 1
ZZ.D = 1/ Z
Else
ZZ.D = Z
EndIf
If ZZ.D < R
R = ZZ.D: T = x
EndIf
Next
Debug "la valeur la plus proche est " + StrD(valeur(T))
Re: trouver le nombre le plus proche parmi plusieurs
Publié : mar. 14/nov./2017 19:27
par blendman
En ajoutant ça SortArray(valeur(), #PB_Sort_Ascending ) , mon code marche (j'avais juste ajouté une valeur que j'ai oublié de trier dans l'exemple), puis que j'obtiens les bonnes valeurs (tu l'as dit toi-même).
Mais ce n'est pas le problème.
je veux bien tester d'autres codes, mais il faut qu'ils fonctionnent, sinon, ben, je ne peux pas les tester

.
J'ai testé ton code, mais ça plante à la ligne :
Code : Tout sélectionner
Debug "le nombre : "+number+" est entre "+valeur(i-1) +" et " + valeur(i)
Car si i= 0 -> valeur(i-1) est en dehors de l'index du tableau

(l'index -1 d'un tableau n'existant pas).
je ne sais pas ce que tu souhaites faire exactement, donc, je ne sais pas comment modifier pour que ça marche

Re: trouver le nombre le plus proche parmi plusieurs
Publié : mer. 15/nov./2017 1:19
par falsam
J'ai revue ma copie précédente
http://www.purebasic.fr/french/viewtopi ... 35#p196835
J'aime bien cette procédure FindNearValue() et j'ai rédigé le code autrement.
Code : Tout sélectionner
Procedure FindNearValue(Array ThisArray(1), number.i)
Protected p0 = #PB_Ignore, p1, i0, i1
SortArray(ThisArray(), #PB_Sort_Ascending)
For i = 0 To ArraySize(ThisArray())
If number >= ThisArray(i) And p0 = #PB_Ignore
p0 = ThisArray(i) : i0 = Number - ThisArray(i)
EndIf
If number <= ThisArray(i) And p0 <> #PB_Ignore
p1 = ThisArray(i) : i1 = ThisArray(i) - Number
EndIf
If p0 * p1 > 0
If i0 > i1
Swap p0, p1
EndIf
Break
EndIf
Next
ProcedureReturn p0
EndProcedure
;// Zone de teste
EnableExplicit
; notre tableau de couleur
Global Dim valeur(4)
valeur(0) = 8429776
valeur(1) = 7377072
valeur(2) = 7377088
valeur(3) = 6324384
valeur(4) = 5324384
; je vais chercher les couleurs les plus proche de ces deux-ci
Debug "7107020 est plus proche de " + FindNearValue(Valeur(), 7107020)
Debug "6207020 est plus proche de " + FindNearValue(Valeur(), 6207020)
Re: trouver le nombre le plus proche parmi plusieurs
Publié : mer. 15/nov./2017 8:25
par Zorro
blendman a écrit :
En fait, c'est pour remplacer des couleurs proches entre elles par une autre couleur indexée

.
Pour mon code "Pure_reductor" que j'avais posté ici :
http://www.purebasic.fr/french/viewtopi ... 59#p196859
voici ce que je faisais ,pour determiner la couleur la plus proche
j'utilise en fait une fonction qui calcul la Distance entre deux points (entre deux valeurs)
en fait c'est le meme principe
et c'est tres court !
appel :
Valeur de distance=
distance_couleur(
Couleur1,
couleur2)
ça retourne la valeur qui sépare ces 2 couleurs, plus la valeur est petite, plus proche tu te trouve
voici 3 exemples d'utilisation :
Code : Tout sélectionner
Declare distance_couleur(couleur1,couleur2)
debug "couleur peu distante : "+ str(distance_couleur(rgb(255,0,2),rgb(255,0,5))) ;
debug "couleur identique :"+str( distance_couleur(rgb(255,0,2),rgb(255,0,2)) );
debug " couleur tres eloignée :"+str(distance_couleur(rgb(255,255,255),rgb(0,0,0))) ;
Procedure distance_couleur(couleur1,couleur2)
; by Dobro
rf.c=red(couleur1) :vf.c=green(couleur1): bf.c=blue(couleur1)
r.c=red(couleur2) :v.c=green(couleur2): b.c=blue(couleur2)
distance=sqr(pow(rf-r.c,2)+ pow(vf-v.c,2)+pow(bf-b.c,2)) ; calcul de la distqnce qui separe la couleur de l'image avec la couleur de la palette
ProcedureReturn distance
Endprocedure
;Epb
Re: trouver le nombre le plus proche parmi plusieurs
Publié : mer. 15/nov./2017 9:53
par MLD
@blendman
je n'est pas plus rapide
Code : Tout sélectionner
; notre tableau de couleur
Global Dim valeur(4)
valeur(0) = 8429776
valeur(1) = 7377072
valeur(2) = 7377088
valeur(3) = 6324384
valeur(4) = 5324384
SortArray(valeur(),#PB_Sort_Ascending)
Procedure FindNearValue(number.i)
For i= 0 To ArraySize(valeur())-1
If number < valeur(i)
Debug "le nombre : "+number+" est entre "+valeur(i)+" et "+valeur(i-1)
Break
EndIf
Next
Zh.i = valeur(i) - number
Zb.i = number - valeur(i-1)
If Zh < Zb
result.i = valeur(i)
Else
result.i = valeur(i-1)
EndIf
Debug "la valeur la plus proche est " + StrD(result)
EndProcedure
; je vais chercher les couleurs les plus proche de ces deux-ci
FindNearValue(7107020)
FindNearValue(6207020)
FindNearValue(8429777)
Re: trouver le nombre le plus proche parmi plusieurs
Publié : mer. 15/nov./2017 10:07
par Micoute
Merci à tous pour le partage.
Re: trouver le nombre le plus proche parmi plusieurs
Publié : mer. 15/nov./2017 10:33
par MLD
@Blendman
Comme ceci le tableau ne plante plus
Code : Tout sélectionner
Global Dim valeur(4)
valeur(0) = 8429776
valeur(1) = 7377072
valeur(2) = 7377088
valeur(3) = 6324384
valeur(4) = 5324384
SortArray(valeur(),#PB_Sort_Ascending)
Procedure FindNearValue(number.i)
For i= 0 To ArraySize(valeur())-1
If number.i < valeur(0):Zb.i = 0:Break:EndIf
If number < valeur(i)
Debug "le nombre : "+number+" est entre "+valeur(i)+" et "+valeur(i-1)
Break
EndIf
Next
If Zb.I <> 0
Zh.i = valeur(i) - number
Zb.i = number - valeur(i-1)
If Zh < Zb
result.i = valeur(i)
Else
result.i = valeur(i-1)
EndIf
Else
result.i = valeur(0)
EndIf
Debug "la valeur la plus proche est " + StrD(result)
EndProcedure
; je vais chercher les couleurs les plus proche de ces deux-ci
FindNearValue(7107020)
FindNearValue(6207020)
FindNearValue(5324380)