trouver le nombre le plus proche parmi plusieurs

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

trouver le nombre le plus proche parmi plusieurs

Message 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 :).
Avatar de l’utilisateur
MLD
Messages : 1105
Inscription : jeu. 05/févr./2009 17:58
Localisation : Bretagne

Re: trouver le nombre le plus proche parmi plusieurs

Message par MLD »

@ blendman
Après réflexion J'ai pas mieux
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: trouver le nombre le plus proche parmi plusieurs

Message 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

:idea: le nombre : 7107020 est entre 7377072 et 6324384
Configuration : Windows 11 Famille 64-bit - PB 6.03 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: trouver le nombre le plus proche parmi plusieurs

Message 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)
:idea: Ton code fonctionne aussi si tu inseres un SortArray(valeur(), #PB_Sort_Descending)
Configuration : Windows 11 Famille 64-bit - PB 6.03 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
MLD
Messages : 1105
Inscription : jeu. 05/févr./2009 17:58
Localisation : Bretagne

Re: trouver le nombre le plus proche parmi plusieurs

Message 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
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Re: trouver le nombre le plus proche parmi plusieurs

Message 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 ^^
Avatar de l’utilisateur
celtic88
Messages : 309
Inscription : sam. 12/sept./2015 14:31
Localisation : Alger

Re: trouver le nombre le plus proche parmi plusieurs

Message par celtic88 »

:wink:

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)
.....i Love Pb :)
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: trouver le nombre le plus proche parmi plusieurs

Message 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.
Configuration : Windows 11 Famille 64-bit - PB 6.03 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
MLD
Messages : 1105
Inscription : jeu. 05/févr./2009 17:58
Localisation : Bretagne

Re: trouver le nombre le plus proche parmi plusieurs

Message 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)) 
    
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Re: trouver le nombre le plus proche parmi plusieurs

Message 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 :D.

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 ;)
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: trouver le nombre le plus proche parmi plusieurs

Message 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)
Configuration : Windows 11 Famille 64-bit - PB 6.03 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
Zorro
Messages : 2185
Inscription : mar. 31/mai/2016 9:06

Re: trouver le nombre le plus proche parmi plusieurs

Message 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
Dernière modification par Zorro le mer. 15/nov./2017 11:56, modifié 1 fois.
Image
Image
Site: http://michel.dobro.free.fr/
Devise :"dis moi ce dont tu as besoin, je t'expliquerai comment t'en passer"
Avatar de l’utilisateur
MLD
Messages : 1105
Inscription : jeu. 05/févr./2009 17:58
Localisation : Bretagne

Re: trouver le nombre le plus proche parmi plusieurs

Message 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)
Avatar de l’utilisateur
Micoute
Messages : 2522
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

Re: trouver le nombre le plus proche parmi plusieurs

Message par Micoute »

Merci à tous pour le partage.
Microsoft Windows 10 Famille 64 bits : Carte mère : ASRock 970 Extreme3 R2.0 : Carte Graphique NVIDIA GeForce RTX 3080 : Processeur AMD FX 6300 6 cœurs 12 threads 3,50 GHz PB 5.73 PB 6.00 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
Avatar de l’utilisateur
MLD
Messages : 1105
Inscription : jeu. 05/févr./2009 17:58
Localisation : Bretagne

Re: trouver le nombre le plus proche parmi plusieurs

Message 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)
Répondre