MusterSpeicher.java

//
// Klasse       MusterSpeicher + Hilfsklassen Person und Eingabe
//
// Projekt      FingerPrint
//
// Written by Christian Birzer, Peter Söllner Juni 1998
//
// Die MusterSpeicher - Klasse übernimmt die Verwaltung aller Eingabe-
// und Ausgabemuster und ordnet sie den entsprechnenden Personen zu.
// Der MusterSpeicher ist also eine Art Datenbank zur Verwaltung sämt-
// licher personenbezogener Daten im Projekt. Um einen Ausgabevektor des 
// Neuronalen Netztes einer Person zuordnen zu können, ermittelt die Klasse 
// in einer Funktion den Personennamen, dessen Identifikationsmuster am 
// besten mit dem berechneten Ausgabevektor des Netztes übereinstimmt. 
// Die Klasse Person dient hierbei zum Speichern aller notwendigen Personendaten,
// wie z.B. den Namen, einen Farbwert oder das entsprechenden Identifikationsmuster.
// Die Eingabe - Klasse hingegen speichert alle notwendigen Daten für
// einen Eingabevektor. Dies ist unter anderem der Eingabevektor selbst,
// sowie eine Personen - ID und einen Wert, der angibt ob das Muster 
// zum Lernen verwendet werden soll. Zusätzlich enthält die Klasse noch
// ein Textfeld, das einen eindeutigen Namen für dieses Muster enthalten 
// muß und im Projekt zur Speicherung des Dateinamens verwendet wird.

import java.awt.Color;

//
//
// Person
//
//
class Person
{
    public String       name;           // Name der Person
    public String       text;           // Zusätzliche Bemerkungen
    public Color        farbe;          // Farbwert für Netzausgaben
    public NeuroVektor  ausgabemuster;  // Identifikationsmuster der Person
    
    /*
    **
    **  Konstruktoren der Personen - Klasse. 
    **
    */
    public Person(String n, String t, Color f, byte []muster)
    {
        // Kopiert das Identifikationsmuster 'muster' in eine NeuroVektor.
        name=n;
        text=t;
        farbe=f;
        ausgabemuster=new NeuroVektor(muster.length);
        ausgabemuster.InitVektor(muster);
    }

    public Person(String n, String t, Color f, NeuroVektor muster)
    {
        // Speichert direkt das übergebenen Identifikationsmuster.
        name=n;
        text=t;
        farbe=f;
        ausgabemuster=muster;
    }
}

//
//
// Eingabe
//
//
class Eingabe
{
    public NeuroVektor  eingabemuster;  // Eingabemuster (z.B. von der Bildverarbeitung)
    public String       text;           // Eindeutiger Text, das Muster identifiziert
    public int          personenid;     // Personen - ID, für die Zuordnung des Musters
    public boolean      lernen=false;   // Vektor wird vorerst nicht gelernt

    /*
    **
    **  Konstruktor der Eingabe - Klasse.
    **
    */
    public Eingabe(NeuroVektor muster, String t, int pid)
    {
        eingabemuster=muster;
        text=t;
        personenid=pid;
    }
}

//
//
// MusterSpeicher
//
//
public class MusterSpeicher 
{
    private Person m_personen[];    // Array für die Personen - Objekte
    private Eingabe m_eingaben[];   // Array für die Eingabe - Objekte

    private int m_personenanzahl,   // Maximale Anzahl von Personen 
                m_eingabeanzahl;    // Maximale Anzahl von Eingabevektoren  
    private int m_personenindex,    // Aktuelle Anzahl von Personen
                m_eingabeindex;     // Aktuelle Anzahl von Eingabevektoren  
    
    private int m_first,            // Summer der ersten Elemente eines 
                m_firstcount=2,     // Ausgabevektors, hier festgelegt auf 2
                m_suchindex;        // Personenindex der letzten Suche
    private float m_prozent;        // Trefferwahrscheinlichkeit der letzten Suche

    /*
    **
    **  Kontruktor der Klasse MusterSpeicher, zur Initiierung des
    **  Personen- und Eingabearrays. 
    **
    */
    public MusterSpeicher()
    {
        // Maximal 10 Personen
        m_personenanzahl=10;
        m_personenindex=0;
        m_personen=new Person[m_personenanzahl];

        // Maximal 30 Muster pro Person
        m_eingabeanzahl=m_personenanzahl*30;
        m_eingabeindex=0;
        m_eingaben=new Eingabe[m_eingabeanzahl];
    }

    public void AnzahlErsteWerte(int count)
    {
        // Legt die Anzahl der Elemente fest, die zur Berechnung von
        // 'm_first' verwendet werden sollen.
        m_firstcount=count;
    }

    /*
    **
    **  Add - Methoden, zum Hinzufügen eines Personen - Datensatzes.
    **
    */
    public void Add(String name, String text, Color c, byte []muster)
    {
        // Das Feld 'muster' wird im NeuroVektor kopiert.
        m_personen[m_personenindex]=new Person(name,text,c,muster);
        m_personenindex++;
    }

    public void Add(String name, String text, Color c, NeuroVektor muster)
    {
        // Der Vektor 'muster' wird direkt übernommen, 
        // ohne ihn zu kopieren!
        m_personen[m_personenindex]=new Person(name,text,c,muster);
        m_personenindex++;
    }

    public int AnzahlPersonen()
    {
        // Liefert die aktuelle Anzahl von Personen im Musterspeicher zurück.
        return m_personenindex;
    }

    public int GetPersonenIndex(String name)
    {
        // Liefert den Personenindex der Person mit dem Namen 'name' zurück.
        for (int i=0; i<m_personenindex; i++) 
            if (name.equalsIgnoreCase(m_personen[i].name)) return i;
    
        return -1;
    }
    
    public Person GetPerson(int index)
    {
        // Liefert eine Personen - Klasse der Person mit dem Index 'index' zurück.
        return m_personen[index];
    }

    public Person GetPerson(String name)
    {
        // Liefert eine Personen - Klasse der Person mit dem Namen 'name' zurück.
        return m_personen[GetPersonenIndex(name)];
    }
    
    public Color GetColor(int person)
    {
        // Liefert den Farbwert der Person mit dem Index 'person' zurück.
        return m_personen[person].farbe;
    }

    // ****************************************************************
    
    /*
    **
    **  Add - Methode zum Hinzufügen eines Eingabevektors.
    **
    */
    public void Add(NeuroVektor eingabemuster, String text, int personenid)
    {
        // Fügt einen Eingabevektor hinzu.
        m_eingaben[m_eingabeindex]=new Eingabe(eingabemuster, text, personenid);
        m_eingabeindex++;
    }

    public int AnzahlEingaben()
    {
        // Gibt die aktuelle Anzahl von Eingabevektoren zurück.
        return m_eingabeindex;
    }

    public Eingabe GetEingabe(String text)
    {
        // Liefert eine Eingabe anhand des eindeutigen Textes 'text' zurück.
        for (int i=0; i < m_eingabeindex; i++)
            if (text.equalsIgnoreCase(m_eingaben[i].text)) return m_eingaben[i];
    
        return null;
    }
    
    public Eingabe GetEingabe(int index)
    {
        // Liefert die Eingabe mit dem Index 'index' zurück.
        return m_eingaben[index];
    }

    // ****************************************************************

    /*
    **
    **  Sucht für das Ausgabemuster (berechnet vom NN) die Personen - ID
    **  mit dem ähnlichsten Identifikationsmuster.
    **
    */
    public int SucheIndex(NeuroVektor muster)
    {
        // Beeinträchtigt nicht die letzten Ergebnisse der Funktion
        // SucheMuster im Bezug auf Trefferquote, Suchindex und Geschlecht.
        
        int index=-1, level, minlevel=Integer.MAX_VALUE, maxlevel=0;

        for (int i=0; i<m_personenindex; i++) {
            level = muster.GetLevel(m_personen[i].ausgabemuster);
            if (level > maxlevel) maxlevel=level;
            if (level < minlevel) {
                minlevel=level;
                index=i;
            }
        }
        return ((maxlevel==minlevel)?-1:index);
    }

    /*
    **
    **  Gibt nicht wie die vorherige Funktion den Index zurück, sondern
    **  gleich den Farbwert der Person (wird für die Netzausgabe benötigt).
    **
    */
    public Color SucheColor(NeuroVektor muster)
    {
        int index=SucheIndex(muster);
        return (index<0)?new Color(0,0,0):m_personen[index].farbe;
    }

    /*
    **
    **  Eigentliche Suche - Funktion des MusterSpeichers, die den Personen-
    **  namen zurückgibt, dessen Identifikationsmuster mit dem Ausgabemuster
    **  (des NN) am besten übereinstimmt.
    **
    */
    public String SucheMuster(NeuroVektor muster)
    {
        // Bei dem Mustervergleich wird die selbe Methode verwendet,
        // anhand der das Neuronale Netz das Neuron mit der größten
        // Aktivität bzgl. eines Eingabemuster ermittelt.
        int index=-1, level, minlevel=Integer.MAX_VALUE, maxlevel=0;
        m_first=0;

        for (int i=0; i<m_personenindex; i++) {
            level = muster.GetLevel(m_personen[i].ausgabemuster);
            if (level > maxlevel) maxlevel=level;
            if (level < minlevel) {
                minlevel=level;
                index=i;
            }
        }
        
        m_suchindex=index;
        
        // Die Trefferquote wird anhand der minimalen und maximalen Level,
        // die beim Suchenvorgang berechnet wurde, ermittelt 
        m_prozent=(maxlevel>0)?((float)(maxlevel-minlevel)/(float)maxlevel):1;
        
        // Berechnet die Summe der ersten 'm_fistcount' Elemente des Ausgabe-
        // musters. Wird im Projekt zur Bestimmung des Geschlechts verwendet.
        for (int i=0;i<m_firstcount;i++)
            m_first+=muster.Value(i);
        
        return m_personen[index].name;
    }

    // ****************************************************************

    public int Index()
    {
        // Gibt den Personenindex der letzten Suche zurück.
        return m_suchindex;
    }

    public float Trefferquote()
    {
        // Gibt die Trefferquote der letzten Suche zurück.
        return m_prozent;
    }

    public int SummeErsterWerte()
    {
        // Gibt die Summe der ersten 'm_firstcount' Elemente, der letzen
        // Suche zurück. Anhand dieses Werts wird später im Projekt das 
        // Geschlecht der gefundenen Person ermittelt. Hierfür besitzen 
        // die Identifikationsmuster der männlichen Personen für die ersten
        // beiden Vektorelemente positive Werte, hingegeg die weibliche 
        // Personen negative Werte enthalten (Fraglich ist, ob überhaupt 
        // Merkmale vorhanden sind, die darauf schließen lassen, daß es 
        // sich um eine männliche oder weibliche Person handelt ;-)).
        return m_first;
    }
}