Page 1 sur 4

Lisseur de nombres

Publié : dim. 11/juin/2017 16:35
par Shadow
Salut,

J’essaie de faire un lisseur de nombres mais j'y arrive pas bien, j'ai surement pas la bonne méthode...
Je prends chaque nombres dans une liste de nombres, un à un et je les compares.

Je prends le nombre 1, je le compare au deuxième, et si la différence est <= la référence
alors je le prends puis je trie la liste du plus grand au plus petit et je continue, sinon je stop tous.

De cette façon le nombre suivant s'il est <= la référence, je le prends et ainsi de suite.
Méthode qui fonctionne pas...

Exemple: "240.238.242.238.240.242.239.241.243.237.244.236.245"

Ici je veux lisser les nombres entres donc 238 et 242.
Les nombres qui m’intéresses sont donc: 240.238.242.238.240.242.239.241 car il ne dépasse pas 2 de + ou de -que 240.
Ensuite je fais la moyenne de tous ces nombre et le les remplace tous par la moyenne (Lissage).

Le programme dois s'adapter par apport aux nombres qu'il va prendre.
Les nombres doivent être pris à la file indienne.

Exemple avec: "237.240.238.242.238.240.242.239.241.243.237.244.236.245"

Ici ya que: 237.240.238 qui nous intéresse car entre 237 et 240 ya 3.
Si je prends: 237.240.238.242.238.240.242.239.241.
Entre 237 et 242 ya quand même 5 !

Je ne sais pas si je suis bien clair dans mes propos :?
Faut surement comparer le nombre le plus petit pris avec le nombre le plus grand et la différence dois pas dépassé la référence.
Référence que ont choisie justement avant.

J'vé creuser encore plus.
Si vous avez un tuyau ça peut servir :)

Re: Lisseur de nombres

Publié : dim. 11/juin/2017 16:46
par Ar-S
là j'ai buggué

Code : Tout sélectionner

Ensuite je fais la moyenne de tous ces nombre et le les remplace tous par la moyenne (Lissage).
Le programme dois s'adapter par apport aux nombres qu'il va prendre.
Déjà tu les mets tous dans une liste chainée, tu les sorts du plus petits au plus grand via SortList()
Ensuite tu vérifies chaque élément en vérifiant qu'il n'est pas +petit ou + grand que X ou Y. S'il ne correspond pas tu le vires de la liste.
Je ne propose pas de code, mais sur le principe ça n'a pas l'air sorcier..
Commandes NewList, sortlist, if, endif, and, DeleteElement

Re: Lisseur de nombres

Publié : dim. 11/juin/2017 16:50
par falsam
Tu m'a devancé Ar-s. Mais il faut avouer que
je fais la moyenne de tous ces nombre et le les remplace tous par la moyenne
ça peut interpeller :mrgreen:

Re: Lisseur de nombres

Publié : dim. 11/juin/2017 17:43
par Shadow
Mouais bon vous m'avez pas compris, pas grave :)

Code : Tout sélectionner

Procedure.s LisseurDeValeurs(Valeur.s, EcartMax.i)
  
  NewList ListeNombresEntree.i()
  NewList ListeNombresSortie.i()
  NewList ListeNombresSortieLisser.i()
  
  For Index.i = 1 To CountString(Valeur.s, ".") + 1
    
    AjouterNombreListe.b = #False
    NombreExtrait.i = Val(StringField(Valeur.s, Index.i, "."))
    
    If ListSize(ListeNombresEntree.i()) > 0
      FirstElement(ListeNombresEntree.i())
      PremierNombreListe.i = ListeNombresEntree.i()
      
    Else
      AddElement(ListeNombresEntree.i())
      ListeNombresEntree.i() = NombreExtrait.i
      
      AddElement(ListeNombresSortie.i())
      ListeNombresSortie.i() = NombreExtrait.i
      
      Continue
      
    EndIf
    
    If PremierNombreListe.i > NombreExtrait.i
      
      If PremierNombreListe.i - NombreExtrait.i <= EcartMax.i
        AjouterNombreListe.b = #True
      Else
        Break
        
      EndIf
      
    ElseIf PremierNombreListe.i < NombreExtrait.i
      
      If NombreExtrait.i - PremierNombreListe.i <= EcartMax.i
        AjouterNombreListe.b = #True
      Else
        Break
        
      EndIf
      
    ElseIf PremierNombreListe.i = NombreExtrait.i
      AjouterNombreListe.b = #True
      
    EndIf
    
    If AjouterNombreListe.b = #True
      AddElement(ListeNombresEntree.i())
      ListeNombresEntree.i() = NombreExtrait.i
      SortList(ListeNombresEntree.i(), #PB_Sort_Descending)
      
      AddElement(ListeNombresSortie.i())
      ListeNombresSortie.i() = NombreExtrait.i
      
    EndIf
    
  Next
  
  ForEach ListeNombresSortie.i()
    TotaleListeNombres.i + ListeNombresSortie.i()
    Sortie.s + ListeNombresSortie.i() + "."
  Next
  
  TailleListeNombre.i = ListSize(ListeNombresSortie.i())
  MoyenneListeNombres.i = TotaleListeNombres.i / TailleListeNombre.i
  
  Sortie.s = InsertString(Sortie.s, Str(TailleListeNombre.i) + "-", 1)
  
  Sortie.s = ReverseString(Sortie.s)
  Sortie.s = Mid(Sortie.s, 2)
  Sortie.s = ReverseString(Sortie.s)
  Sortie.s + "-"
  
  ForEach ListeNombresSortie.i()
    Sortie.s + Str(MoyenneListeNombres.i) + "."
  Next
  
  Sortie.s = ReverseString(Sortie.s)
  Sortie.s = Mid(Sortie.s, 2)
  Sortie.s = ReverseString(Sortie.s)
  
  ProcedureReturn Sortie.s
  
EndProcedure


ValeurTest.s = "237.240.238.242.238.240.242.239.241.243.244.236.245"
EcartMaxTest.i = 3

Debug LisseurDeValeurs(ValeurTest.s, EcartMaxTest.i)
C'est pas encore ça.

Re: Lisseur de nombres

Publié : lun. 12/juin/2017 9:23
par TazNormand
Comme ça peut être ?

Code : Tout sélectionner

ValeurTest.s = "237.240.238.242.238.240.242.239.241.243.244.236.245"
EcartMaxTest.i = 3
Somme.i=0
Moyen.i=0
valeur.i=0

NewList inList.i()
NewList outList.i()

; Créer notre liste de nombres
nbElem=CountString(ValeurTest,".")+1
For i.i=1 To nbElem
  AddElement(inList())
  valeur=Val(StringField(ValeurTest,i,"."))
  inList()=valeur
  
  ; Additionner les différentes valeurs de notre "suite"
  Somme+valeur
Next i

; trier notre liste
SortList(inList(),#PB_Sort_Ascending)

;  trouver le nombre "moyen" parmi tous ceux de la liste
moyen=somme/nbelem
Debug "Moyen " + moyen

; Copier la liste
CopyList(inlist(),outList())

; éjecter de notre liste tous les nombres qui ne sont pas compris dans la fourchette (moyen - écart) et (moyen + écart)
valMin.i=moyen-EcartMaxTest
valMax.i=moyen+EcartMaxTest

ForEach outList()
  If outList() < valMin Or outList()>valMax
    DeleteElement(outList())
    EndIf
  Next
  
; Afficher la liste après traitement
ForEach outList()
  Debug outList()  
Next

Re: Lisseur de nombres

Publié : lun. 12/juin/2017 11:35
par microdevweb

Re: Lisseur de nombres

Publié : lun. 12/juin/2017 14:03
par Shadow
TazNormand
Merci Taz.
En faite se que je voudrait, c'est lisser les nombres suivant une condition, ici différence, ok vous 'lavez bien compris...
Mais sans changer les nombre de sortie de place !

Imagine pour faire simple, du sable ou chaque bosse représente un nombre, plus la bosse est grand et plus le nombre est grand.
Il faut si je puis dire, aplanir les bosses qui son adjacente et très proche de notre bosse à nous.

Bon, j'vé tenté une autres approche...
Je veux m'en servir pour les images pour "lisser" les valeurs des pixels (RGBA)...

Pour lisser les valeur se rapprochant le plus de la notre:

Imaginons:

114, 116, 113, 112, 115, 113, 118, 120, 119, 122, 121, 134, 133, 135, 136...

Je ne veux pas lisser toutes la ligne d'un coups car ça ferais trop de pertes et je dois rester au plus proche des nombres.
Ici donc ça ferais un truc du genre:

114, 116, 113, 112, 115, 113 -> 114, 114, 114, 114, 114, 114, 114
118, 120, 119, 122, 121 -> 120, 120, 120, 120, 120
134, 133, 135, 136 -> 134, 134, 134, 134

De cette façon j’obtiens ceci: -> 114, 114, 114, 114, 114, 114, 114, 120, 120, 120, 120, 120, 134, 134, 134, 134

Évidement si les valeur son pas dans la bonne fourchette on zap, ex: 125, 130, 115, 145, 178, 100, 133, 130, 134, 136, 131, 135, 132, 130, 133, 130, 134, 131

125, 130, 115, 145, 178, 100-> Pas de changement, trop de différence, le lissage serais trop brutale. (Paramétrable grâce à différence)

133, 130, 134 -> 132, 132, 132
136, 131, 135 -> Ont zap
132, 130, 133, 130 -> 131, 131, 131, 131
134, 131 -> 132, 132

De toute évidence, je sais se que je veux mais c'est un peut confus, il faut que je cherche par moi même
Je vais bien y arrivé, ce dois pas être si dur que ça aller courage.

Re: Lisseur de nombres

Publié : lun. 12/juin/2017 14:52
par Ar-S
Avec le code de taz comme exemple je ne vois pas comment tu ne pourrais pas arriver à faire ça. Allez un petit effort.

Re: Lisseur de nombres

Publié : lun. 12/juin/2017 15:04
par Micoute
Mais pourquoi ne prends-tu pas tes nombres par 3, tu fais la somme qui tu divises par 3, etc...
Evidemment, tu calcules l'intervalle pour savoir s'il est dans la fourchette.

Re: Lisseur de nombres

Publié : lun. 12/juin/2017 15:58
par TazNormand
Comme te l'a suggéré Micoute, prends tes nombres par intervalles, et tu fais la moyenne de cet intervalle. Algo simple :
Liste = "237.240.238.242.238.240.242.239.241.243.237.244.236.245"

1° Tu tries ta liste par ordre croissant, ce qui donne :
===> Liste = "236.237.237.238.238.239.240.240.241.242.242.243.244"

2° tu travailles par groupe de 3 par exemple et tu fais la moyenne de ce groupe :
===> (236.237.237) ==> Moyenne : (236+237+237)/3 = 236.6667 soit 237 donc en arrondissant au dessus

3° Tu passe au groupe de 3 (ou moins) suivants
===> (238.238.239), (240.240.241), (242.242.243) et (244) étant seul, pas de moyenne donc

Voilà

Re: Lisseur de nombres

Publié : lun. 12/juin/2017 17:03
par SPH
Il faudrait savoir a quoi ca va servir pour mieux proposer un code optimisé 8)

Re: Lisseur de nombres

Publié : lun. 12/juin/2017 17:05
par Shadow
Ok mais c'est pas par 3 que je dois prendre les nombre, je dois justement déterminer le nombre de nombre que je dois prendre !
Je cherche.
Merci.

Édit: en changeant et en triant la liste du plus petit au plus grand, ça semble fonctionné ! -> #PB_Sort_Ascending
Donc ça donne à présent:

Code : Tout sélectionner

Procedure.s LisseurDeValeurs(Valeur.s, EcartMax.i)
  
  NewList ListeNombresEntree.i()
  NewList ListeNombresSortie.i()
  NewList ListeNombresSortieLisser.i()
  
  For Index.i = 1 To CountString(Valeur.s, ".") + 1
    
    AjouterNombreListe.b = #False
    NombreExtrait.i = Val(StringField(Valeur.s, Index.i, "."))
    
    If ListSize(ListeNombresEntree.i()) > 0
      FirstElement(ListeNombresEntree.i())
      PremierNombreListe.i = ListeNombresEntree.i()
      
    Else
      AddElement(ListeNombresEntree.i())
      ListeNombresEntree.i() = NombreExtrait.i
      
      AddElement(ListeNombresSortie.i())
      ListeNombresSortie.i() = NombreExtrait.i
      
      Continue
      
    EndIf
    
    If PremierNombreListe.i > NombreExtrait.i
      
      If PremierNombreListe.i - NombreExtrait.i <= EcartMax.i
        AjouterNombreListe.b = #True
      Else
        Break
        
      EndIf
      
    ElseIf PremierNombreListe.i < NombreExtrait.i
      
      If NombreExtrait.i - PremierNombreListe.i <= EcartMax.i
        AjouterNombreListe.b = #True
      Else
        Break
        
      EndIf
      
    ElseIf PremierNombreListe.i = NombreExtrait.i
      AjouterNombreListe.b = #True
      
    EndIf
    
    If AjouterNombreListe.b = #True
      AddElement(ListeNombresEntree.i())
      ListeNombresEntree.i() = NombreExtrait.i
      SortList(ListeNombresEntree.i(), #PB_Sort_Ascending)
      
      AddElement(ListeNombresSortie.i())
      ListeNombresSortie.i() = NombreExtrait.i
      
    EndIf
    
  Next
  
  ForEach ListeNombresSortie.i()
    TotaleListeNombres.i + ListeNombresSortie.i()
    Sortie.s + ListeNombresSortie.i() + "."
  Next
  
  TailleListeNombre.i = ListSize(ListeNombresSortie.i())
  MoyenneListeNombres.i = TotaleListeNombres.i / TailleListeNombre.i
  
  Sortie.s = InsertString(Sortie.s, Str(TailleListeNombre.i) + "-", 1)
  
  Sortie.s = ReverseString(Sortie.s)
  Sortie.s = Mid(Sortie.s, 2)
  Sortie.s = ReverseString(Sortie.s)
  Sortie.s + "-"
  
  ForEach ListeNombresSortie.i()
    Sortie.s + Str(MoyenneListeNombres.i) + "."
  Next
  
  Sortie.s = ReverseString(Sortie.s)
  Sortie.s = Mid(Sortie.s, 2)
  Sortie.s = ReverseString(Sortie.s)
  
  ProcedureReturn Sortie.s
  
EndProcedure

Re: Lisseur de nombres

Publié : lun. 12/juin/2017 17:40
par Shadow
Bon pas encore au poins mais ça avance, regardez:

Tests:
; "240.238.237.238.240.239.241.242.243.244.236.245.242" -> 7-240.238.237.238.240.239.241-239.239.239.239.239.239.239 ; Ok
; "237.240.238.236.239.238.240.242.242.241.243.244.245" -> 7-237.240.238.236.239.238.240-238.238.238.238.238.238.238 ; Ok
; "236.239.238.240.237.241.238.242.242.241.243.244.245" -> 5-236.239.238.240.237-238.238.238.238.238 ; Ok
; "236.239.238.240.237.236.239.238.240.237.241.238.242.242.241.243.244.245" -> 10-236.239.238.240.237.236.239.238.240.237-238.238.238.238.238.238.238.238.238.238 ; Ok
; "238.236.240.237.239.238.240.242.242.241.243.244.245" -> 7-238.236.240.237.239.238.240-238.238.238.238.238.238.238 ; Ok
; "5.3.7.4.5.2.7.3.2.4.1.5.4.7" -> 6-5.3.7.4.5.2-4.4.4.4.4.4 ; Pas bon car plus de 3 de différence entre le nombre d'origine et le nombre lissé
; "238.236.240.237.238.235.240.243.242.241.243.244.245" -> 6-238.236.240.237.238.235-237.237.237.237.237.237 ; Pas bon car plus de 3 de différence entre le nombre d'origine et le nombre lissé

Re: Lisseur de nombres

Publié : lun. 12/juin/2017 20:25
par Ar-S
J'ai l'impression que tu veux gagner en nombre de couleurs dans une image en perdant le moins possible de qualité... Le truc c'est qu'en faisant par exemple : 243,243,243,243,201,201 au lieu de 240,245,247,242,200,201 tu vas te retrouver avec une image en N couleurs..
On a déjà parlé de ce sujet et tu peux déjà automatiquement faire ça en PB...
Tu as toi même participé au sujet ICI

Re: Lisseur de nombres

Publié : mar. 13/juin/2017 0:25
par Shadow
Oui mais non, la c'est pour lisser les valeurs qui sont assez proche.
Ex: 100, 102, 101, 99, 100, 101, 101, 102, 99, 100 -> 101, 101, 101, 101, 101, 101, 101, 101, 101, 101

On va pas forcement perdre beaucoup en couleurs !