Erstellung eines laufenden Mittelwertes bei Messwerten

rustyoldguy

Mitglied
Berechung eines laufenden Mittelwertes

Hallo Umschüler und Konsorten!

In der Qualitätssicherung kommt es oft vor, das man Strichproben ziehen muss um die Qualität
der Produkte einer laufenden Produktion regelmäßig zu überprüfen. Bevor ich das Programm hier
hinein stelle, einige Anmerkungen zur Qualitätssicherung.

Bei der Qualitätssicherung werden oft sogenannte Shewhart-Karten eingesetzt. In regelmäßigen
Abständen wird aus der Fertigung eine vorher festgesetzte Menge an Produkten entnommen um
diese dann zu prüfen. Bei sogenannten quantitativen kontinuierlichen Merkmalen wie zum
Beispiel die Bohrungsdurchmesser werden dann die Maße notiert welche dann als sogenannte Urwerte
dienen. Aus diesen werden dann die Kennwerte errechnet, wie etwa Spannweite(Range), arithmetischer
Mittelwert, oder der Medianwert. Aus dem arithmetischen Mittelwert dann die Standardabweichung.

Wobei man unterschiedliche Arten von Shewhart-Karten kennt. Häufig sind Kombinationen wie
Mittelwert und Standardabweichung oder Zentralwert und Spannweite.

Spannweite = Maximalwert -Minimalwert
arithmetischer Mittelwert = Summe_aller_Werte / Anzahl_der_Werte

Nun zum Medianwert(Zentralwert).
Beim Medianwert müssen alle Werte der Größe nach geordnet werden. Ist die Zahl der Werte in der
Stichprobe ungerade wie 5 os ist dessen Bildung einfach:

Wert 1= 10.015 mm
Wert 2= 10.005 mm
Wert 3= 10.001 mm
Wert 4= 10.003 mm
Wert 5= 10.008 mm

geordnet:
Wert 3= 10.001 mm
Wert 4= 10.003 mm

Wert 2= 10.005 mm <--------------Zentralwert(Medianwert), da der mittlere Wert!

Wert 5= 10.008 mm
Wert 1= 10.015 mm



Liegt aber eine geradzahlige Anzahl der Werte einer Stichprobe vor, so werden die beiden
mittleren zur Bildung des Medianwertes heran gezogen. Hätte man im oberen Beispiel sechs statt
fünf Werte vor sich, so sähe die Bildung des Medianwertes so aus:

ungeordnet:
Wert 1= 10.015 mm
Wert 2= 10.005 mm
Wert 3= 10.001 mm
Wert 4= 10.003 mm
Wert 5= 10.008 mm
Wert 6= 10.011 mm


geordnet:
Wert 3= 10.001 mm
Wert 4= 10.003 mm

Wert 2= 10.005 mm
Wert 5= 10.008 mm


Wert 6= 10.011 mm
Wert 1= 10.015 mm

Die beiden mittleren Werte sind hier:
Wert 2= 10.005 mm
Wert 5= 10.008 mm

Der Medianwert wäre hier 10.0065 = (10.005 + 10.008) / 2

Bei diesem Beispiel lassen wir der Einfachheit halber den Medianwert weg.

Idee war hier bei einer ständigen Auswertung der Messwerte immer nur die letzten Werte, hier im
späteren Programm ist die Zahl 5 für die Bildung der Kennwerte heran zu ziehen. Dabei sind oft
nicht nur Eingriffsgrenzen, sondern auch Warngrenzen zu beachten. Im Prinzip ist das
so ähnlich wie wenn man mit dem Auto über eine Brücke fährt, links und rechts das Brückengeländer.
Wie beim Auto fahren korrigiert man ja die Fahrtrichtung BEVOR das Auto das Geländer tuschiert oder
man auf die Gegenfahrbahn, kommt. Hier wird oft das Prinzip zwei von drei angewandt. Das heißt,
wenn in einer Stichprobe zwei von drei Werten ausserhalb der Eingriffsgrenzen liegen, muss gehandelt
werden. Es soll ja der Kunde wiederkommen, nicht das Produkt.

Sofern ständig zum Beispiel der Bohrungsdurchmesser gemessen wird, könnte hier das Prinzip des
laufenden Mittelwertes angewandt werden.

zunächst runaverage.h
Code:
#include <iostream>
#include <math.h>
#ifndef RUNAVERAGE_H_INCLUDED
#define RUNAVERAGE_H_INCLUDED

// Wird das Schluesselwort 'extern' nicht verwendet kommt es zur Fehlermeldung von "multiple definiton of struct....."
extern struct kennwerte{
 double minwert;
 double maxwert;
 double range;
 double mittelwert;
 double s;
    
}kwert;

double maxiwert(double messwerte[], int n);
double miniwert(double messwerte[], int n);
double average(double messwerte[], int n);
double stabw(double messwerte[], int n);
void Ergebnis(struct kennwerte kwert);
void calcvalues(double messwerte[], int n, struct kennwerte *kwert);
void showValues(double messwerte[], int n);
void CngValues(double (*messwerte)[5], int n, double newval);

#include <string>

void clpuf(void);
int MenueFrage(void);

#endif

nun runaverage.cpp
Code:
#include "runaverage.h"

// Loescht den Tastaturpuffer
void clpuf(void)
 {
 while (getc(stdin) != '\n')
    ;
 }

// gibt bei fehlerhafter Auswahl des Menues den Wert 18 aus, um Fehler im Programm zu vermeiden 
int MenueFrage(void)
{
 int frage = 18, i;
 std::string wastun = "";
 std::string erge[16] = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15"};
 
 std::cout << std::endl << "Ihre Wahl: ";
 std::cin >> wastun; // frage 
 
 for (i = 0; i < 16; i++)
  {
   if (wastun.compare(erge[i]) == 0)
   {
    frage = i;
    break;   
   }
 }
 clpuf();
 
 return frage;
}


// Sucht den Maximalwert der Stichprobe
double maxiwert(double messwerte[], int n)
{
 int i;
 double rewer = 0;
 
 for (i = 0; i < n; i++)
   if (messwerte[i] > rewer)
    rewer = messwerte[i];

 //printf("\nMaxi: %lf  ",  rewer);
    
 return rewer;
}

// Sucht den Minimalwert der Stichprobe
double miniwert(double messwerte[], int n)
{
 int i;
 double maxi = 0, mini = 0;
 
 maxi = maxiwert(messwerte, n);
 mini = maxi;
 
 for (i = 0; i < n; i++)
   if (messwerte[i] < mini)
    mini = messwerte[i];

 //printf("\nMini: %lf  ",  mini);
     
 return mini;
}

// Errechnet den arithmetischen Mittelwert der Stichprobe
double average(double messwerte[], int n)
{
 int i;
 double rewer = 0;
 
 for (i = 0; i < n; i++) rewer += messwerte[i];
    
  rewer /= (double)n;
    
 return rewer;
}

// Errechnet die Standardabweichung der Stichprobe
double stabw(double messwerte[], int n)
{
 int i; 
 double q = 0L, di, s, xquer;
 
 xquer = average(messwerte, n);
 
 for (i = 0; i < n; i++)
  {
   di = (messwerte[i] - xquer);
   q += (di * di);
  }
   q /= n - 1;
  
  s = sqrt(q);
  
 return s; 
} 

// Zeigt Kennwerte auf
void Ergebnis(struct kennwerte kwert)
{
 /* Ende der Berechung der Standardabweichung der Stichprobe*/
  std::cout << "\nDurchschnitt.......: " << kwert.mittelwert << std::endl;
  std::cout << "Minimalwert........: " << kwert.minwert << std::endl;
  std::cout << "Maximalwert........: " << kwert.maxwert<< std::endl;
  std::cout << "Range..............: " << kwert.range << std::endl;
  std::cout << "Standardabweichung: " << kwert.s << std::endl;
}
 
// Errechnet die Kennwerte 
void calcvalues(double messwerte[], int n, struct kennwerte *kwert)
{
  kwert->maxwert = maxiwert(messwerte, n);   /* größten Wert feststellen */
  kwert->minwert = miniwert(messwerte, n);   /* kleinsten Wert festellen */
  kwert->range = kwert->maxwert - kwert->minwert;
  kwert->mittelwert = average(messwerte, n); /* arithmetischen Mittelwert errechnen */
  kwert->s = stabw(messwerte, n); /*Start Berechnung der Standardabweichung der Stichprobe */
} 

// Zeigt die Messwerte auf
void showValues(double messwerte[], int n)
{
 int i; 
 std::cout << "\n\nAusgabe von " << n << " Werten: " << std::endl;

 for (i = 0; i < n; i++)
 std::cout << "Messwert " << (i + 1) << " = " << messwerte[i] << std::endl;
}

// Schiebt die letzten Messwerte, nach hinten und nimmt neuen Messwert auf, um einen laufenden Mittelwert zu ermoeglichen
void CngValues(double (*messwerte)[5], int n, double newval)
{
 int i;
 
 for (i = n - 1; i >= 1; i--)
 (*messwerte)[i] = (*messwerte)[i - 1]; 
        
  (*messwerte)[0] = newval;
}

Jetzt main.cpp
Code:
/** laufender Mittelwert aus den letzten 5 Werten wenn mehr oder gleich 5 (anzahlwerte)Werte vorhanden sind
 *  ebenso Minimal- und Maximal-Wert, Range und Standardabweichung
 *  n = maximale Anzahl der einzulesenden Werte 
 * */
#include "runaverage.h"

int main(int argc, char **argv)
{
struct kennwerte kwert;
    
    
int anzahlwerte = 5, n = 10, i, j, watu = 8;
double messwerte[5] = {0}; //20.1, 20.2, 20.3, 20.4, 20.5};
double allewerte[20] = {0};
double q;

q = 0;


 do 
 switch(watu)
 { 
  default:
     std::cout << "Programm beenden...................0" << std::endl;
      std::cout << "Werte eingeben.....................1" << std::endl;
     std::cout << "Zeige alle Werte...................2" << std::endl;
     std::cout << "Kennwerte alle Werte...............3" << std::endl;
     watu = MenueFrage();
    break;     

 case 0:
     std::cout << "Programm beendet" << std::endl;
     return 0;
    break; 
    
 case 1:
  /// Messwerte einlesen 
  j = 0;
  for (i = 0; i < n; i++)
  {
   std::cout << "Eingabe Messwert_" << i + 1 << " : ";
   std::cin >> q;
   allewerte[j++] = q;
   if (i < anzahlwerte) messwerte[i] = q; // Wenn i von 0 bis 4 dann direktes Einspeichern der Werte
   if (i >= anzahlwerte) // Wenn i > 5 also mehr als 5 Elemente eingelesen, Werte verschieben und letzten Wert als ersten eintragen
    {
     CngValues(&messwerte, anzahlwerte, q);
     showValues(messwerte, anzahlwerte);   
    }
    
    // Zaehlung beginnnt bei Null daher sind wenn i = 4 ist, 5 Elemente erreicht, also anzahlwerte - 1
   if (i >= anzahlwerte - 1) 
    {
     calcvalues(messwerte, anzahlwerte, &kwert);
     Ergebnis(kwert);
    } 
   }
   watu = 8;
  break;  
  
  case 2:
     std::cout << "Zeigen alle Werte" << std::endl;
     showValues(allewerte, n);   
    watu = 8;
  break;  
  
   case 3:
     std::cout << "Kennwerte alle Eingabe-Werte" << std::endl;
     calcvalues(allewerte, n, &kwert);
     Ergebnis(kwert);
    watu = 8;
  break; 
   
 }while(watu != 0);
 
 return 0;
}
 
Zurück
Oben Unten