Package eas.math.matrix

Source Code of eas.math.matrix.MatrixVarianten

/*
* Datei:        MatrixVarianten.java
* Autor(en):    Lukas König, free internet code.
* Java-Version: 6.0
* Erstellt:     08.04.2010
*
* (c) This file and the EAS (Easy Agent Simulation) framework containing it
* is protected by Creative Commons by-nc-sa license. Any altered or
* further developed versions of this file have to meet the agreements
* stated by the license conditions.
*
* In a nutshell
* -------------
* You are free:
* - to Share -- to copy, distribute and transmit the work
* - to Remix -- to adapt the work
*
* Under the following conditions:
* - Attribution -- You must attribute the work in the manner specified by the
*   author or licensor (but not in any way that suggests that they endorse
*   you or your use of the work).
* - Noncommercial -- You may not use this work for commercial purposes.
* - Share Alike -- If you alter, transform, or build upon this work, you may
*   distribute the resulting work only under the same or a similar license to
*   this one.
*
* + Detailed license conditions (Germany):
*   http://creativecommons.org/licenses/by-nc-sa/3.0/de/
* + Detailed license conditions (unported):
*   http://creativecommons.org/licenses/by-nc-sa/3.0/deed.en
*
* This header must be placed in the beginning of any version of this file.
*/

package eas.math.matrix;

import java.io.Serializable;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedList;

import eas.math.MiscMath;
import eas.miscellaneous.datatypes.DoppComp;
import eas.miscellaneous.datatypes.Integer2D;




/**
* @author Lukas König, Thomas Darimont (Internet).
*
* http://www.tutorials.de/forum/java/
* 164941-n-x-n-matrizenmultiplikation-aber-wie.html
*/
public class MatrixVarianten implements Serializable {

    private static final long serialVersionUID = -4504318010909128688L;

    /**
     * Die Felder der Matrix.
     */
    private double[][] matrix;
   
    /**
     * Zeilenüberschriften.
     */
    private Integer2D[] zeilenUeberschr;
   
    /**
     * Spalten�berschriften.
     */
    private Integer2D[] spaltenUeberschr;
   
    /**
     * Konstruktor.
     *
     * @param x  Die Anzahl der Spalten.
     * @param y  Die Anzahl der Zeilen.
     */
    public MatrixVarianten(final int x, final int y) {
        this.matrix = new double[x][y];
        this.zeilenUeberschr = new Integer2D[this.getAnzZeilen()];
        this.spaltenUeberschr = new Integer2D[this.getAnzSpalten()];
    }
   
    /**
     * Konstruktor.
     *
     * @param mat  Die Initialmatrix.
     */
    public MatrixVarianten(final double[][] mat) {
        if (mat == null) {
            throw new RuntimeException("Matrix darf nicht null sein.");
        }
        if (mat.length == 0) {
            this.matrix = new double[0][0];
        }
        this.matrix = new double[mat.length][mat[0].length];
        for (int i = 0; i < mat.length; i++) {
            for (int j = 0; j < mat[0].length; j++) {
                this.matrix[i][j] = mat[i][j];
            }
        }
        this.zeilenUeberschr = new Integer2D[this.getAnzZeilen()];
        this.spaltenUeberschr = new Integer2D[this.getAnzSpalten()];
    }
   
    public MatrixVarianten(final MatrixVarianten matrix) {
        this(matrix.matrix);
       
        for (int i = 0; i < matrix.getAnzSpalten(); i++) {
            this.spaltenUeberschr[i] = matrix.spaltenUeberschr[i];
        }
        for (int j = 0; j < matrix.getAnzZeilen(); j++) {
            this.zeilenUeberschr[j] = matrix.zeilenUeberschr[j];
        }
    }
   
    /**
     * Berechnet die Wahrscheinlichkeit, dass sich zwei unterschiedliche
     * aus einer Population treffen.
     *
     * @param vert  Die Verteilung guter und schlechter in der Population.
     * @param schlechteGuete  Die Güte der schlechten Roboter
     *                        (0 - unbeweglich, 1 - gleich wie gute).
     *
     * @return  Die Wahrscheinlichkeit.
     */
    private double wkeitUnterschiedlich(
            final Integer2D vert, final double schlechteGuete) {
        double gute = vert.gute;
        double schlechte = vert.schlechte;
       
        // Schlechte sind so gut wie gute (1).
        if (schlechteGuete > 0.5) {
            return 2 * gute * schlechte / (gute + schlechte)
                    / (gute + schlechte - 1);
        } else { // Schlechte sind schlecht (unbeweglich; 0).
            if (Math.abs(gute) < 0.001) {
                return 0;
            } else {
                return schlechte / (gute + schlechte - 1);
            }
        }
    }

    /**
     * Erzeugt einen Reproduktionsgraphen für die angegebene Populationsgröße
     * für eine homogene Markow-Kette.
     *
     * Dabei wird zwischen guten und schlechten Individuen unterschieden, die
     * sich gleichverteilt zufällig paarweise treffen.
     *
     * @param popGr           Die Populationsgröße.
     * @param schlechteGuete  Die Güte der schlechten Roboter
     *                        (0 - unbeweglich, 1 - gleich wie gute).
     *
     * @return  Die Wahrscheinlichkeitmatrix.
     */
    public static MatrixVarianten erzeugeRepGraphFein(
            final int popGr,
            final double schlechteGuete) {
        LinkedList<Integer2D> zustaende = new LinkedList<Integer2D>();
        MatrixVarianten mat;

        for (int i = 0; i <= popGr; i++) {
            zustaende.add(new Integer2D(i, popGr - i));
        }

        Collections.sort(zustaende, new DoppComp());

        mat = new MatrixVarianten(zustaende.size(), zustaende.size());
        for (int i = 0; i < zustaende.size(); i++) {
            mat.setSpaltenUeberschr(i, zustaende.get(i));
            mat.setZeilenUeberschr(i, zustaende.get(i));
        }

        for (int i = 0; i < mat.getAnzZeilen(); i++) {
            for (int j = 0; j < mat.getAnzSpalten(); j++) {
                // X / Y => X+1 / Y-1
                if (mat.getSpaltenUeberschr(j).gute
                        - mat.getZeilenUeberschr(i).gute == 1) {
                    mat.set(i, j, mat.wkeitUnterschiedlich(mat
                            .getZeilenUeberschr(i), schlechteGuete) / 2);
                }

                // X / Y => X-1 / Y+1
                if (mat.getSpaltenUeberschr(j).gute
                        - mat.getZeilenUeberschr(i).gute == -1) {
                    mat.set(i, j, mat.wkeitUnterschiedlich(mat
                            .getZeilenUeberschr(i), schlechteGuete) / 2);
                }

                // X / Y => X / Y
                if (mat.getSpaltenUeberschr(j).gute
                        - mat.getZeilenUeberschr(i).gute == 0) {
                    mat.set(i, j, 1 - mat.wkeitUnterschiedlich(mat
                            .getZeilenUeberschr(i), schlechteGuete));
                }
            }
        }
       
        mat.transpone();

        return mat;
    }
   
    /**
     * Erzeugt einen Rekombinationsgraphen als
     * Markow-Wahrscheinlichkeits-Matrix.
     *
     * @param startX  Die Anzahl der guten Startroboter.
     * @param startY  Die Anzahl der schlechten Startroboter.
     *
     * @return  Die Wahrscheinlichkeitsmatrix.
     */
    public static MatrixVarianten erzeugeRepGraph(final int startX, final int startY) {
        HashSet<Integer2D> zustaende = new HashSet<Integer2D>();
        LinkedList<Integer2D> hinzu = new LinkedList<Integer2D>();
        LinkedList<Integer2D> zustListe;
        MatrixVarianten mat;
        hinzu.add(new Integer2D(startX, startY));

        while (!zustaende.containsAll(hinzu)) {
            zustaende.addAll(hinzu);
            hinzu.clear();

            for (Integer2D p : zustaende) {
                if (p.gute >= p.schlechte) {
                    for (int i = -p.schlechte; i <= p.schlechte; i += 1) {
                        hinzu.add(new Integer2D(p.gute + i, p.schlechte - i));
                    }
                } else {
                    for (int i = -p.gute; i <= p.gute; i += 1) {
                        hinzu.add(new Integer2D(p.gute + i, p.schlechte - i));
                    }
                }
            }
        }

        zustListe = new LinkedList<Integer2D>(zustaende);
        Collections.sort(zustListe, new DoppComp());

        mat = new MatrixVarianten(zustListe.size(), zustListe.size());
        for (int i = 0; i < zustListe.size(); i++) {
            mat.setSpaltenUeberschr(i, zustListe.get(i));
            mat.setZeilenUeberschr(i, zustListe.get(i));
        }

        // Matrix f�llen.
        // Deterministische Zeilen:
        for (int i = 0; i < mat.getAnzZeilen(); i++) {
            if (mat.getZeilenUeberschr(i).gute == 0
                    || mat.getZeilenUeberschr(i).schlechte == 0) {
                for (int j = 0; j < mat.getAnzSpalten(); j++) {
                    if (mat.getSpaltenUeberschr(j).equals(
                            mat.getZeilenUeberschr(i))) {
                        mat.set(i, j, 1);
                    } else {
                        mat.set(i, j, 0);
                    }
                }
            }
        }

        // Probabilistische Zeilen:
        for (int i = 0; i < mat.getAnzZeilen(); i++) {
            if (mat.getZeilenUeberschr(i).gute >= mat.getZeilenUeberschr(i).schlechte) {
                for (int k = 0; k <= mat.getZeilenUeberschr(i).schlechte; k++) {
                    for (int j = 0; j < mat.getAnzSpalten(); j++) {
                        if (mat.getSpaltenUeberschr(j).gute == mat
                                .getZeilenUeberschr(i).gute
                                - mat.getZeilenUeberschr(i).schlechte + 2 * k
                                && mat.getSpaltenUeberschr(j).schlechte == 2
                                        * mat.getZeilenUeberschr(i).schlechte - 2 * k) {
                            double wert = MiscMath.binomialCoefficient(mat
                                    .getZeilenUeberschr(i).schlechte, k)
                                    / Math.pow(2, mat.getZeilenUeberschr(i).schlechte);
                            mat.set(i, j, wert);
                        }
                    }
                }
            } else {
                for (int k = 0; k <= mat.getZeilenUeberschr(i).gute; k++) {
                    for (int j = 0; j < mat.getAnzSpalten(); j++) {
                        if (mat.getSpaltenUeberschr(j).gute == 2
                                * mat.getZeilenUeberschr(i).gute - 2 * k
                                && mat.getSpaltenUeberschr(j).schlechte == mat
                                        .getZeilenUeberschr(i).schlechte
                                        - mat.getZeilenUeberschr(i).gute + 2 * k) {
                            double wert = MiscMath.binomialCoefficient(mat
                                    .getZeilenUeberschr(i).gute, k)
                                    / Math.pow(2, mat.getZeilenUeberschr(i).gute);
                            mat.set(i, j, wert);
                        }
                    }
                }
            }
        }

        mat.transpone();
       
        return mat;
    }

   
    /**
     * @param i  Spalte.
     * @param j  Zeile.
     *
     * @return  Das Feld [i,j].
     */
    public double get(final int i, final int j) {
        return this.matrix[i][j];
    }
   
    /**
     * @param i     Die Zeile.
     * @param j     Die Spalte.
     * @param wert  Der zu setzende Wert.
     */
    public void set(final int i, final int j, final double wert) {
        this.matrix[i][j] = wert;
    }
   
    /**
     * @return  Spaltenanzahl der Matrix.
     */
    public int getAnzSpalten() {
        return this.matrix.length;
    }
   
    /**
     * @return  Zeilenanzahl der Matrix.
     */
    public int getAnzZeilen() {
        if (this.matrix.length == 0) {
            return 0;
        }
       
        return this.matrix[0].length;
    }
   
    /**
     * Gibt die j-te Zeilen�berschrift zur�ck.
     *
     * @param j  Nummer der �berschrift.
     *
     * @return  Die �berschrift mit der angegebenen Nummer.
     */
    public Integer2D getZeilenUeberschr(final int j) {
        return this.zeilenUeberschr[j];
    }

    /**
     * Gibt die i-te Spaltenn�berschrift zur�ck.
     *
     * @param i  Nummer der �berschrift.
     *
     * @return  Die �berschrift mit der angegebenen Nummer.
     */
    public Integer2D getSpaltenUeberschr(final int i) {
        return this.spaltenUeberschr[i];
    }
   
    /**
     * Setzt die i-te �berschrift auf einen Wert.
     *
     * @param i  Nummer der �berschrift.
     *
     * @param wert  Der Wert, auf den die �berschrift gesetzt werden soll.
     */
    public void setSpaltenUeberschr(final int i, final Integer2D wert) {
        this.spaltenUeberschr[i] = wert;
    }
   
    /**
     * Setzt die j-te �berschrift auf einen Wert.
     *
     * @param j  Nummer der �berschrift.
     *
     * @param wert  Der Wert, auf den die �berschrift gesetzt werden soll.
     */
    public void setZeilenUeberschr(final int j, final Integer2D wert) {
        this.zeilenUeberschr[j] = wert;
    }
   
    public void transpone() {
        MatrixVarianten mat = new MatrixVarianten(this.getAnzZeilen(), this.getAnzSpalten());
       
        for (int i = 0; i < this.getAnzSpalten(); i++) {
            mat.setZeilenUeberschr(i, this.getSpaltenUeberschr(i));
            for (int j = 0; j < this.getAnzZeilen(); j++) {
                mat.setSpaltenUeberschr(j, this.getZeilenUeberschr(j));
                mat.set(j, i, this.get(i, j));
            }
        }
       
        this.matrix = mat.matrix;
        this.spaltenUeberschr = mat.spaltenUeberschr;
        this.zeilenUeberschr = mat.zeilenUeberschr;
    }
   
    /**
     * @param selAnzahlK      Anzahl der Agenten für die Selektion.
     * @param agentenAnzahlN  Anzahl der Agenten in der Population.
     *
     * @return  Wahrscheinlichkeitsmatrix.
     */
    public static Matrix erzeugeWkeitsMatrixStandard1(final int selAnzahlK, final int agentenAnzahlN) {
        int k = selAnzahlK;
        int n = agentenAnzahlN;
       
        Matrix wkeitsMatrix = new Matrix(k + 1, n + 1);
       
        // Ãœberschriften.
        for (int i = 0; i < wkeitsMatrix.getColumnCount(); i++) {
            wkeitsMatrix.setColumnTitle(i, new Integer2D(i, k - i));
        }
       
        for (int j = 0; j < wkeitsMatrix.getRowCount(); j++) {
            wkeitsMatrix.setRowTitle(j, new Integer2D(j, n - j));
        }
       
        // Werte erzeugen.
        for (int i = 0; i < wkeitsMatrix.getColumnCount(); i++) {
            for (int j = 0; j < wkeitsMatrix.getRowCount(); j++) {
                if (wkeitsMatrix.getColumnTitle(i).gute > wkeitsMatrix.getRowTitle(j).gute
                        || wkeitsMatrix.getColumnTitle(i).schlechte > wkeitsMatrix.getRowTitle(j).schlechte) {
                    wkeitsMatrix.set(i, j, 0);
                } else {
                    wkeitsMatrix.set(i, j, 1);
                }
            }
        }
       
        // Werte normalisieren.
        for (int j = 0; j < wkeitsMatrix.getRowCount(); j++) {
            double summe = 0;
           
            for (int i = 0; i < wkeitsMatrix.getColumnCount(); i++) {
                summe += wkeitsMatrix.get(i, j);
            }
            for (int i = 0; i < wkeitsMatrix.getColumnCount(); i++) {
                wkeitsMatrix.set(i, j, wkeitsMatrix.get(i, j) / summe);
            }
        }
       
        return wkeitsMatrix;
    }
}
TOP

Related Classes of eas.math.matrix.MatrixVarianten

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.