#include "StdAfx.h"
#include "simulation.h"
#include "pixel.h"
#include "oekologie.h"
#include "massnahme.h"
#include "kosten.h"
#include "matrix.h"
#include "datenbank.h"
#include "variablekosten.h"
#include "verfahren_ertrag.h"
#include "wuchshoehe.h"
#include <time.h>
#include <math.h>   
  
#include "loa.h"

#include <functional>
#include <numeric>



#include <iostream>
#include <sstream>
#include <fstream>


#include <algorithm>
#include <cmath> 

using namespace std;

simulation::simulation( void)
{
}

simulation::~simulation( void)
{
}
bool myfunction( modell::masspixelergeb mp1, modell::masspixelergeb mp2)
{
    return (mp1.gewinn > mp2.gewinn);
}

simulation::ergebnis simulation::simulate(
        int tzahlung,
        vector< art*>& artlist,
        vector< massnahme>& mliste,
        vector< double>& minqualitaet,
        vector< double>& ziehlartqual,
        bool zahlung,
        int zeilen,
        int spalten,
        int bundeslandID,
        bool hoch,
        bool egal)
{

    //falls zahlung = false -> der erste Durchlauf soll ohne Zahlung erfolgen, damit eine minimale Zahlung berechnet werden kann
    vector< massnahme>::iterator ml;
    vector< double>::iterator flaeche;
    ergebnis *ergeb;
    ergeb = new ergebnis;
    modell mod;
    vector< double> zahlung0, zahlung1, zahlungbest;
    //speichert für jede Massnahme die Zahlung;
    vector< int> menge1, mengeneu, mengebest; //speichert für jede Massnaheme die Fläche = Anzahl an Pixel für die die Massnamhe angewendet werden darf

    int max_flaeche = 0;
    int minq = 0;
    int anzahlarten = artlist.size();
    for( flaeche = ziehlartqual.begin(); flaeche != ziehlartqual.end();
            flaeche++)
    {
        //for(minq = 0; minq < ziehlartqual.size(); minq++)
        //{
        int fl = static_cast< int>( ((*flaeche) / (minqualitaet[ minq])) / 6.25);
        //CString st;
        //st.Format(_T("%.d"),fl);
        //AfxMessageBox(st,MB_YESNO,0);
        if( max_flaeche < fl)
            max_flaeche = fl;
        minq++;
        //}
    }

    max_flaeche = max_flaeche * anzahlarten;
    /*CString st;
     AfxMessageBox("Gesammtausgabe",MB_YESNO,0);
     st.Format(_T("%.d"),max_flaeche);
     AfxMessageBox(st,MB_YESNO,0);*/
    if( !zahlung)
    {
        for( ml = mliste.begin(); ml != mliste.end(); ml++)
        {
            (*ml).zahlung = 0;
            zahlung0.push_back( 0);
            menge1.push_back( 0);

        }
    } else
    {
        for( ml = mliste.begin(); ml != mliste.end(); ml++)
        {
            zahlung0.push_back( (*ml).zahlung);
            menge1.push_back( 0);

        }
    }

    vector< double> kostendifferenz;
    vector< double> kostenmax;
    int mn = mliste.size();

    vector< vector< modell::masspixelergeb>>::iterator me; // Iterator für die Liste der Kostenlisten aller Massnahmen
    vector< modell::masspixelergeb>::iterator mp; //Iterator für die Kostenliste einer Massnahme
    vector < vector < modell::masspixelergeb >> massnahmenergebvector1( mn);
    vector < vector < modell::masspixelergeb >> massnahmenergebvector2( mn);
    for( int i = 0; i < mn; i++)
    {
        vector < modell::masspixelergeb > *vec1 = new vector<
                modell::masspixelergeb>;
        vector < modell::masspixelergeb > *vec2 = new vector<
                modell::masspixelergeb>;
        massnahmenergebvector1[ i] = *vec1;
        massnahmenergebvector2[ i] = *vec2;
    }

//AfxMessageBox("Vor der Modelierung",MB_YESNO,0);
    //die Modelierung erfolgt nun
    mod.calculate_oekologiemodell( artlist, mliste, minqualitaet,
            massnahmenergebvector1, bundeslandID, hoch, egal);
//AfxMessageBox("Nach der Modelierung",MB_YESNO,0);

    int i = 0;
    int anzahl = massnahmenergebvector1.size();
    CString st;
    st.Format( _T( "%.d"), anzahl);
    //AfxMessageBox(st,MB_YESNO,0);
    int penalty1 = 0;
    int penalty2 = 0; //Zähler für die nicht erreichten Artenflächen
	int penaltybest;
    double penaltyfaktor1 = 0;
    double penaltyfaktor2 = 0;
    CString str;

    for( me = massnahmenergebvector1.begin();
            me != massnahmenergebvector1.end(); me++)
    {
        if( (*me).size() > 0)
        {
            sort( (*me).begin(), (*me).end(), myfunction);

            if( (*me)[ 0].gewinn < 0)
            {
                //zahlung0[i]=(((*me)[0].gewinn )*(-1))+1+tzahlung;// die minimale Zahlung die geleistet werde  muss, damit einige Pixel einen Gewinn >=0 haben +50%;
                //str.Format(_T("%.2f"),zahlung0[i]);
                //AfxMessageBox(str,MB_YESNO,0);

                double kd = (((*me).back().gewinn) * (-1))
                        - (((*me)[ 0].gewinn) * (-1));
                str.Format( _T( "%.2f"), kd);
                //AfxMessageBox(str,MB_YESNO,0);
                zahlung0[ i] = (((*me)[ 0].gewinn) * (-1)) + 1 + tzahlung
                        + (kd / 4);

                kostendifferenz.push_back( kd);
                kostenmax.push_back( (((*me).back().gewinn) * (-1)));
            } else
            {
                if( (*me)[ 0].gewinn == 0) //hier kann noch an den Werten geändert werden!!!!!!
                {

                    double kd = (((*me).back().gewinn) * (-1));
                    zahlung0[ i] = 1 + tzahlung + (kd / 4);
                    kostendifferenz.push_back( kd);
                    kostenmax.push_back( (((*me).back().gewinn) * (-1)));
                } else
                {

                    double kd = (((*me).back().gewinn) * (-1));
                    zahlung0[ i] = 1 + tzahlung + (kd / 4);
                    kostendifferenz.push_back( kd);
                    kostenmax.push_back( (((*me).back().gewinn) * (-1)));
                }
            }

            if( (*me).size() < max_flaeche)
                menge1[ i] = ((*me).size()); //die maximale Fläche für die Massnahme, alle Pixel auf denen die Massnahme positiv ist
            else
                menge1[ i] = max_flaeche;

        } else
        {
            //AfxMessageBox("gibt nichts!",MB_YESNO,0);
            zahlung0[ i] = 0;
            menge1[ i] = 0;
            kostendifferenz.push_back( 0);
            kostenmax.push_back( 0);
        }

        i++;
    }
    //AfxMessageBox("Nach Sortierung",MB_YESNO,0);
    vector < simulation::mapixelliste_mit_pos > pixellisten_mit_position1;
    vector< modell::masspixelergeb> ergebnisliste_alt, ergebnisliste_neu,
            ergebnisliste_best;
    vector< modell::masspixelergeb>::iterator listenit;

    vector< int> pixelpromassnahme1, pixelpromassnahmebest;
    for( i = 0; i < anzahl; i++)
    {
        if( !massnahmenergebvector1[ i].empty())
        {
            for( mp = massnahmenergebvector1[ i].begin();
                    mp < massnahmenergebvector1[ i].end(); mp++)
            {
                (*mp).gewinn = (*mp).kosten + zahlung0[ i] - tzahlung; // die neue Zahlung muss dazu addiert werden
                (*mp).m.zahlung = zahlung0[ i];
            }
        }
        mapixelliste_mit_pos mmp;
        mmp.massnahmenergebnis = massnahmenergebvector1[ i];
        mmp.position = 0;
        pixellisten_mit_position1.push_back( mmp);
        pixelpromassnahme1.push_back( 0);

    }
    //AfxMessageBox("Nach der Schleife",MB_YESNO,0);
    //Verteilung der Pixel nach Gewinn.
    //Matrix erstellend die erfast ob Pixel schon erfast oder nicht

    double ges_ausgabe1, ges_ausgabe2, ges_ausgabe_best;
    ges_ausgabe1 = 0;
    vector< double> artflaeche1, artflaeche_best; //Wird die Fläche nach der Modelierung für jede Art erfassen jetzt erst mal initialisieren

    //Initialisierung des Simulated annealing

    int anzahl_arten = artlist.size();
    for( int a = 0; a < anzahl_arten; a++)
    {
        artflaeche1.push_back( 0);
    }
    //die initiale Lösung wird berechnet
    //AfxMessageBox("Vor Gesammtkosten",MB_YESNO,0);

    ges_ausgabe1 = gesammtkosten( pixellisten_mit_position1, ergebnisliste_alt,
            artflaeche1, menge1, pixelpromassnahme1, zeilen, spalten,
            anzahl_arten);
    //AfxMessageBox("Nach Gesammtkosten",MB_YESNO,0);
    double missingflaeche1 = 0;
   // double missingflaeche_best;

    for( int a = 0; a < anzahl_arten; a++)
    {
        if( artflaeche1[ a] < ziehlartqual[ a])
        {
           /* int z = (ziehlartqual[ a] - artflaeche1[ a]);
            if( z > 0)

                missingflaeche1 = missingflaeche1 + z;*/
            penalty1++;
        }
    }

   /* if( penalty1 > 0)
    {
        if( ges_ausgabe1 > 0)
        {

            //penaltyfaktor1 = k/max_iteration;
            ges_ausgabe1 = ges_ausgabe1 * (missingflaeche1) * 100; // * k/max_iteration);
        } else
            ges_ausgabe1 = missingflaeche1 * 10000000;
        //Wenn die Randbedingung nicht erfüllt wird, wird die Gesammtausgabe mit der Anzahl
        //an Arten multipilziert, deren Flächenvorgaben nicht erfüllt werden.
    }*/

    // AfxMessageBox("Komme bis hier",MB_YESNO,0);
    //die Lösung aus der Nachbarschaft der ersten wird berechnet und das simulated annealing wird gestartet
    massnahmenergebvector2 = massnahmenergebvector1;

    ges_ausgabe2 = 0;

    srand (time( NULL) );int
    m1 = menge1.size();
    if( m1 == 0)
        m1 = 1;
    int m_halbe = m1 / 2;
    if( m_halbe == 0)
        m_halbe = 1;

    double T = (m1  * 10000000); //Anzahl der Kombinationen um Zahlungen und oder Mengen zu ändern und alle noch mal 1000
    int max_iteration = 100000000;
    int k = 1; //Zähler für die Iterationen
    int n = 0; // Zähler für Anzahl der Iterationen ohne Verbesserung des Ergebnisses
    int bloob = 0;
    bool besser = false;
    bool zwischen = false;
    int zahl;
    int meng;
    int faktormeng;
    int faktorzahl;
    //missingflaeche_best = missingflaeche1;
    ges_ausgabe_best = ges_ausgabe1;
    artflaeche_best = artflaeche1;
    ergebnisliste_best = ergebnisliste_alt;
    pixelpromassnahmebest = pixelpromassnahme1;
    mengebest = menge1;
    zahlungbest = zahlung0;
	penaltybest = penalty1;

    while( (T > 0.005) && (k < max_iteration) && (n != 100000))
    {
        // AfxMessageBox("In der Optimierung",MB_YESNO,0);
        vector< int> pixelpromassnahme2;
        vector< double> artflaeche2;

        for( int a = 0; a < anzahl_arten; a++)
        {
            artflaeche2.push_back( 0);
        }
        vector < simulation::mapixelliste_mit_pos > pixellisten_mit_position2;
        zahlung1 = zahlung0; //Die letzte beste Lösung
        mengeneu = menge1; //Die letzte beste Lösung
        //neue Zahlungen und neue Mengen festlegen
        int addorsub;
        if( besser == false && zwischen == false)
        {
            for( int x = 0; x < m_halbe; x++)
            {
                zahl = rand() % anzahl; //Zufallszahl zwischen 0 und anzahl an Massnahmen

                faktorzahl = ((double) rand() / ((double) RAND_MAX) / 2) + 0.1; //Zufallszahl zwischen 0.1 und 2

                //Die Änderung der Zahlung ist Abbhängig von der Varianz in den Kosten für eine Massnahme
                addorsub = rand() % 2;
                if( addorsub == 1)
                {

                    zahlung1[ zahl] = zahlung1[ zahl]
                            + (faktorzahl * kostendifferenz[ zahl]);
                    if( zahlung1[ zahl] > kostenmax[ zahl])
                        zahlung1[ zahl] = kostenmax[ zahl] + 10 + tzahlung;
                } else
                {

                    zahlung1[ zahl] = zahlung1[ zahl]
                            - (faktorzahl * kostendifferenz[ zahl]);
                    if( zahlung1[ zahl] < 0)
                        zahlung1[ zahl] = 0;
                }
            }
        }
        if( besser == true)
        {
            zahl = rand() % anzahl;
            addorsub = rand() % 2;
            if( addorsub == 1)
            {

                zahlung1[ zahl] = zahlung1[ zahl]
                        + (faktorzahl * kostendifferenz[ zahl]);
                if( zahlung1[ zahl] > kostenmax[ zahl])
                    zahlung1[ zahl] = kostenmax[ zahl] + 10 + tzahlung;

            } else
            {
                zahlung1[ zahl] = zahlung1[ zahl]
                        - (faktorzahl * kostendifferenz[ zahl]);
                if( zahlung1[ zahl] < 0)
                    zahlung1[ zahl] = 0;

                if( zahlung1[ zahl] < 0)
                    zahlung1[ zahl] = 0;

            }
        }
        if( zwischen == true)
        {
            for( int x = 0; x < m_halbe; x++)
            {
                zahl = rand() % anzahl;
                addorsub = rand() % 2;
                if( addorsub == 1)
                {

                    zahlung1[ zahl] = zahlung1[ zahl] + 20;
                    if( zahlung1[ zahl] > kostenmax[ zahl])
                        zahlung1[ zahl] = kostenmax[ zahl] + tzahlung + 10;

                } else
                {

                    zahlung1[ zahl] = zahlung1[ zahl] - 20;

                    if( zahlung1[ zahl] < 0)
                        zahlung1[ zahl] = 0;

                }
            }
        }

        if( besser == false)
        {
            for( int x = 0; x < m_halbe; x++)
            {
                meng = rand() % anzahl; //Zufallszahl zwischen 0 und anzahl an Massnahmen

                //double  faktormeng =  ((double)rand() / ((double)RAND_MAX ));//Zufallszahl zwischen 0 und 1
                faktormeng = rand() % max_flaeche;
                mengeneu[ meng] = faktormeng;

            }
        } else
        {
            meng = rand() % anzahl;
            if( addorsub == 1)
                mengeneu[ meng] = max_flaeche;
            else
                mengeneu[ meng] = 0;
        }

        for( i = 0; i < anzahl; i++)
        {
            if( !massnahmenergebvector2[ i].empty())
            {
                for( mp = massnahmenergebvector2[ i].begin();
                        mp < massnahmenergebvector2[ i].end(); mp++)
                {
                    (*mp).gewinn = (*mp).kosten + zahlung1[ i] - tzahlung; // die neue Zahlung muss dazu addiert werden
                    (*mp).m.zahlung = zahlung1[ i];
                }
            }
            //else
            //AfxMessageBox("Keine Pixel",MB_YESNO,0);

            mapixelliste_mit_pos mmp;
            mmp.massnahmenergebnis = massnahmenergebvector2[ i];
            mmp.position = 0;
            pixellisten_mit_position2.push_back( mmp);
            pixelpromassnahme2.push_back( 0);

        }
        penalty2 = 0;
        ges_ausgabe2 = gesammtkosten( pixellisten_mit_position2,
                ergebnisliste_neu, artflaeche2, mengeneu, pixelpromassnahme2,
                zeilen, spalten, anzahl_arten);
        double missingflaeche2 = 0;
        for( int a = 0; a < anzahl_arten; a++)
        {

            if( artflaeche2[ a] < ziehlartqual[ a])
            {
              /*  int z = (ziehlartqual[ a] - artflaeche2[ a]);
                if( z > 0)
                    missingflaeche2 = missingflaeche2 + z;*/
                penalty2++;
            }
        }

       /* if( penalty2 > 0)
        {
            //penaltyfaktor2 = k/max_iteration;
            if( ges_ausgabe2 > 0)
                ges_ausgabe2 = ges_ausgabe2 * (missingflaeche2) * 100; // * k/max_iteration);
            else
                ges_ausgabe2 = missingflaeche2 * 10000000;

        }*/

        /*
         if(penalty1 >0)
         {
         if(ges_ausgabe1>0)
         {
         ges_ausgabe1 = ges_ausgabe1/(missingflaeche1 * penaltyfaktor1);
         penaltyfaktor1 = k/max_iteration;
         ges_ausgabe1 = ges_ausgabe1 * (missingflaeche1 * k/max_iteration);
         }
         else
         ges_ausgabe1 = missingflaeche1 *  10000000;

         }*/

        double ausgabendiff = ges_ausgabe1 - ges_ausgabe2;
        if( ((ausgabendiff > 0)&& (penalty2 == 0))|| (penalty2 < penalty1))
        {
            ergebnisliste_alt = ergebnisliste_neu;

            artflaeche1 = artflaeche2;
            pixelpromassnahme1 = pixelpromassnahme2;
            ges_ausgabe1 = ges_ausgabe2;
            zahlung0 = zahlung1;
            menge1 = mengeneu;
            penalty1 = penalty2;
            penaltyfaktor1 = penaltyfaktor2;
            //missingflaeche1 = missingflaeche2;
            n = 0;
            besser = true;
            zwischen = false;

            // AfxMessageBox("Die neue ist günstiger",MB_YESNO,0);
        } else
        {
            double a = (double( rand()) / ((double) RAND_MAX)); // produces a random number in [0,1]
            /*str.Format(_T("%.2f"),a);
             AfxMessageBox("a",MB_YESNO,0);
             AfxMessageBox(str,MB_YESNO,0);*/
            double b = exp( ausgabendiff / T);
            /*str.Format(_T("%.2f"),b);
             AfxMessageBox("b",MB_YESNO,0);
             AfxMessageBox(str,MB_YESNO,0);*/
            if( b > a)
            {
                ergebnisliste_alt = ergebnisliste_neu;
                artflaeche1 = artflaeche2;
                pixelpromassnahme1 = pixelpromassnahme2;
                ges_ausgabe1 = ges_ausgabe2;
                zahlung0 = zahlung1;
                menge1 = mengeneu;
                penalty1 = penalty2;
                penaltyfaktor1 = penaltyfaktor2;
               // missingflaeche1 = missingflaeche2;
                n = 0;
                besser = false;
                zwischen = true;
                //AfxMessageBox("bin in dem b>a Zweig ",MB_YESNO,0);

            } else
            {
                n++;
                besser = false;
                zwischen = false;
            }

        }
        if( (ges_ausgabe1 < ges_ausgabe_best)
                && (penaltybest >= penalty1))
        {
            //missingflaeche_best = missingflaeche1;
			penaltybest = penalty1;
            ges_ausgabe_best = ges_ausgabe1;
            artflaeche_best = artflaeche1;
            ergebnisliste_best = ergebnisliste_alt;
            pixelpromassnahmebest = pixelpromassnahme1;
            mengebest = menge1;
            zahlungbest = zahlung0;
        }

        T = T * 0.99998;//9999; //99; //Abkühlung
        k++;
        bloob++;
        penalty2 = 0;
        penaltyfaktor2 = 0;

        ergebnisliste_neu.clear();

    }
    str.Format( _T( "%d"), bloob);
    AfxMessageBox( str, MB_YESNO, 0);

    // AfxMessageBox("bin hinter der Optimierung",MB_YESNO,0);
    (*ergeb).artenflaechen = artflaeche_best;
    (*ergeb).massnahmenergebnis = ergebnisliste_best;
    (*ergeb).masspixel = pixelpromassnahmebest;
    (*ergeb).mengen = mengebest;
    (*ergeb).zahlung = zahlungbest;

    return (*ergeb);

}
simulation::ergebnis simulation::simulate(
        int tzahlung,
        vector< art*>& artlist,
        vector< massnahme>& mliste,
        vector< double>& gewichte,
        vector< double>& minqualitaet,
        int budget,
        bool zahlung,
        int zeilen,
        int spalten,
        int bundeslandID,
        bool hoch,
        bool egal)
{

    //falls zahlung = false -> der erste Durchlauf soll ohne Zahlung erfolgen, damit eine minimale Zahlung berechnet werden kann
    vector< massnahme>::iterator ml;

    ergebnis *ergeb;
    ergeb = new ergebnis;
    modell mod;
    vector< double> zahlung0, zahlung1, zahlungbest; //speichert für jede Massnahme die Zahlung;
    vector< int> menge1, mengeneu, max_flaeche, mengebest; //speichert für jede Massnaheme die Fläche = Anzahl an Pixel für die die Massnamhe angewendet werden darf

    int anzahl_arten = artlist.size();
    /*flaeche = (zeilen*spalten)/(mliste.size());//Teile alle Pixel durch die Anzahl an Massnahmen
     for(int minq = 0; minq != anzahl_arten; minq++)
     {

     int fl = static_cast<int>(flaeche/minqualitaet[minq]);
     if (max_flaeche < fl)
     max_flaeche = fl;
     
     }*/

    if( !zahlung)
    {
        for( ml = mliste.begin(); ml != mliste.end(); ml++)
        {
            (*ml).zahlung = 0;
            zahlung0.push_back( 0);
            menge1.push_back( 0);

        }
    } else
    {
        for( ml = mliste.begin(); ml != mliste.end(); ml++)
        {
            zahlung0.push_back( (*ml).zahlung);
            menge1.push_back( 0);

        }
    }

    vector< double> kostendifferenz;
    vector< double> kostenmax;
    int mn = mliste.size();
    vector< vector< modell::masspixelergeb>>::iterator me; // Iterator für die Liste der Kostenlisten aller Massnahmen
    vector< modell::masspixelergeb>::iterator mp; //Iterator für die Kostenliste einer Massnahme
    vector < vector < modell::masspixelergeb >> massnahmenergebvector1( mn);
    vector < vector < modell::masspixelergeb >> massnahmenergebvector2( mn);
    vector < vector < modell::masspixelergeb >> massnahmenergebvector_best( mn);
    for( int i = 0; i < mn; i++)
    {
        vector < modell::masspixelergeb > *vec1 = new vector<
                modell::masspixelergeb>;
        vector < modell::masspixelergeb > *vec2 = new vector<
                modell::masspixelergeb>;
        vector < modell::masspixelergeb > *vec3 = new vector<
                modell::masspixelergeb>;
        massnahmenergebvector1[ i] = *vec1;
        massnahmenergebvector2[ i] = *vec2;
        massnahmenergebvector_best[ i] = *vec3;
    }
    //die Modelierung erfolgt nun

    mod.calculate_oekologiemodell( artlist, mliste, minqualitaet,
            massnahmenergebvector1, bundeslandID, hoch, egal);
    //AfxMessageBox("Nach der Modelierung",MB_YESNO,0);

    int i = 0;
    int anzahl = massnahmenergebvector1.size();
    int penalty1 = 0;
    int penalty2 = 0; //Zähler für die nicht erreichten Artenflächen
    double penaltyfaktor1 = 0;
    double penaltyfaktor2 = 0;
    CString str;
    int greifende_massnahmen = 0;
    for( me = massnahmenergebvector1.begin();
            me != massnahmenergebvector1.end(); me++)
    {

        //auffangen falls eine Maßnahme sich für kein Pixel qualifiziert hat!!!

        if( (*me).size() > 0)
            greifende_massnahmen = greifende_massnahmen + 1;
    }

    for( me = massnahmenergebvector1.begin();
            me != massnahmenergebvector1.end(); me++)
    {
        int z = 0;
        //auffangen falls eine Maßnahme sich für kein Pixel qualifiziert hat!!!

        if( (*me).size() > 0)
        {
            sort( (*me).begin(), (*me).end(), myfunction);

            if( (*me)[ 0].gewinn < 0)
            {
                //zahlung0[i]=(((*me)[0].gewinn )*(-1))+1+tzahlung;// die minimale Zahlung die geleistet werde  muss, damit einige Pixel einen Gewinn >=0 haben +50%;
                //str.Format(_T("%.2f"),zahlung0[i]);
                //AfxMessageBox(str,MB_YESNO,0);

                double kd = (((*me).back().gewinn) * (-1))
                        - (((*me)[ 0].gewinn) * (-1));
                str.Format( _T( "%.2f"), kd);
                //AfxMessageBox(str,MB_YESNO,0);
                zahlung0[ i] = (((*me)[ 0].gewinn) * (-1)) + 1 + tzahlung
                        + (kd / 2);

                kostendifferenz.push_back( kd);
                kostenmax.push_back( ((*me).back().gewinn) * (-1));
                max_flaeche.push_back(
                        static_cast< int>( budget
                                / (((*me).back().gewinn) * (-1))));
            } else
            {
                if( (*me)[ 0].gewinn == 0) //hier kann noch an den Werten geändert werden!!!!!!
                {

                    double kd = (((*me).back().gewinn) * (-1));
                    zahlung0[ i] = 1 + tzahlung + (kd / 2);
                    kostendifferenz.push_back( kd);
                    kostenmax.push_back( ((*me).back().gewinn) * (-1));
                    max_flaeche.push_back( static_cast< int>( budget / 1));
                } else
                {

                    double kd = (((*me).back().gewinn) * (-1));
                    zahlung0[ i] = 1 + tzahlung + (kd / 2);
                    kostendifferenz.push_back( kd);
                    kostenmax.push_back( ((*me).back().gewinn) * (-1));
                    max_flaeche.push_back( static_cast< int>( budget / 1));
                }
            }

            if( (*me).size()
                    < ((static_cast< int>( budget / zahlung0[ i]))
                            / greifende_massnahmen) / 4)
                menge1[ i] = ((*me).size()); //die maximale Fläche für die Massnahme, alle Pixel auf denen die Massnahme positiv ist
            else
                menge1[ i] = ((static_cast< int>( budget / zahlung0[ i]))
                        / greifende_massnahmen) / 4;

        } else
        {
            //AfxMessageBox("Bin hier",MB_YESNO,0);
            zahlung0[ i] = 0;
            menge1[ i] = 0;
            max_flaeche.push_back( 0);
            kostenmax.push_back( 0);
            kostendifferenz.push_back( 0);

        }

        i++;

    }
    //AfxMessageBox("Nach Sortierung",MB_YESNO,0);
    vector< simulation::mapixelliste_mit_pos> pixellisten_mit_position1,
            pixellisten_mit_position_best;
    vector< modell::masspixelergeb> ergebnisliste_alt, ergebnisliste_neu,
            ergebnisliste_best;
    vector< modell::masspixelergeb>::iterator listenit;

    vector< int> pixelpromassnahme1;
    vector< int> pixelpromassnahmebest;
    for( i = 0; i < mn; i++)
    {
        if( !massnahmenergebvector1[ i].empty())
        {
            for( mp = massnahmenergebvector1[ i].begin();
                    mp < massnahmenergebvector1[ i].end(); mp++)
            {
                (*mp).gewinn = (*mp).kosten + zahlung0[ i] - tzahlung; // die neue Zahlung muss dazu addiert werden
                (*mp).m.zahlung = zahlung0[ i];
            }
        }
        mapixelliste_mit_pos mmp;
        mmp.massnahmenergebnis = massnahmenergebvector1[ i];
        mmp.position = 0;
        pixellisten_mit_position1.push_back( mmp);
        pixelpromassnahme1.push_back( 0);

    }
    //AfxMessageBox("Nach der Schleife",MB_YESNO,0);
    //Verteilung der Pixel nach Gewinn.
    //Matrix erstellend die erfast ob Pixel schon erfast oder nicht

    double ges_ausgabe1, ges_ausgabe2, ges_ausgabe_best;
    ges_ausgabe1 = 0;
    vector< double> artflaeche1; //Wird die Fläche nach der Modelierung für jede Art erfassen jetzt erst mal initialisieren
    vector< double> artflaeche_best;

    for( int a = 0; a < anzahl_arten; a++)
    {
        artflaeche1.push_back( 0);
    }
    //die initiale Lösung wird berechnet
    //AfxMessageBox("Vor Gesammtkosten",MB_YESNO,0);

    ges_ausgabe1 = gesammtkosten( pixellisten_mit_position1, ergebnisliste_alt,
            artflaeche1, menge1, pixelpromassnahme1, zeilen, spalten,
            anzahl_arten);

    //AfxMessageBox("Nach Gesammtkosten",MB_YESNO,0);
    artflaeche_best = artflaeche1;
    ergebnisliste_best = ergebnisliste_alt;
    mengebest = menge1;
    //pixellisten_mit_position_best = pixellisten_mit_position1;
    ges_ausgabe_best = ges_ausgabe1;
    pixelpromassnahmebest = pixelpromassnahme1;
    zahlungbest = zahlung0;
    double gesflaeche1 = 0;
    double gesflaeche_best = 0;
    for( int a = 0; a < anzahl_arten; a++)
    {

        gesflaeche1 = artflaeche1[ a] * gewichte[ a];

    }
    gesflaeche_best = gesflaeche1;
    /*
     if( ges_ausgabe1 > budget)
     {

     penalty1 = 1;
     penaltyfaktor1 = k/max_iteration;
     gesflaeche1 = gesflaeche1 / ((ges_ausgabe1 - budget) * k/max_iteration);
     

     }*/

    // AfxMessageBox("Komme bis hier",MB_YESNO,0);
    //die Lösung aus der Nachbarschaft der ersten wird berechnet und das simulated annealing wird gestartet
    massnahmenergebvector2 = massnahmenergebvector1;
    //massnahmenergebvector_best = massnahmenergebvector1;

    ges_ausgabe2 = 0;

    srand (time( NULL) );int
    m1 = menge1.size();
    if( m1 == 0)
        m1 = 1;
    int m_halbe = m1 / 2;
    if( m_halbe == 0)
        m_halbe = 1;

    double T = (m1 * 10000000); //Anzahl der Kombinationen um Zahlungen und oder Mengen zu ändern und alle noch mal 1000
    int max_iteration = 100000000;
    int k = 1; //Zähler für die Iterationen
    int n = 0; // Zähler für Anzahl der Iterationen ohne Verbesserung des Ergebnisses
    int bloob = 0;
    bool besser = false;
    bool zwischen = false;
    int zahl;
    int meng;
    int faktormeng;
    int faktorzahl;

    while( (T > 0.005) && (k < max_iteration) && (n != 100000))
    {
        // AfxMessageBox("In der Optimierung",MB_YESNO,0);
        vector< int> pixelpromassnahme2;
        vector< double> artflaeche2;

        for( int a = 0; a < anzahl_arten; a++)
        {
            artflaeche2.push_back( 0);
        }
        vector < simulation::mapixelliste_mit_pos > pixellisten_mit_position2;
        zahlung1 = zahlung0; //Die letzte beste Lösung
        mengeneu = menge1; //Die letzte beste Lösung
        //neue Zahlungen und neue Mengen festlegen
        //AfxMessageBox("hier11",MB_YESNO,0);
        int addorsub;
        if( besser == false && zwischen == false)
        {
            for( int x = 0; x < m_halbe; x++)
            {
                zahl = rand() % anzahl; //Zufallszahl zwischen 0 und Anzahl an Massnahmen
                //AfxMessageBox("hier12",MB_YESNO,0);

                faktorzahl = ((double) rand() / ((double) RAND_MAX) / 2) + 0.1; //Zufallszahl zwischen 0.1 und 2
                //Die Änderung der Zahlung ist Abbhängig von der Varianz in den Kosten für eine Massnahme
                addorsub = rand() % 2;
                if( addorsub == 1)
                {

                    zahlung1[ zahl] = zahlung1[ zahl]
                            + (faktorzahl * kostendifferenz[ zahl]);
                    if( zahlung1[ zahl] > kostenmax[ zahl])
                        zahlung1[ zahl] = kostenmax[ zahl] + tzahlung + 100;
                } else
                {

                    zahlung1[ zahl] = zahlung1[ zahl]
                            - (faktorzahl * kostendifferenz[ zahl]);

                    if( zahlung1[ zahl] < 0)
                        zahlung1[ zahl] = 0;

                }

            }
        }
        if( besser == true)
        {
            zahl = rand() % anzahl;
            addorsub = rand() % 2;
            if( addorsub == 1)
            {

                zahlung1[ zahl] = zahlung1[ zahl]
                        + (faktorzahl * kostendifferenz[ zahl]);
                if( zahlung1[ zahl] > kostenmax[ zahl])
                    zahlung1[ zahl] = kostenmax[ zahl] + tzahlung + 100;

            } else
            {
                zahlung1[ zahl] = zahlung1[ zahl]
                        - (faktorzahl * kostendifferenz[ zahl]);

                if( zahlung1[ zahl] < 0)
                    zahlung1[ zahl] = 0;

            }
        }
        if( zwischen == true)
        {
            for( int x = 0; x < m_halbe; x++)
            {
                zahl = rand() % anzahl;
                addorsub = rand() % 2;
                if( addorsub == 1)
                {

                    zahlung1[ zahl] = zahlung1[ zahl] + 30;
                    if( zahlung1[ zahl] > kostenmax[ zahl])
                        zahlung1[ zahl] = kostenmax[ zahl] + tzahlung + 100;

                } else
                {

                    zahlung1[ zahl] = zahlung1[ zahl] - 20;

                    if( zahlung1[ zahl] < 0)
                        zahlung1[ zahl] = 0;

                }
            }
        }

//AfxMessageBox("vor Anzahl",MB_YESNO,0);
        if( besser == false)
        {
            for( int x = 0; x < m_halbe; x++)
            {
                meng = rand() % anzahl; //Zufallszahl zwischen 0 und anzahl an Massnahmen

                //double  faktormeng =  ((double)rand() / ((double)RAND_MAX ));//Zufallszahl zwischen 0 und 1
                if( max_flaeche[ meng] != 0)
                {

                    mengeneu[ meng] = rand() % max_flaeche[ meng];

                } else
                    mengeneu[ meng] = 0;

            }
        } else
        {
            meng = rand() % anzahl;
            addorsub = rand() % 2;
            if( max_flaeche[ meng] != 0)
            {
                //mengeneu[meng] =  rand() % max_flaeche[meng];	
                if( addorsub == 1)
                    mengeneu[ meng] = max_flaeche[ meng];
                else
                    mengeneu[ meng] = 0;
            } else
                mengeneu[ meng] = 0;
        }

        //AfxMessageBox("neue Anzahl",MB_YESNO,0);
        //str.Format(_T("%.2f"),faktormeng);
        //AfxMessageBox(str,MB_YESNO,0);

        for( i = 0; i < anzahl; i++)
        {
            if( !massnahmenergebvector2[ i].empty())
            {
                for( mp = massnahmenergebvector2[ i].begin();
                        mp < massnahmenergebvector2[ i].end(); mp++)
                {
                    (*mp).gewinn = (*mp).kosten + zahlung1[ i] - tzahlung; // die neue Zahlung muss dazu addiert werden
                    (*mp).m.zahlung = zahlung1[ i];
                }
            }
            //else
            //AfxMessageBox("Keine Pixel",MB_YESNO,0);

            mapixelliste_mit_pos mmp;
            mmp.massnahmenergebnis = massnahmenergebvector2[ i];
            mmp.position = 0;
            pixellisten_mit_position2.push_back( mmp);
            pixelpromassnahme2.push_back( 0);

        }
        ges_ausgabe2 = gesammtkosten( pixellisten_mit_position2,
                ergebnisliste_neu, artflaeche2, mengeneu, pixelpromassnahme2,
                zeilen, spalten, anzahl_arten);
        double gesflaeche2 = 0;
        for( int a = 0; a < anzahl_arten; a++)
        {

            gesflaeche2 = artflaeche2[ a] * gewichte[ a];
        }

        bool bok;

        if( (ges_ausgabe2 > budget))
            bok = false;
        else
            bok = true;

        //double ausgabendiff = ges_ausgabe1 - ges_ausgabe2;
        double qualdiff = gesflaeche2 - gesflaeche1;
        if( (qualdiff > 0) && bok)
        {
            ergebnisliste_alt = ergebnisliste_neu;
            artflaeche1 = artflaeche2;
            pixelpromassnahme1 = pixelpromassnahme2;
            ges_ausgabe1 = ges_ausgabe2;
            zahlung0 = zahlung1;
            menge1 = mengeneu;
            gesflaeche1 = gesflaeche2;
            penalty1 = penalty2;
            penaltyfaktor1 = penaltyfaktor2;
            //missingflaeche1 = missingflaeche2;
            besser = true;
            zwischen = false;
            n = 0;
            // AfxMessageBox("Die neue ist günstiger",MB_YESNO,0);
        } else
        {
            if( bok)
            {
                double a = (double( rand()) / ((double) RAND_MAX)); // produces a random number in [0,1]

                double b = exp( qualdiff / T);

                if( b > a)
                {
                    ergebnisliste_alt = ergebnisliste_neu;
                    artflaeche1 = artflaeche2;
                    pixelpromassnahme1 = pixelpromassnahme2;
                    ges_ausgabe1 = ges_ausgabe2;
                    zahlung0 = zahlung1;
                    menge1 = mengeneu;
                    gesflaeche1 = gesflaeche2;
                    penalty1 = penalty2;
                    penaltyfaktor1 = penaltyfaktor2;
                    //missingflaeche1 = missingflaeche2;
                    besser = false;
                    zwischen = true;
                    n = 0;
                    //AfxMessageBox("bin in dem b>a Zweig ",MB_YESNO,0);

                } else
                {
                    besser = false;
                    zwischen = false;
                    n++;
                }
            } else
            {
                besser = false;
                zwischen = false;
                n++;
            }
        }
        if( ((gesflaeche_best < gesflaeche1) || (ges_ausgabe_best > budget))
                && (ges_ausgabe1 < budget))
        {

            gesflaeche_best = gesflaeche1;
            artflaeche_best = artflaeche1;
            ergebnisliste_best = ergebnisliste_alt;
            pixelpromassnahmebest = pixelpromassnahme1;
            mengebest = menge1;
            zahlungbest = zahlung0;
        }

        T = T * 0.999;//9999; //99; //Abkühlung
        k++;
        bloob++;
        //penalty2 = 0;
        //penaltyfaktor2=0;

        ergebnisliste_neu.clear();

    }
    str.Format( _T( "%d"), bloob);
    AfxMessageBox( str, MB_YESNO, 0);

    // AfxMessageBox("bin hinter der Optimierung",MB_YESNO,0);

    (*ergeb).artenflaechen = artflaeche_best;
    (*ergeb).massnahmenergebnis = ergebnisliste_best;
    (*ergeb).masspixel = pixelpromassnahmebest;
    (*ergeb).mengen = mengebest;
    (*ergeb).zahlung = zahlungbest;

    return (*ergeb);

}

////////////////////////////////
double simulation::gesammtkosten(
        vector< struct mapixelliste_mit_pos>& mpos,
        vector< modell::masspixelergeb>& ergebnis,
        vector< double>& artflaechen,
        vector< int>& menge,
        vector< int>& pixelproma,
        int zeilen,
        int spalten,
        int anzahl_arten)
{
    bool** modelliert;
    //modelliert[zeilen][spalten];
    int i, j;
    //AfxMessageBox("In Gesammtkosten1",MB_YESNO,0);

    modelliert = new bool*[ zeilen];
    for( i = 0; i < zeilen; i++)
        modelliert[ i] = new bool[ spalten];
    for( i = 0; i < zeilen; i++)
    {

        for( j = 0; j < spalten; j++)
        {
            modelliert[ i][ j] = false;
        }

    }

    masnahmen_position maspos;
    maspos.mas = 0;
    maspos.pos = 0;
    double ges_ausgabe = 0;

    for( int ai = 0; ai < anzahl_arten; ai++)
    {
        artflaechen[ ai] = 0;
    }
    //AfxMessageBox("In Gesammtkosten",MB_YESNO,0);

    while( (maspos.mas != -99) && (maspos.pos != -99)) //nur solange es noch Pixel gibt mit positivem Gewinn 
    {
        maspos = calculate_best_massnahme( mpos, menge, pixelproma);
        int m = maspos.mas;
        int p = maspos.pos;
        if( (m >= 0) && (p >= 0)) // es gibt ein positives Pixel -> übertrage es in die Ergebnismatrix falls nicht schon besetzt
        {

            i = mpos[ m].massnahmenergebnis[ p].matrix_i;
            j = mpos[ m].massnahmenergebnis[ p].matrix_j;
            //int anzahl =  mpos[m].massnahmenergebnis[p].artenq.size();

            if( (modelliert[ i][ j]) == false) // der Pixel ist noch nicht vergeben -> die Artenflächen und die Budgetausgaben anpassen
            {
                for( int ai = 0; ai < anzahl_arten; ai++)
                {
                    artflaechen[ ai] = artflaechen[ ai]
                            + (mpos[ m].massnahmenergebnis[ p].artenq[ ai]
                                    .qualitaet * 6.25);
                }
                ges_ausgabe = ges_ausgabe
                        + mpos[ m].massnahmenergebnis[ p].m.zahlung;
                //CString str;
                //AfxMessageBox("Gesammtausgabe",MB_YESNO,0);
                //str.Format(_T("%.2f"),ges_ausgabe);
                //AfxMessageBox(str,MB_YESNO,0);
                pixelproma[ m] = pixelproma[ m] + 1;
                modelliert[ i][ j] = true;
                //modell::masspixelergeb * er;
                //er = new modell::masspixelergeb ;
                //(*er) = mpos[m].massnahmenergebnis[p];
                //ergebnis.push_back((*er));//Das modelierte Pixel in die Liste schieben
                ergebnis.push_back( mpos[ m].massnahmenergebnis[ p]);
            }
            mpos[ m].position = p + 1; // die Position eins weiter setzen egal ob benutzt oder nicht

        }
    }
//AfxMessageBox("In Gesammtkosten fertig",MB_YESNO,0);
    for( i = 0; i < zeilen; i++)
    {

        for( j = 0; j < spalten; j++)
        {
            modelliert[ i][ j] = false;
        }

    }

    for( i = 0; i < zeilen; i++)
    {

        delete[] modelliert[ i];
    }

    delete[] modelliert;
    /*
     CString str;
     AfxMessageBox("Gesammtausgabe",MB_YESNO,0);
     str.Format(_T("%.2f"),ges_ausgabe);
     AfxMessageBox(str,MB_YESNO,0);*/
    return (ges_ausgabe * 6.25);

}








        
simulation::masnahmen_position simulation::calculate_best_massnahme(
        vector< simulation::mapixelliste_mit_pos>& mmp,
        vector< int>& menge,
        vector< int>& pixelproma)
{
    int anzahl = mmp.size();
    double gewinn = 0;
    simulation::masnahmen_position mapo;
    mapo.mas = -99;
    mapo.pos = -99;
    vector< simulation::mapixelliste_mit_pos>::iterator pointer;
    int i = 0;
    for( pointer = mmp.begin(); pointer != mmp.end(); pointer++)
    {
        int az = mmp[ i].massnahmenergebnis.size();
        int pos = mmp[ i].position;
        if( az > 0) //Die Liste ist nicht leer
        {
            if( (pos < az) && (pixelproma[ i] < menge[ i])) // Mann ist weder am Ende der Liste, noch ist die max Anzahl erreicht
            {
                if( mmp[ i].massnahmenergebnis[ pos].gewinn >= 0)
                {

                    if( mmp[ i].massnahmenergebnis[ pos].gewinn > gewinn) //Der Gewinn muss positiv sein und größer als bisheriger
                    {
                        mapo.mas = i;
                        mapo.pos = pos;
                        gewinn = mmp[ i].massnahmenergebnis[ pos].gewinn;
                        /*CString str;
                         AfxMessageBox("Gewinn in calculate",MB_YESNO,0);
                         str.Format(_T("%.2f"),gewinn);
                         AfxMessageBox(str,MB_YESNO,0);*/
                    }
                    if( mmp[ i].massnahmenergebnis[ pos].gewinn == gewinn) // wenn gleich werfe Münze ob annehmen oder nicht
                    {
                        int a;
                        a = rand() % 2; //modulo 2, es kommt also nur eine 0 oder 1 zurück
                        if( a != 0)
                        {
                            mapo.mas = i;
                            mapo.pos = pos;
                        }
                    }
                }
            }
        }
        i++;
    }

    return mapo;
}

//////






//*********************************************
//Neue Optimierungsalgorithmen
simulation::ergebnis simulation::maximiereEffFlaeche( 
			int tzahlung,
            vector< art*>& artlist,
            vector< massnahme>& mliste,
            vector< double>& gewichte,
            vector< double>& minqualitaet,
            int budget,
            bool zahlung,
            int zeilen,
            int spalten,
            int bundeslandID,
            bool hoch,
            bool egal)
{
	//Berechnen des Modells
	int anzahl_arten = artlist.size();   
    int anzMass = mliste.size();
    vector < vector < modell::masspixelergeb >> massnahmenergebvector_ANF(anzMass);
	modell mod;
    mod.calculate_oekologiemodell( artlist, mliste, minqualitaet,
            massnahmenergebvector_ANF, bundeslandID, hoch, egal);
	sortiereMassnahmenlisten(massnahmenergebvector_ANF);

	vector<int> AnzPixel = berechneAnzPixel(massnahmenergebvector_ANF);
	int M_greifend = bestimmeAnzahlGreifMass(AnzPixel);

	//Bestimmen einer Anfangsloesung
	vector< double> zahlungen; //speichert für jede Massnahme die Zahlung;
    vector< int> flaechen; //speichert für jede Massnaheme die Fläche = Anzahl an Pixel für die die Massnahme angewendet werden darf
  
	vector< double> artflaeche = NullvektorDouble(anzahl_arten); //Wird die Fläche nach der Modellierung für jede Art erfassen jetzt erst mal initialisieren

	vector< simulation::mapixelliste_mit_pos> pixellisten_mit_position;
    vector< modell::masspixelergeb> ergebnisliste;
	vector< int> pixelpromassnahme; 

	//CString str;
	//str.Format("AnzMass=%d, AnzGreifMass=%d", anzMass, M_greifend);
	//AfxMessageBox(str);


	if(M_greifend == 1)//Aufgabe kann optimal geloest werden
	{
		//AfxMessageBox("Nur eine greifende Massnahme");
		int m;//greifende Massnahme
		//Welche Massnahme greift?
		for(int i=0; i<anzMass; i++)
		{
			if(AnzPixel[i] > 0)
				m = i;
		}

		//Ausschoepfendes Pixel bestimmen.
		int INDEX = bestimmeIndexAusschoepfendesPixel(double(budget), 
													  tzahlung,
													  0,
													  massnahmenergebvector_ANF[m]);


		zahlungen = NullvektorDouble(anzMass);
		flaechen = NullvektorInt(anzMass);
		if(INDEX >= 0)
		{		
			zahlungen[m] = berZahlung(massnahmenergebvector_ANF[m][INDEX], tzahlung, 0);
			flaechen[m] = INDEX+1;
		}
		else
		{//Budget zu niedrig
			zahlungen[m] = 0;//eigentlich überflüssig
			flaechen[m] = 0;
		}			

		klaereFormalitaeten(zahlungen, 
							tzahlung,
							massnahmenergebvector_ANF, 
							pixellisten_mit_position,
							pixelpromassnahme);
		//Simulation der optimalen Loesung
		double gesKosten = gesammtkosten(
				pixellisten_mit_position, 
				ergebnisliste,
				artflaeche, 
				flaechen, 
				pixelpromassnahme, 
				zeilen, 
				spalten,
				anzahl_arten);
		double gesFlaeche = 0;  
		for( int a = 0; a < anzahl_arten; a++)//Berechnen der Gesamtflaeche
			gesFlaeche = gesFlaeche + artflaeche[a] * gewichte[a];

		/*
		str.Format("Kosten = %f", gesKosten);
		AfxMessageBox(str);

		zeigeVektor(pixelpromassnahme);
		zeigeVektor(artflaeche);
		*/

	}
	else if(M_greifend > 1)
	{//per Heuristik wird Anfangsloesung bestimmt und verbessert	
		HeurMFBudgetwichtung(zahlungen, 
							flaechen, 
						   _T("MaxErrEffGew=12"),
						   _T("AnteilKostendifferenz"),
						    gewichte,
							0.35,									
							budget,
							tzahlung,
							massnahmenergebvector_ANF,
							pixellisten_mit_position,
							ergebnisliste,
							pixelpromassnahme);
	
		//Simulation der Anfangsloesung
		double gesKosten = gesammtkosten(
					pixellisten_mit_position, 
					ergebnisliste,
					artflaeche, 
					flaechen, 
					pixelpromassnahme, 
					zeilen, 
					spalten,
					anzahl_arten);
		double gesFlaeche = 0;  
		for( int a = 0; a < anzahl_arten; a++)//Berechnen der Gesamtflaeche
			gesFlaeche = gesFlaeche + artflaeche[a] * gewichte[a];

		
	
		//Verbessern der Anfangsloesung
		int anzIt = 5000;
		double AnfTemp = berechneAnfangstemperatur(gesFlaeche, 0.0000001);
		verbessere( anzIt,//Mit lokaler Nachbarschaftsvariante
					AnfTemp,
					zahlungen,
					flaechen,
					gesFlaeche,
					gesKosten,
					tzahlung,
					mliste,
					gewichte,
					budget,
					anzahl_arten,
					zeilen,
					spalten,
					artflaeche,
					massnahmenergebvector_ANF,
					pixellisten_mit_position,
					ergebnisliste,
					pixelpromassnahme);
	}

	ergebnis *ergeb;
    ergeb = new ergebnis;
    (*ergeb).artenflaechen = artflaeche;
    (*ergeb).massnahmenergebnis = ergebnisliste;
    (*ergeb).masspixel = pixelpromassnahme;
    (*ergeb).mengen = flaechen;
    (*ergeb).zahlung = zahlungen;
	return *ergeb;
}



void simulation::verbessere(
			int anzIt,
			double AnfTemp,
			vector<double> &zahlungenAkt,
			vector<int> &flaechenAkt,
			double &erreichteFlaeche,
			double &erreichteAusgabe,
			int tzahlung,
			vector< massnahme>& mliste,
            vector< double>& gewichte,
			int budget,
			int anzahl_arten,
			int zeilen,
            int spalten,
			vector<double> &artflaecheAkt,
			vector<vector<modell::masspixelergeb>> &massnahmenergebvectorAkt,
			vector<simulation::mapixelliste_mit_pos> &pixellisten_mit_positionAkt,
			vector< modell::masspixelergeb> &ergebnislisteAkt,
			vector<int> &pixelpromassnahmeAkt)
{

    vector<double>  zahlungenVar, zahlungenBest; //speichert für jede Massnahme die Zahlung;
	zahlungenBest = zahlungenAkt;//Uebergeben der Anfangsloesung

    vector<int> flaechenVar, flaechenBest; //speichert für jede Massnaheme die Fläche = Anzahl an Pixel für die die Massnamhe angewendet werden darf
	flaechenBest = flaechenAkt;

	double ausgabeAkt, ausgabeVar, ausgabeBest;
	ausgabeAkt = erreichteAusgabe;
	ausgabeBest = erreichteAusgabe;

	double gesflaecheAkt, gesflaecheVar, gesflaecheBest;
	gesflaecheAkt = erreichteFlaeche;
	gesflaecheBest = erreichteFlaeche;

	vector<double> artflaecheVar, artflaecheBest;
	artflaecheBest = artflaecheAkt;

	int anzMass = massnahmenergebvectorAkt.size();
	vector<int> AnzPixel = berechneAnzPixel(massnahmenergebvectorAkt);
	int greifende_massnahmen = 0;
	for(int i=0; i<anzMass; i++)
	{
		if( AnzPixel[i] > 0)
			greifende_massnahmen++;
	}

	vector<vector<modell::masspixelergeb>> massnahmenergebvectorVar;
	    
    vector<simulation::mapixelliste_mit_pos> pixellisten_mit_positionVar, pixellisten_mit_positionBest;
    vector<modell::masspixelergeb> ergebnislisteVar, ergebnislisteBest;

	ergebnislisteBest = ergebnislisteAkt;
    
    vector<int> pixelpromassnahmeVar, pixelpromassnahmeBest;
	pixelpromassnahmeBest = pixelpromassnahmeAkt;

    vector<double> kostendifferenz = berechneKostendifferenzAst(massnahmenergebvectorAkt);
	
	//Parametrisierung meiner Variante(n)
	 vector<double> minAbweichungZahlung(anzMass);
	 vector<double> maxAbweichungZahlung(anzMass);
	 vector<int> minAnzahlAbweichungFlaeche = NullvektorInt(anzMass);
	 vector<int> maxAnzahlAbweichungFlaeche(anzMass);
	 int maxAnzahlVeraenderterMass;
	 vector<vector<double>> Sprungstufen;

	 double fakAnzMass;
	 double fakZahlung ;
	 double fakPixel;
	 fakAnzMass = 0.2;
	 fakZahlung = 0.1;
	 fakPixel = 0.05;
	
	 maxAnzahlVeraenderterMass = max(1, static_cast<int>( fakAnzMass * greifende_massnahmen) );

	 for(int i=0; i<anzMass; i++)
	 {
		 minAbweichungZahlung[i] = 0.1;
		 maxAbweichungZahlung[i] = max(fakZahlung*kostendifferenz[i], 0.1);
		 maxAnzahlAbweichungFlaeche[i] = max(1 , static_cast<int>( fakPixel*AnzPixel[i]) );
	 }
		
	
    double T = AnfTemp; //Anzahl der Kombinationen um Zahlungen und oder Mengen zu ändern und alle noch mal 1000
	double TAbb = 0.005;
    int k = 1; //Zähler für die Iterationen
    bool besser = false;
    bool zwischen = false;

	double alpha = calcAlpha(anzIt, AnfTemp, TAbb);//Fuer geometrische Temperaturfolge
	
	while( T > TAbb)
    {
		
        artflaecheVar = NullvektorDouble(anzahl_arten);

		pixelpromassnahmeVar.clear();
		pixellisten_mit_positionVar.clear();
		ergebnislisteVar.clear();
   
        zahlungenVar = zahlungenAkt; //Die letzte beste Lösung
        flaechenVar = flaechenAkt; //Die letzte beste Lösung
		massnahmenergebvectorVar = massnahmenergebvectorAkt;
			
		variiereZahlungenFlaechen(zahlungenVar,
								  flaechenVar,
								  AnzPixel,
								  pixelpromassnahmeAkt,
								  maxAnzahlVeraenderterMass, 
								  minAbweichungZahlung,
								  maxAbweichungZahlung,
								  minAnzahlAbweichungFlaeche,
								  maxAnzahlAbweichungFlaeche,
								  tzahlung,
								  massnahmenergebvectorVar, 
								  pixellisten_mit_positionVar,
								  pixelpromassnahmeVar);
								  
		// 'Formalitaten' werden in der Variationsfunktion geklaert

        //Simulation der variierten Loesung
        ausgabeVar = gesammtkosten( pixellisten_mit_positionVar,
									ergebnislisteVar, artflaecheVar, flaechenVar, pixelpromassnahmeVar,
									zeilen, spalten, anzahl_arten);
        gesflaecheVar = 0;//Bestimmen der neuen Flaeche
        for( int a = 0; a < anzahl_arten; a++)
            gesflaecheVar = gesflaecheVar + artflaecheVar[a] * gewichte[a];

        bool bok = ausgabeVar <= budget;
        double qualdiff = gesflaecheVar - gesflaecheAkt;

        if( (qualdiff > 0) && bok)//Neue Loesung besser
        {
            ergebnislisteAkt = ergebnislisteVar;
            artflaecheAkt = artflaecheVar;
            pixelpromassnahmeAkt = pixelpromassnahmeVar;
            ausgabeAkt = ausgabeVar;
            zahlungenAkt = zahlungenVar;
            flaechenAkt = flaechenVar;
            gesflaecheAkt = gesflaecheVar;
            besser = true;
            zwischen = false;
            // AfxMessageBox("Die neue ist günstiger",MB_YESNO,0);
        } 
		else
        {
            if(bok)
            {
                double a = (double( rand()) / ((double) RAND_MAX)); // produces a random number in [0,1]
                double b = exp( qualdiff / T);

                if( b > a)//Neue Loesung wird beibehalten, obwohl sie schlechter ist
                { 
					ergebnislisteAkt = ergebnislisteVar;
					artflaecheAkt = artflaecheVar;
					pixelpromassnahmeAkt = pixelpromassnahmeVar;
					ausgabeAkt = ausgabeVar;
					zahlungenAkt = zahlungenVar;
					flaechenAkt = flaechenVar;
					gesflaecheAkt = gesflaecheVar;
                    besser = false;
                    zwischen = true;
              
                } else
                {
                    besser = false;
                    zwischen = false;
            
                }
            } 
			else
            {
                besser = false;
                zwischen = false;
               
            }
        }

		//Schauen, ob aktuelle Loesung besser ist als die Beste bisher gefundene
		bool flaecheUnveraendert = fabs(gesflaecheBest - gesflaecheAkt) <= 0.00000001;

		if( (gesflaecheBest < gesflaecheAkt && ausgabeAkt <= budget) ||
			(flaecheUnveraendert && ausgabeAkt < ausgabeBest))
        {
			ausgabeBest = ausgabeAkt;
            gesflaecheBest = gesflaecheAkt;
            artflaecheBest = artflaecheAkt;
            ergebnislisteBest = ergebnislisteAkt;
            pixelpromassnahmeBest = pixelpromassnahmeAkt;
            zahlungenBest = zahlungenAkt;
			flaechenBest = flaechenAkt;
        }
		
        k++;
		T = T * alpha;//Abkühlung, alpha wird vor der Schleife festgelegt (geometrische Folge)
    }

	erreichteFlaeche = gesflaecheBest;
	erreichteAusgabe = ausgabeBest;
	artflaecheAkt = artflaecheBest;
	pixelpromassnahmeAkt = pixelpromassnahmeBest;
	ergebnislisteAkt = ergebnislisteBest;
	zahlungenAkt = zahlungenBest;
	flaechenAkt = flaechenBest;

}


//Verbessert eine Anfangsloesung mit simulated annealing = eigentlicher simulated annealing Algorithmus
void simulation::verbessereTest(
			int anzIt,
			double AnfTemp,
			CString varianteVar,
			vector<double> &zahlungenAkt,
			vector<int> &flaechenAkt,
			double &erreichteFlaeche,
			double &erreichteAusgabe,
			int tzahlung,
			vector< massnahme>& mliste,
            vector< double>& gewichte,
			int budget,
			int anzahl_arten,
			int zeilen,
            int spalten,
			vector<double> &artflaecheAkt,
			vector<vector<modell::masspixelergeb>> &massnahmenergebvectorAkt,
			vector<simulation::mapixelliste_mit_pos> &pixellisten_mit_positionAkt,
			vector< modell::masspixelergeb> &ergebnislisteAkt,
			vector<int> &pixelpromassnahmeAkt)
{
	CString filename = _T("VariationTestProt.txt");
	schreibeInDatei(filename , _T("In 'verbessere'!"));
	CString str;
	str.Format("anzIt = %d", anzIt);
	schreibeInDatei(filename, str);

    vector<double>  zahlungenVar, zahlungenBest; //speichert für jede Massnahme die Zahlung;
	zahlungenBest = zahlungenAkt;//Uebergeben der Anfangsloesung

    vector<int> flaechenVar, flaechenBest; //speichert für jede Massnaheme die Fläche = Anzahl an Pixel für die die Massnamhe angewendet werden darf
	flaechenBest = flaechenAkt;

	double ausgabeAkt, ausgabeVar, ausgabeBest;
	ausgabeAkt = erreichteAusgabe;
	ausgabeBest = erreichteAusgabe;

	double gesflaecheAkt, gesflaecheVar, gesflaecheBest;
	gesflaecheAkt = erreichteFlaeche;
	gesflaecheBest = erreichteFlaeche;

	vector<double> artflaecheVar, artflaecheBest;
	artflaecheBest = artflaecheAkt;

	int anzMass = massnahmenergebvectorAkt.size();
	vector<int> AnzPixel = berechneAnzPixel(massnahmenergebvectorAkt);
	int greifende_massnahmen = 0;
	for(int i=0; i<anzMass; i++)
	{
		if( AnzPixel[i] > 0)
			greifende_massnahmen++;
	}

	vector<vector<modell::masspixelergeb>> massnahmenergebvectorVar;
	    
    vector<simulation::mapixelliste_mit_pos> pixellisten_mit_positionVar, pixellisten_mit_positionBest;
    vector<modell::masspixelergeb> ergebnislisteVar, ergebnislisteBest;

	ergebnislisteBest = ergebnislisteAkt;
    
    vector<int> pixelpromassnahmeVar, pixelpromassnahmeBest;
	pixelpromassnahmeBest = pixelpromassnahmeAkt;

	schreibeInDatei(filename , _T("Variablen angelegt und Anfangsloesung uebergeben."));
	//zeigeVektor(AnzPixel);
	//Werte fuer Astrids Variation
    vector<double> kostendifferenz = berechneKostendifferenzAst(massnahmenergebvectorAkt);
	//zeigeVektor(kostendifferenz);
    vector<double> kostenmax = berechneKostenmaxAst(massnahmenergebvectorAkt);
	//zeigeVektor(kostenmax);
	vector<int> max_flaeche = berechneMaxFlaecheAst(massnahmenergebvectorAkt, budget);
	//zeigeVektor(max_flaeche);

	//Parametrisierung meiner Variante(n)
	 vector<double> minAbweichungZahlung(anzMass);
	 vector<double> maxAbweichungZahlung(anzMass);
	 vector<int> minAnzahlAbweichungFlaeche = NullvektorInt(anzMass);
	 vector<int> maxAnzahlAbweichungFlaeche(anzMass);
	 int maxAnzahlVeraenderterMass;
	 vector<vector<double>> Sprungstufen;

	 double fakAnzMass;
	 double fakZahlung ;
	 double fakPixel;

	
	 if(varianteVar.Compare( _T("Meine1") ) == 0)//lokal
	 {
		 fakAnzMass = 0.2;
		 fakZahlung = 0.1;
		 fakPixel = 0.05;
	 }
	 else if( varianteVar.Compare( _T("Meine2") ) == 0)//globaler
	 {
		 fakAnzMass = 0.5;
		 fakZahlung = 1.0;
		 fakPixel = 0.2;
	 }
	 else if(varianteVar.Compare( _T("Stufen") ) == 0)
	 {
		 fakAnzMass = 0.5;
		 fakZahlung = 0;//egal
		 fakPixel = 0.05;
		 bestimmeSprungstufenZahlungen(Sprungstufen, 0.00000001, tzahlung, massnahmenergebvectorAkt);
	 }
	 else if( varianteVar.Compare( _T("Meine4")) == 0)//sehr lokal
	 {
		 fakAnzMass = 0.1;
		 fakZahlung = 0.02;
		 fakPixel = 0.005;
	 }

	 if(varianteVar.Compare( _T("Meine1") ) == 0 || 
		varianteVar.Compare( _T("Meine2")) == 0 || 
		varianteVar.Compare( _T("Stufen") ) == 0 || 
		varianteVar.Compare( _T("Meine4") ) == 0 )
	 {
		 maxAnzahlVeraenderterMass = max(1, static_cast<int>( fakAnzMass * greifende_massnahmen) );

		 str.Format("maxAnzahlVeraenderterMass=%d", maxAnzahlVeraenderterMass);
		 schreibeInDatei(filename, str);

		 for(int i=0; i<anzMass; i++)
		 {
			 minAbweichungZahlung[i] = 0.1;
			 maxAbweichungZahlung[i] = max(fakZahlung*kostendifferenz[i], 0.1);
			 maxAnzahlAbweichungFlaeche[i] = max(1 , static_cast<int>( fakPixel*AnzPixel[i]) );

			 str.Format("maxAbweichungZahlung=%f, maxAnzahlAbweichungFlaeche=%d", 
					maxAbweichungZahlung[i], maxAnzahlAbweichungFlaeche[i]);
			 schreibeInDatei(filename, str);
		 }
		
	 }
	 bool meine3 = varianteVar.Compare( _T("Meine3") ) == 0;


	schreibeInDatei(filename , _T("Variationsalgorithmen parametrisiert."));

    double T = AnfTemp; //Anzahl der Kombinationen um Zahlungen und oder Mengen zu ändern und alle noch mal 1000
	double TAbb = 0.005;
    int max_iteration = 100000000;
    int k = 1; //Zähler für die Iterationen
    int n = 0; // Zähler für Anzahl der Iterationen ohne Verbesserung des Ergebnisses
    int bloob = 0;
    bool besser = false;
    bool zwischen = false;

	double alpha = calcAlpha(anzIt, AnfTemp, TAbb);//Fuer geometrische Temperaturfolge
	double Basis = exp( log(AnfTemp-TAbb+1) / double(anzIt) );
	double Diff = (AnfTemp-TAbb)/anzIt;//Fuer arithmetische Temperatur

	int optID = 332;
	
	schreibeInDatei(filename , _T("Direkt vor der Verbesserungsschleife!"));

	/*
	datenbank *daten = new datenbank;
	daten->save_optimierungsfortgang(optID,0, 
									 AUPtoString(mliste, zahlungenAkt, flaechenAkt),
									 gesflaecheAkt, gesflaecheAkt, ausgabeAkt, AnfTemp, - 1);
	*/

    while( (T > TAbb) && (k < max_iteration) && (n != 100000))
    {
		 if(meine3)//linearer Verlauf
		 {
			 maxAnzahlVeraenderterMass = max(1, static_cast<int>
											( lineareFkt(k, 1, anzIt, 0.5 , 0.1 ) * greifende_massnahmen) );
			 for(int i=0; i<anzMass; i++)
			 {
				 minAbweichungZahlung[i] = 0.1;
				 maxAbweichungZahlung[i] = max( lineareFkt(k, 1, anzIt, 1 , 0.02 ) * kostendifferenz[i], 0.1);
				 maxAnzahlAbweichungFlaeche[i] = max(1, static_cast<int> 
											(lineareFkt(k, 1, anzIt, 0.2 , 0.005 ) * AnzPixel[i] ) );
			 }
		 }

        //AfxMessageBox("In der Optimierung",MB_YESNO,0);
        
        artflaecheVar = NullvektorDouble(anzahl_arten);

		pixelpromassnahmeVar.clear();
		pixellisten_mit_positionVar.clear();
		ergebnislisteVar.clear();
   
        zahlungenVar = zahlungenAkt; //Die letzte beste Lösung
        flaechenVar = flaechenAkt; //Die letzte beste Lösung
		massnahmenergebvectorVar = massnahmenergebvectorAkt;

		if(varianteVar.Compare( _T("Astrid") ) == 0)
		{
			variiereZahlungenFlaechenAstrid(zahlungenVar,
											flaechenVar,
											besser, zwischen,
											tzahlung,
											kostenmax,
											kostendifferenz,
											max_flaeche,
											massnahmenergebvectorVar, 
											pixellisten_mit_positionVar,
											pixelpromassnahmeVar);
		}
		else if(varianteVar.Find( _T("Meine") ) != -1)// varianteVar enthaelt "Meine"
		{
			
			variiereZahlungenFlaechen(zahlungenVar,
									  flaechenVar,
									  AnzPixel,
									  pixelpromassnahmeAkt,
									  maxAnzahlVeraenderterMass, 
									  minAbweichungZahlung,
									  maxAbweichungZahlung,
									  minAnzahlAbweichungFlaeche,
									  maxAnzahlAbweichungFlaeche,
									  tzahlung,
									  massnahmenergebvectorVar, 
									  pixellisten_mit_positionVar,
									  pixelpromassnahmeVar);
								  
		}
		else if(varianteVar.Compare( _T("Stufen") ) == 0)
		{
			variiereZahlungenFlaechenStufen(Sprungstufen,
											zahlungenVar,
											flaechenVar,
											AnzPixel,
											pixelpromassnahmeAkt,
											maxAnzahlVeraenderterMass,
											minAnzahlAbweichungFlaeche,
											maxAnzahlAbweichungFlaeche,
											tzahlung, 
											massnahmenergebvectorVar, 
											pixellisten_mit_positionVar,
											pixelpromassnahmeVar);
		}

		// 'Formalitaten' werden in der Variationsfunktion geklaert

        //Simulation der variierten Loesung
        ausgabeVar = gesammtkosten( pixellisten_mit_positionVar,
									ergebnislisteVar, artflaecheVar, flaechenVar, pixelpromassnahmeVar,
									zeilen, spalten, anzahl_arten);
        gesflaecheVar = 0;//Bestimmen der neuen Flaeche
        for( int a = 0; a < anzahl_arten; a++)
            gesflaecheVar = gesflaecheVar + artflaecheVar[a] * gewichte[a];

        bool bok = ausgabeVar <= budget;
        double qualdiff = gesflaecheVar - gesflaecheAkt;

        if( (qualdiff > 0) && bok)//Neue Loesung besser
        {
            ergebnislisteAkt = ergebnislisteVar;
            artflaecheAkt = artflaecheVar;
            pixelpromassnahmeAkt = pixelpromassnahmeVar;
            ausgabeAkt = ausgabeVar;
            zahlungenAkt = zahlungenVar;
            flaechenAkt = flaechenVar;
            gesflaecheAkt = gesflaecheVar;
            besser = true;
            zwischen = false;
            n = 0;
            // AfxMessageBox("Die neue ist günstiger",MB_YESNO,0);
        } 
		else
        {
            if(bok)
            {
                double a = (double( rand()) / ((double) RAND_MAX)); // produces a random number in [0,1]
                double b = exp( qualdiff / T);

                if( b > a)//Neue Loesung wird beibehalten, obwohl sie schlechter ist
                { 
					ergebnislisteAkt = ergebnislisteVar;
					artflaecheAkt = artflaecheVar;
					pixelpromassnahmeAkt = pixelpromassnahmeVar;
					ausgabeAkt = ausgabeVar;
					zahlungenAkt = zahlungenVar;
					flaechenAkt = flaechenVar;
					gesflaecheAkt = gesflaecheVar;
                    besser = false;
                    zwischen = true;
                    n = 0;//Wieso? Es fand doch keine Verbesserung statt
                    //AfxMessageBox("bin in dem b>a Zweig ",MB_YESNO,0);

                } else
                {
                    besser = false;
                    zwischen = false;
                    n++;
                }
            } 
			else
            {
                besser = false;
                zwischen = false;
                n++;
            }
        }

		//Schauen, ob aktuelle Loesung besser ist als die Beste bisher gefundene
		bool flaecheUnveraendert = fabs(gesflaecheBest - gesflaecheAkt) <= 0.00000001;

		if( (gesflaecheBest < gesflaecheAkt && ausgabeAkt <= budget) ||
			(flaecheUnveraendert && ausgabeAkt < ausgabeBest))
        {
			ausgabeBest = ausgabeAkt;
            gesflaecheBest = gesflaecheAkt;
            artflaecheBest = artflaecheAkt;
            ergebnislisteBest = ergebnislisteAkt;
            pixelpromassnahmeBest = pixelpromassnahmeAkt;
            zahlungenBest = zahlungenAkt;
			flaechenBest = flaechenAkt;
        }
		double Wkt;
		if(qualdiff<=0 && bok)//Schlechteres AUP kann akzeptiert werden
			Wkt = exp(qualdiff/T);
		else if(qualdiff>0 && bok)//Loesung wurde sowieso uebernommen
			Wkt = -1;
		else 
			Wkt = -2;
			
		/*
		daten->save_optimierungsfortgang(optID, k, 
										 AUPtoString(mliste, zahlungenAkt, flaechenAkt),
										 gesflaecheAkt, gesflaecheBest, ausgabeAkt, T, Wkt);
		 */
	
        k++;
		T = T * alpha;//Abkühlung, alpha wird vor der Schleife festgelegt (geometrische Folge)
		//T = AnfTemp - pow(Basis, k)+1;
		//T = AnfTemp - k*Diff; //arithmetisch

    }

	erreichteFlaeche = gesflaecheBest;
	erreichteAusgabe = ausgabeBest;
	artflaecheAkt = artflaecheBest;
	pixelpromassnahmeAkt = pixelpromassnahmeBest;
	ergebnislisteAkt = ergebnislisteBest;

	schreibeInDatei(filename , _T("Verbesserung durchgefuehrt!"));
    // AfxMessageBox("bin hinter der Optimierung",MB_YESNO,0);
}


//Diese Funktion ist zum Testen von Anfangsheuristiken gedacht fuer die 
// Maximierung der Flaeche.
simulation::ergebnis simulation::testeAnfHeurMaxFlaeche(
		int tzahlung,
		vector< art*>& artlist,
		vector< massnahme>& mliste,
		vector< double>& gewichte,
		vector< double>& minqualitaet,
		int budget,
		bool zahlung,
		int zeilen,
		int spalten,
		int bundeslandID,
		bool hoch,
		bool egal)
{
	srand( (unsigned) time(NULL) ) ; 

	/*
	testeVariationStatistisch(100);
	exit(0);
	*/
	
	
	testeAnfHeurMaxFlaecheStatistisch(150);
	exit(0);
		
	
	/*
	testeIterationszahlStatistisch(50);
	exit(0);
	*/
	
    int anzahl_arten = artlist.size();
   
    int anzMass = mliste.size();
    vector < vector < modell::masspixelergeb >> massnahmenergebvector_ANF( anzMass);
    vector < vector < modell::masspixelergeb >> massnahmenergebvector_ARBEIT( anzMass);

    //die Modellierung erfolgt nun
	modell mod;
    mod.calculate_oekologiemodell( artlist, mliste, minqualitaet,
            massnahmenergebvector_ANF, bundeslandID, hoch, egal);
    //AfxMessageBox("Nach der Modelierung",MB_YESNO,0);

	//Sortieren des massnahmenergebvectors 
	sortiereMassnahmenlisten(massnahmenergebvector_ANF);
	massnahmenergebvector_ARBEIT = massnahmenergebvector_ANF;

	vector< double> zahlungen; //speichert für jede Massnahme die Zahlung;
    vector< int> flaechen; //speichert für jede Massnaheme die Fläche = Anzahl an Pixel für die die Massnamhe angewendet werden darf
  
	vector< double> artflaeche = NullvektorDouble(anzahl_arten); //Wird die Fläche nach der Modelierung für jede Art erfassen jetzt erst mal initialisieren

	vector<double> kostendifferenz;
    vector<double> kostenmax;
	vector<int> max_flaeche;

	vector< simulation::mapixelliste_mit_pos> pixellisten_mit_position;
    vector< modell::masspixelergeb> ergebnisliste;
	vector< int> pixelpromassnahme; 

	vector<int> AnzPixel = berechneAnzPixel(massnahmenergebvector_ANF);
	int M_greifend = bestimmeAnzahlGreifMass(AnzPixel);

	int anzHeur = 11;
	for(int i=3; i<4; i++)
	//for(int i=0; i<anzHeur; i++)
	{
		switch(i)
		{
		case 0://Berechnen einer Anfangsloesung, so wie es am Anfang funktionierte.
			HeurMFAstrid(	zahlungen, 
							flaechen, 
							kostendifferenz,
							kostenmax,
							max_flaeche,
							budget,
							tzahlung,
							massnahmenergebvector_ARBEIT,
							pixellisten_mit_position,
							ergebnisliste,
							pixelpromassnahme);
			break;
		case 1:					
			HeurSukWP(	zahlungen, 
						flaechen, 
						budget,
						tzahlung,
						200,
						_T("Pixel"),
						gewichte,
						massnahmenergebvector_ARBEIT,
						pixellisten_mit_position,
						ergebnisliste,
						pixelpromassnahme);
			break;
		case 2:					
			HeurSukWP(	zahlungen, 
						flaechen, 
						budget,
						tzahlung,
						200,
						_T("Global"),
						gewichte,
						massnahmenergebvector_ARBEIT,
						pixellisten_mit_position,
						ergebnisliste,
						pixelpromassnahme);
			break;
		case 3:	
			HeurMFBudgetwichtung(zahlungen, 
								flaechen, 
							   //_T("MaxErrEffFlaeche"),
							    _T("MaxErrEffGew=500"),
							   _T("AnteilKostendifferenz"),
							    gewichte,
								0.4,									
								budget,
								tzahlung,
								massnahmenergebvector_ARBEIT,
								pixellisten_mit_position,
								ergebnisliste,
								pixelpromassnahme);
			break;
		case 4:
			HeurMFBudgetwichtung(zahlungen, 
					    flaechen, 
					   _T("MaxErrEffFlaeche"),
					   _T("Pauschal"),
					    gewichte,
					    30,									
						budget,
						tzahlung,
						massnahmenergebvector_ARBEIT,
						pixellisten_mit_position,
						ergebnisliste,
						pixelpromassnahme);
			break;
		case 5:
			HeurMFBudgetwichtung(zahlungen, 
					    flaechen, 
					   _T("MaxErrEffFlaeche"),
					   _T("AngleichungKostendifferenz"),
					    gewichte,
					    1.5,									
						budget,
						tzahlung,
						massnahmenergebvector_ARBEIT,
						pixellisten_mit_position,
						ergebnisliste,
						pixelpromassnahme);
			break;
		case 6:
			HeurMFBudgetwichtung(zahlungen, 
					    flaechen, 
					   _T("MaxErrEff"),
					   _T("AnteilKostendifferenz"),
					    gewichte,
					    0.15,									
						budget,
						tzahlung,
						massnahmenergebvector_ARBEIT,
						pixellisten_mit_position,
						ergebnisliste,
						pixelpromassnahme);
			break;
		case 7:
			HeurMFBudgetwichtung(zahlungen, 
					    flaechen, 
					   _T("MaxErrEff"),
					   _T("Pauschal"),
					    gewichte,
					    30,									
						budget,
						tzahlung,
						massnahmenergebvector_ARBEIT,
						pixellisten_mit_position,
						ergebnisliste,
						pixelpromassnahme);
			break;
		case 8:
			HeurMFBudgetwichtung(zahlungen, 
					    flaechen, 
					   _T("MaxErrEff"),
					   _T("AngleichungKostendifferenz"),
					    gewichte,
					    1.5,									
						budget,
						tzahlung,
						massnahmenergebvector_ARBEIT,
						pixellisten_mit_position,
						ergebnisliste,
						pixelpromassnahme);
			break;
		case 9:
			HeurMFBudgetwichtungOhneKonku(zahlungen, 
										flaechen, 
										_T("MaxErrEffFlaeche"),
										gewichte,
										budget,
										tzahlung,
										massnahmenergebvector_ARBEIT,
										pixellisten_mit_position,
										ergebnisliste,
										pixelpromassnahme);
			break;
		case 10:
			HeurMFBudgetwichtungOhneKonku(zahlungen, 
										flaechen, 
										_T("MaxErrEff"),
										gewichte,
										budget,
										tzahlung,
										massnahmenergebvector_ARBEIT,
										pixellisten_mit_position,
										ergebnisliste,
										pixelpromassnahme);
			break;

		}
	
		double ges_ausgabe = gesammtkosten( //Simulation des AUP
					pixellisten_mit_position, 
					ergebnisliste,
					artflaeche, 
					flaechen, 
					pixelpromassnahme, 
					zeilen, 
					spalten,
					anzahl_arten);
		//AfxMessageBox("Lösung Astrid simuliert.",MB_YESNO,0);

		double gesflaeche = 0;  
		for( int a = 0; a < anzahl_arten; a++)//Berechnen der Gesamtflaeche
		{
			gesflaeche = gesflaeche + artflaeche[ a] * gewichte[ a];
		}

		datenbank *daten = new datenbank;
		//zeigeAUP(mliste, zahlungen_Astrid, flaechen_Astrid); 
		/*
		daten->save_optimierungsfortgang(-111,	0, 
											AUPtoString(mliste, zahlungen, flaechen),
											gesflaeche,
											-1,
											ges_ausgabe, -1, -1);
										*/
		delete daten;
	
		massnahmenergebvector_ARBEIT = massnahmenergebvector_ANF;
		pixellisten_mit_position.clear();
		ergebnisliste.clear();
		pixelpromassnahme.clear();
		ges_ausgabe = 0;
		gesflaeche = 0;

	}

	ergebnis *ergeb;
    ergeb = new ergebnis;
    (*ergeb).artenflaechen = artflaeche;
    (*ergeb).massnahmenergebnis = ergebnisliste;
    (*ergeb).masspixel = pixelpromassnahme;
    (*ergeb).mengen = flaechen;
    (*ergeb).zahlung = zahlungen;

    return (*ergeb);
}



simulation::ergebnis simulation::testeSensitivitaetVerschiedenerAnfTemp(
		int tzahlung,
		vector< art*>& artlist,
		vector< massnahme>& mliste,
		vector< double>& gewichte,
		vector< double>& minqualitaet,
		int budget,
		bool zahlung,
		int zeilen,
		int spalten,
		int bundeslandID,
		bool hoch,
		bool egal)
{

	int anzahl_arten = artlist.size();
   
    int anzMass = mliste.size();
    vector < vector < modell::masspixelergeb >> massnahmenergebvector_ANF( anzMass);
    vector < vector < modell::masspixelergeb >> massnahmenergebvector_ARBEIT( anzMass);

    //die Modellierung erfolgt nun
	modell mod;
    mod.calculate_oekologiemodell( artlist, mliste, minqualitaet,
            massnahmenergebvector_ANF, bundeslandID, hoch, egal);
    //AfxMessageBox("Nach der Modelierung",MB_YESNO,0);

	//Sortieren des massnahmenergebvectors 
	sortiereMassnahmenlisten(massnahmenergebvector_ANF);
	massnahmenergebvector_ARBEIT = massnahmenergebvector_ANF;

	vector< double> zahlungen_ANF; //speichert für jede Massnahme die Zahlung;
    vector< int> flaechen_ANF; //speichert für jede Massnaheme die Fläche = Anzahl an Pixel für die die Massnamhe angewendet werden darf
  
	vector< double> artflaeche = NullvektorDouble(anzahl_arten); //Wird die Fläche nach der Modelierung für jede Art erfassen jetzt erst mal initialisieren

	vector<double> kostendifferenz;
    vector<double> kostenmax;
	vector<int> max_flaeche;

	vector< simulation::mapixelliste_mit_pos> pixellisten_mit_position;
    vector< modell::masspixelergeb> ergebnisliste;
	vector< int> pixelpromassnahme; 

	vector<int> AnzPixel = berechneAnzPixel(massnahmenergebvector_ANF);
	int M_greifend = bestimmeAnzahlGreifMass(AnzPixel);
	HeurMFBudgetwichtung(zahlungen_ANF, 
					    flaechen_ANF, 
					   _T("MaxErrEff"),
					   _T("AnteilKostendifferenz"),
					    gewichte,
					    0.45,									
						budget,
						tzahlung,
						massnahmenergebvector_ARBEIT,
						pixellisten_mit_position,
						ergebnisliste,
						pixelpromassnahme);
	double AnfKosten = gesammtkosten( //Simulation des AUP
					pixellisten_mit_position, 
					ergebnisliste,
					artflaeche, 
					flaechen_ANF, 
					pixelpromassnahme, 
					zeilen, 
					spalten,
					anzahl_arten);
	
	double AnfFlaeche = 0;  
	for( int a = 0; a < anzahl_arten; a++)//Berechnen der Gesamtflaeche
	{
		AnfFlaeche = AnfFlaeche + artflaeche[ a] * gewichte[ a];
	}

	int anzIt = 2000;
	int anzWiederholungen = 100;

	CString help;

	vector<CString> name;
	vector<double> AnfTemp;
	AnfTemp.push_back(double( anzMass *  10000000) );
	help.Format("%f",AnfTemp.back());
	name.push_back("Astrid Temp=" + help);

	AnfTemp.push_back( berechneAnfangstemperatur(AnfFlaeche, 0.33) );
	help.Format("%f",AnfTemp.back());
	name.push_back("Temp=" + help);

	AnfTemp.push_back( berechneAnfangstemperatur(AnfFlaeche, 0.01) );
	help.Format("%f",AnfTemp.back());
	name.push_back("Temp=" + help);

	AnfTemp.push_back( berechneAnfangstemperatur(AnfFlaeche, 0.0001) );
	help.Format("%f",AnfTemp.back());
	name.push_back("Temp=" + help);

	AnfTemp.push_back( berechneAnfangstemperatur(AnfFlaeche, 0.0000001) );
	help.Format("%f",AnfTemp.back());
	name.push_back("Temp=" + help);

	int anzTemp = name.size();
	vector<vector<double>> DeltaFlaechen(anzWiederholungen);//Speicherung der Ergebnisse
	vector<CString> test;
	for(int i=0; i<anzWiederholungen; i++)
	{
		DeltaFlaechen[i] = NullvektorDouble(anzTemp);
		test.push_back( toString(mliste) );
	}
	
	CString varianteVar = "Meine1";

	for(int k=0; k<anzTemp; k++)//Durchlaufen der Temperaturen
	{
		for(int i=0 ;i<anzWiederholungen; i++)
		{
			double erreichteFlaeche = AnfFlaeche;
			double erreichteKosten = AnfKosten;
			vector<double> zahlungen_ARBEIT = zahlungen_ANF;
			vector<int> flaechen_ARBEIT = flaechen_ANF;
	
			verbessereTest( anzIt,
						AnfTemp[k],
						varianteVar,
						zahlungen_ARBEIT,
						flaechen_ARBEIT,
						erreichteFlaeche,
						erreichteKosten,
						tzahlung,
						mliste,
						gewichte,
						budget,
						anzahl_arten,
						zeilen,
						spalten,
						artflaeche,
						massnahmenergebvector_ARBEIT,
						pixellisten_mit_position,
						ergebnisliste,
						pixelpromassnahme);

			DeltaFlaechen[i][k] = erreichteFlaeche - AnfFlaeche;//erreichte Verbesserung
			
			loescheMassnahmenlisten(massnahmenergebvector_ARBEIT);
			massnahmenergebvector_ARBEIT = massnahmenergebvector_ANF;
			zahlungen_ARBEIT = zahlungen_ANF;
			flaechen_ARBEIT = flaechen_ANF;
		}
	}

	//zeigeMatrix(DeltaFlaechen);
	vector<double> durchVerbesserung = berechneDurchschnitte(DeltaFlaechen);
	vector<double> varVerbesserung = berechneVarianzen(durchVerbesserung, DeltaFlaechen);

	AfxMessageBox("AnfTemps getestet. Nach OK wird Ergebnis in DB gespeichert.",MB_YESNO,0);

	datenbank *daten = new datenbank;
	//Speichern in DB
	daten->save_heurtest(	name,
							anzWiederholungen,
							NullvektorInt(anzTemp),
							durchVerbesserung,
							varVerbesserung,
							NullvektorInt(anzTemp),
							NullvektorDouble(anzTemp),
							NullvektorInt(anzTemp),
							NullvektorDouble(anzTemp));
	daten->speichereStichproben(name, test, DeltaFlaechen);
	delete daten;

	ergebnis *ergeb;
    ergeb = new ergebnis;
   
    return (*ergeb);
}


simulation::ergebnis simulation::testeIterationszahlAnhandBsp(
		int tzahlung,
		vector< art*>& artlist,
		vector< massnahme>& mliste,
		vector< double>& gewichte,
		vector< double>& minqualitaet,
		int budget,
		bool zahlung,
		int zeilen,
		int spalten,
		int bundeslandID,
		bool hoch,
		bool egal)
{

	int anzahl_arten = artlist.size();
   
    int anzMass = mliste.size();
    vector < vector < modell::masspixelergeb >> massnahmenergebvector_ANF( anzMass);
    vector < vector < modell::masspixelergeb >> massnahmenergebvector_ARBEIT( anzMass);

    //die Modellierung erfolgt nun
	modell mod;
    mod.calculate_oekologiemodell( artlist, mliste, minqualitaet,
            massnahmenergebvector_ANF, bundeslandID, hoch, egal);
    //AfxMessageBox("Nach der Modelierung",MB_YESNO,0);

	//Sortieren des massnahmenergebvectors 
	sortiereMassnahmenlisten(massnahmenergebvector_ANF);
	massnahmenergebvector_ARBEIT = massnahmenergebvector_ANF;

	vector< double> zahlungen_ANF; //speichert für jede Massnahme die Zahlung;
    vector< int> flaechen_ANF; //speichert für jede Massnaheme die Fläche = Anzahl an Pixel für die die Massnamhe angewendet werden darf
  
	vector< double> artflaeche = NullvektorDouble(anzahl_arten); //Wird die Fläche nach der Modelierung für jede Art erfassen jetzt erst mal initialisieren

	vector<double> kostendifferenz;
    vector<double> kostenmax;
	vector<int> max_flaeche;

	vector< simulation::mapixelliste_mit_pos> pixellisten_mit_position;
    vector< modell::masspixelergeb> ergebnisliste;
	vector< int> pixelpromassnahme; 

	vector<int> AnzPixel = berechneAnzPixel(massnahmenergebvector_ANF);
	int M_greifend = bestimmeAnzahlGreifMass(AnzPixel);

	CString info;
	info.Format("AnzMass=%d, AnzGreifMass=%d", anzMass, M_greifend);
	//AfxMessageBox(info);

	
	HeurMFBudgetwichtung(zahlungen_ANF, 
					    flaechen_ANF, 
					   _T("MaxErrEff"),
					   _T("AnteilKostendifferenz"),
					    gewichte,
					    0.35,									
						budget,
						tzahlung,
						massnahmenergebvector_ARBEIT,
						pixellisten_mit_position,
						ergebnisliste,
						pixelpromassnahme);

	//zeigeVektor(zahlungen_ANF);
	
	
	/*
	HeurMFAstrid(	zahlungen_ANF, 
					flaechen_ANF, 
					kostendifferenz,
					kostenmax,
					max_flaeche,
					budget,
					tzahlung,
					massnahmenergebvector_ARBEIT,
					pixellisten_mit_position,
					ergebnisliste,
					pixelpromassnahme);
	*/
	double AnfKosten = gesammtkosten( //Simulation des AUP
					pixellisten_mit_position, 
					ergebnisliste,
					artflaeche, 
					flaechen_ANF, 
					pixelpromassnahme, 
					zeilen, 
					spalten,
					anzahl_arten);
	
	double AnfFlaeche = 0;  
	for( int a = 0; a < anzahl_arten; a++)//Berechnen der Gesamtflaeche
		AnfFlaeche = AnfFlaeche + artflaeche[ a] * gewichte[ a];
	
	double AnfTemp = anzMass * 10000000;//Astrids Variante
	AnfTemp = berechneAnfangstemperatur(AnfFlaeche, 0.0000001);
	int anzWiederholungen = 5;//Jede Iterationszahl wird so oft wiederholt
	CString varianteVar = "Meine1";//lokal
	//varianteVar = "Astrid";
	vector<int> anzIt;
	vector<CString> name;
	vector<CString> name2;

	info.Format("AnfTemp=%f, AnfFlaeche=%f",AnfTemp, AnfFlaeche);
	//AfxMessageBox(info);

	anzIt.push_back( 2000 );
	anzIt.push_back( 5000 );
	anzIt.push_back( 10000 );
	anzIt.push_back( 15000 );
	anzIt.push_back( 20000 );
	anzIt.push_back( 25000 );
	
	int anzItZahl = anzIt.size();
	
	CString help;
	for(int i=0; i<anzItZahl; i++)
	{
		help.Format("%d",anzIt[i]);
		name.push_back("EndFlaeche ItZahl=" + help);
		name2.push_back("Laufzeit ItZahl=" + help);
	}

	vector<vector<double>> EndFlaechen(anzWiederholungen);//Speicherung der Ergebnisse
	vector<vector<double>> Zeiten(anzWiederholungen);//SPeicherung der Laufzeiten
	vector<CString> test;
	for(int i=0; i<anzWiederholungen; i++)
	{
		EndFlaechen[i] = NullvektorDouble(anzItZahl);
		Zeiten[i] = NullvektorDouble(anzItZahl);
		test.push_back( toString(mliste) );
	}
	
	LONGLONG g_Frequency, g_CurentCount, g_LastCount;

    //Frequenz holen
    if (!QueryPerformanceFrequency((LARGE_INTEGER*)&g_Frequency))
        std::cout << "Performance Counter nicht vorhanden" << std::endl;   

	for(int k=0; k<anzItZahl; k++)//Durchlaufen aller zu testenden Iterationszahlen
	{
		for(int i=0 ;i<anzWiederholungen; i++)
		{
			double erreichteFlaeche = AnfFlaeche;
			double erreichteKosten = AnfKosten;
			vector<double> zahlungen_ARBEIT = zahlungen_ANF;
			vector<int> flaechen_ARBEIT = flaechen_ANF;
	
			//AfxMessageBox("Start");
			QueryPerformanceCounter((LARGE_INTEGER*)&g_CurentCount);//Zeit messen
			verbessereTest( anzIt[k],
						AnfTemp,
						varianteVar,
						zahlungen_ARBEIT,
						flaechen_ARBEIT,
						erreichteFlaeche,
						erreichteKosten,
						tzahlung,
						mliste,
						gewichte,
						budget,
						anzahl_arten,
						zeilen,
						spalten,
						artflaeche,
						massnahmenergebvector_ARBEIT,
						pixellisten_mit_position,
						ergebnisliste,
						pixelpromassnahme);
			QueryPerformanceCounter((LARGE_INTEGER*)&g_LastCount);
			//AfxMessageBox("Stopp");

			EndFlaechen[i][k] = erreichteFlaeche;//erreichte Verbesserung
			Zeiten[i][k] = (((double)(g_LastCount-g_CurentCount))/((double)g_Frequency));//Zeitdiff. berechnen
			
			loescheMassnahmenlisten(massnahmenergebvector_ARBEIT);
			massnahmenergebvector_ARBEIT = massnahmenergebvector_ANF;
			zahlungen_ARBEIT = zahlungen_ANF;
			flaechen_ARBEIT = flaechen_ANF;
		}
	}

	//zeigeMatrix(DeltaFlaechen);
	vector<double> durchEndFlaeche = berechneDurchschnitte(EndFlaechen);
	vector<double> varEndFlaeche = berechneVarianzen(durchEndFlaeche, EndFlaechen);

	AfxMessageBox("Iterationszahlen getestet. Nach OK wird Ergebnis in DB gespeichert.",MB_YESNO,0);

	datenbank *daten = new datenbank;
	//Speichern in DB
	daten->save_heurtest(	name,
							anzWiederholungen,
							NullvektorInt(anzItZahl),
							durchEndFlaeche,
							varEndFlaeche,
							NullvektorInt(anzItZahl),
							NullvektorDouble(anzItZahl),
							NullvektorInt(anzItZahl),
							NullvektorDouble(anzItZahl));
	daten->speichereStichproben(name, test, EndFlaechen);
	AfxMessageBox("Nach OK werden Laufzeiten in DB gespeichert.",MB_YESNO,0);
	daten->speichereStichproben(name2, test, Zeiten);
	delete daten;

	exit(0);

	ergebnis *ergeb;
    ergeb = new ergebnis;
   
    return (*ergeb);
}
//Berechnen und Simulieren von AUP fuer verschiedene Optimierungsszenarios
void simulation::testeAnfHeurMaxFlaecheStatistisch(int anzWiederholungen)
{
	CString filename = _T("AnfHeurTestProt.txt");

	schreibeInDatei(filename , _T("Statistischer Heuristik-Test gestartet!"));

	vector<CString> name;
	
	
	name.push_back( _T("Astrids AnfHeur") );
	name.push_back( _T("MitKonku MaxErrEffFlaeche Anteil Kostendifferenz 0.35") );
	name.push_back( _T("MitKonku MaxErrEffFlaeche Pauschal 110") );	
	name.push_back( _T("MitKonku MaxErrEff AnteilKostendifferenz 0.35") );
	name.push_back( _T("MitKonku MaxErrEff Pauschal 110") );
	name.push_back( _T("MitKonku MaxErrEffGew 12 AnteilKostendifferenz 0.35") );
	name.push_back( _T("MitKonku MaxErrEffGew 12 Pauschal 110") );
	name.push_back( _T("OhneKonku MaxErrEffFlaeche") );
	name.push_back( _T("OhneKonku MaxErrEff") );
	name.push_back( _T("OhneKonku MaxErrEffGew 12") );
	
	
	/*
	vector<double> konkFak;
	for(int i=0; i<=40; i++)
	{
		konkFak.push_back(5*i);
		CString s;
		s.Format( _T("MitKonku MaxErrEffFlaeche Pauschal: konkFak = %f"), konkFak.back() );
		name.push_back( s );
	}
	*/
		
	
	/*
	vector<double> konkFak;
	for(int i=0; i<=40; i++)
	{
		konkFak.push_back(0.05*double(i));
		CString s;
		s.Format( _T("MitKonku MaxErrEff AnteilKostendifferenz: konkFak = %f"), konkFak.back() );
		name.push_back( s );
	}
	*/
		
	
	/*
	vector<double> konkFak;
	for(int i=0; i<=40; i++)
	{
		konkFak.push_back(0.05*i);
		CString s;
		s.Format( _T("MitKonku MaxErrEff AnteilKostendifferenz: konkFak = %f"), konkFak.back() );
		name.push_back( s );
	}
	*/
	
	

	//name.push_back( _T("OhneKonku MaxErrEffFlaeche") );
	//name.push_back( _T("OhneKonku MaxErrEff") );
	//varianteWichtung.push_back( _T("MaxErrEffFlaeche") );
	//varianteWichtung.push_back( _T("MaxErrEff") );

	/*
	vector<CString> varianteWichtung;
	for(int i=200; i<=5000;i=i+200)
	{
		CString strGew;
		strGew.Format("%d", i );
		name.push_back( "OhneKonku MaxErrEffGew=" + strGew );
		varianteWichtung.push_back( "MaxErrEffGew=" + strGew );
	}
	*/
	
	

	double eps = 0.00000001;
	int anzHeur = name.size();

	vector<int> anzBeste(anzHeur);
	vector<int> anzBudOk(anzHeur);//Zum Sammeln der Daten
	vector<int> anzOhneLoes(anzHeur);

	vector<double> AnteilAnBesterAkt(anzHeur);
	vector<vector<double>> AnteilAnBesterGes;//Sammeln der Vektoren VerschlechterungAkt
												//--> Bilden von Mittelwert und Varianz
	vector<double> durchBudAuss(anzHeur);//Speichern der durchschnittlichen Budgetausschöpfung, sofern das Budget eingehaltn wurde
	
	vector<int> aktRang(anzHeur);
	vector<double> durchRang(anzHeur);

	vector<bool> bOk(anzHeur);//Fuer ein Szenario
	vector<double> gesamtflaeche(anzHeur);//Zum Vergleich in einem Szenario
	vector<double> ausgabe(anzHeur);//Zum Vergleich in einem Szenario

	vector< vector< modell::masspixelergeb>>::iterator me; // Iterator für die Liste der Kostenlisten aller Massnahmen
	vector< modell::masspixelergeb>::iterator mp; //Iterator für die Kostenliste einer Massnahme

	vector < vector < modell::masspixelergeb >> massnahmenergebvector_ANF;
	vector < vector < modell::masspixelergeb >> massnahmenergebvector_ARBEIT;

	vector< simulation::mapixelliste_mit_pos> pixellisten_mit_position;
	vector< modell::masspixelergeb> ergebnisliste;
	vector< int> pixelpromassnahme;
	
	int tzahlung;
	vector< art*> artlist;
	vector< massnahme> mliste;
	vector< double> gewichte;
	vector< double> minqual;
	int budget;
	bool zahlung;
	int zeilen;
	int spalten;
	int bundeslandID;
	bool hoch;
	bool egal;

	CString str;
	vector<CString> mass;
	int it=0;

	while(it<anzWiederholungen)
	{
		calcRandomKonfiMaxFlaeche(//zufällige Wahl einer Optimierungskonfiguration
				tzahlung,
				artlist,
				mliste,
				gewichte,
				minqual,
				budget,
				zahlung,
				zeilen,
				spalten,
				bundeslandID,
				hoch,
				egal);

		str.Format("Konfiguration Nummer %d erzeugt.",it);
		schreibeInDatei(filename, str);	

		mass.push_back(toString(mliste));

		int AnzMass = mliste.size();
		int anzahl_arten = artlist.size();

		loescheMassnahmenlisten(massnahmenergebvector_ANF);
		massnahmenergebvector_ANF.resize(AnzMass);
	
		//die Modellierung erfolgt nun
		modell mod;
		mod.calculate_oekologiemodell( artlist, mliste, minqual,
				massnahmenergebvector_ANF, bundeslandID, hoch, egal);

		
		str.Format("Modell berechnet.");
		schreibeInDatei(filename, str);
		
		//Sortieren des massnahmenergebvectors_ANF
		sortiereMassnahmenlisten(massnahmenergebvector_ANF);
		massnahmenergebvector_ARBEIT = massnahmenergebvector_ANF;

		//speichereErgebnisvektoren(massnahmenergebvector_ANF,_T("ergebnisvektoren.txt"));

		str.Format("size massnahmenergebvector=%d" , massnahmenergebvector_ARBEIT.size());
		schreibeInDatei(filename, str);

		for(int i=0; i<anzHeur; i++)
		{
			vector< double> zahlungen; //speichert für jede Massnahme die Zahlung;
			vector< int> flaechen; //speichert für jede Massnaheme die Fläche = Anzahl an Pixel für die die Massnamhe angewendet werden darf
			vector< double> artflaeche(anzahl_arten); 
			vector<double> kostendifferenz;
			vector<double> kostenmax;
			vector<int> max_flaeche;

			str.Format("Heuristik Nr. %d: %s" ,i, name[i]);
			schreibeInDatei(filename, str);
			
			/*
			switch(i)
			{
			case 0://Berechnen einer Anfangsloesung, so wie es am Anfang funktionierte.
				HeurMFAstrid(	zahlungen, 
								flaechen, 
								kostendifferenz,
								kostenmax,
								max_flaeche,
								budget,
								tzahlung,
								massnahmenergebvector_ARBEIT,
								pixellisten_mit_position,
								ergebnisliste,
								pixelpromassnahme);
				break;
			case 1:					
				HeurSukWP(	zahlungen, 
							flaechen, 
							budget,
							tzahlung,
							100,
							_T("Global"),
							gewichte,
							massnahmenergebvector_ARBEIT,
							pixellisten_mit_position,
							ergebnisliste,
							pixelpromassnahme);
				break;
			case 2:	
				HeurMFBudgetwichtung(zahlungen, 
									flaechen, 
								   _T("MaxErrEffFlaeche"),
								   _T("AnteilKostendifferenz"),
								    gewichte,
									0.4,									
									budget,
									tzahlung,
									massnahmenergebvector_ARBEIT,
									pixellisten_mit_position,
									ergebnisliste,
									pixelpromassnahme);
				break;
			case 3:
				HeurMFBudgetwichtung(zahlungen, 
							flaechen, 
						   _T("MaxErrEffFlaeche"),
						   _T("Pauschal"),
						    gewichte,
							80,									
							budget,
							tzahlung,
							massnahmenergebvector_ARBEIT,
							pixellisten_mit_position,
							ergebnisliste,
							pixelpromassnahme);
				break;
			case 4:
				HeurMFBudgetwichtung(zahlungen, 
							flaechen, 
						   _T("MaxErrEffFlaeche"),
						   _T("AngleichungKostendifferenz"),
						    gewichte,
							0.6,									
							budget,
							tzahlung,
							massnahmenergebvector_ARBEIT,
							pixellisten_mit_position,
							ergebnisliste,
							pixelpromassnahme);
				break;
			case 5:
				HeurMFBudgetwichtung(zahlungen, 
							flaechen, 
						   _T("MaxErrEff"),
						   _T("AnteilKostendifferenz"),
						    gewichte,
							0.4,									
							budget,
							tzahlung,
							massnahmenergebvector_ARBEIT,
							pixellisten_mit_position,
							ergebnisliste,
							pixelpromassnahme);
				break;
			case 6:
				HeurMFBudgetwichtung(zahlungen, 
							flaechen, 
						   _T("MaxErrEff"),
						   _T("Pauschal"),
						    gewichte,
							80,									
							budget,
							tzahlung,
							massnahmenergebvector_ARBEIT,
							pixellisten_mit_position,
							ergebnisliste,
							pixelpromassnahme);
				break;
			case 7:
				HeurMFBudgetwichtung(zahlungen, 
							flaechen, 
						   _T("MaxErrEff"),
						   _T("AngleichungKostendifferenz"),
						    gewichte,
							0.6,									
							budget,
							tzahlung,
							massnahmenergebvector_ARBEIT,
							pixellisten_mit_position,
							ergebnisliste,
							pixelpromassnahme);
				break;
			case 8:
				HeurMFBudgetwichtungOhneKonku(zahlungen, 
											flaechen, 
											_T("MaxErrEffFlaeche"),
											gewichte,
											budget,
											tzahlung,
											massnahmenergebvector_ARBEIT,
											pixellisten_mit_position,
											ergebnisliste,
											pixelpromassnahme);
				break;
			case 9:
				HeurMFBudgetwichtungOhneKonku(zahlungen, 
											flaechen, 
											_T("MaxErrEff"),
											gewichte,
											budget,
											tzahlung,
											massnahmenergebvector_ARBEIT,
											pixellisten_mit_position,
											ergebnisliste,
											pixelpromassnahme);
				break;

			}
			*/

			
			switch(i)
			{
			case 0://Berechnen einer Anfangsloesung, so wie es am Anfang funktionierte.
				HeurMFAstrid(	zahlungen, 
								flaechen, 
								kostendifferenz,
								kostenmax,
								max_flaeche,
								budget,
								tzahlung,
								massnahmenergebvector_ARBEIT,
								pixellisten_mit_position,
								ergebnisliste,
								pixelpromassnahme);
				break;
			case 1:	
				HeurMFBudgetwichtung(zahlungen, 
									flaechen, 
								   _T("MaxErrEffFlaeche"),
								   _T("AnteilKostendifferenz"),
								    gewichte,
									0.35,									
									budget,
									tzahlung,
									massnahmenergebvector_ARBEIT,
									pixellisten_mit_position,
									ergebnisliste,
									pixelpromassnahme);
				break;
			case 2:
				HeurMFBudgetwichtung(zahlungen, 
							flaechen, 
						   _T("MaxErrEffFlaeche"),
						   _T("Pauschal"),
						    gewichte,
							110,									
							budget,
							tzahlung,
							massnahmenergebvector_ARBEIT,
							pixellisten_mit_position,
							ergebnisliste,
							pixelpromassnahme);
				break;
			case 3:
				HeurMFBudgetwichtung(zahlungen, 
							flaechen, 
						   _T("MaxErrEff"),
						   _T("AnteilKostendifferenz"),
						    gewichte,
							0.35,									
							budget,
							tzahlung,
							massnahmenergebvector_ARBEIT,
							pixellisten_mit_position,
							ergebnisliste,
							pixelpromassnahme);
				break;
			case 4:
				HeurMFBudgetwichtung(zahlungen, 
							flaechen, 
						   _T("MaxErrEff"),
						   _T("Pauschal"),
						    gewichte,
							110,									
							budget,
							tzahlung,
							massnahmenergebvector_ARBEIT,
							pixellisten_mit_position,
							ergebnisliste,
							pixelpromassnahme);
				break;
			case 5:
				HeurMFBudgetwichtung(zahlungen, 
							flaechen, 
						   _T("MaxErrEffGew=12"),
						   _T("AnteilKostendifferenz"),
						    gewichte,
							0.35,									
							budget,
							tzahlung,
							massnahmenergebvector_ARBEIT,
							pixellisten_mit_position,
							ergebnisliste,
							pixelpromassnahme);
				break;
			case 6:
				HeurMFBudgetwichtung(zahlungen, 
							flaechen, 
						   _T("MaxErrEffGew=12"),
						   _T("Pauschal"),
						    gewichte,
							110,									
							budget,
							tzahlung,
							massnahmenergebvector_ARBEIT,
							pixellisten_mit_position,
							ergebnisliste,
							pixelpromassnahme);
				break;
			case 7:
				HeurMFBudgetwichtungOhneKonku(zahlungen, 
											flaechen, 
											_T("MaxErrEffFlaeche"),
											gewichte,
											budget,
											tzahlung,
											massnahmenergebvector_ARBEIT,
											pixellisten_mit_position,
											ergebnisliste,
											pixelpromassnahme);
				break;
			case 8:
				HeurMFBudgetwichtungOhneKonku(zahlungen, 
											flaechen, 
											_T("MaxErrEff"),
											gewichte,
											budget,
											tzahlung,
											massnahmenergebvector_ARBEIT,
											pixellisten_mit_position,
											ergebnisliste,
											pixelpromassnahme);
				break;
			case 9:
				HeurMFBudgetwichtungOhneKonku(zahlungen, 
											flaechen, 
											_T("MaxErrEffGew=12"),
											gewichte,
											budget,
											tzahlung,
											massnahmenergebvector_ARBEIT,
											pixellisten_mit_position,
											ergebnisliste,
											pixelpromassnahme);
				break;

			}
			
			
			/*
			HeurMFBudgetwichtung( zahlungen, 
								  flaechen, 
								  _T("MaxErrEff"),
								  _T("Pauschal"),
								  gewichte,
								  konkFak[i],
								  budget,
								  tzahlung,
								  massnahmenergebvector_ARBEIT,
								  pixellisten_mit_position,
								  ergebnisliste,
								  pixelpromassnahme);
			  */
			
			/*
			HeurMFBudgetwichtung(zahlungen, 
									flaechen, 
								   _T("MaxErrEff"),
								   _T("AnteilKostendifferenz"),
								    gewichte,
									konkFak[i],									
									budget,
									tzahlung,
									massnahmenergebvector_ARBEIT,
									pixellisten_mit_position,
									ergebnisliste,
									pixelpromassnahme);
			*/
						

			/*
			HeurMFBudgetwichtungOhneKonku(  zahlungen, 
											flaechen, 
											varianteWichtung[i],
											gewichte,
											budget,
											tzahlung,
											massnahmenergebvector_ARBEIT,
											pixellisten_mit_position,
											ergebnisliste,
											pixelpromassnahme);
			*/
			
			

			str.Format(AUPtoString(mliste, zahlungen, flaechen));
			schreibeInDatei(filename, str);

			ausgabe[i] = gesammtkosten( //Simulation des AUP
						pixellisten_mit_position, 
						ergebnisliste,
						artflaeche, 
						flaechen, 
						pixelpromassnahme, 
						zeilen, 
						spalten,
						anzahl_arten);

			gesamtflaeche[i] = 0;  
			for( int a = 0; a < anzahl_arten; a++)//Berechnen der Gesamtflaeche
			{
				gesamtflaeche[i] += artflaeche[ a] * gewichte[ a];
			}

			str.Format("Gesamtflaeche=%f, Gesamtkosten=%f", gesamtflaeche[i], ausgabe[i]);
			schreibeInDatei(filename, str);	
			
			vector< simulation::mapixelliste_mit_pos> vec1;
			pixellisten_mit_position.swap(vec1);
			loescheMassnahmenlisten(massnahmenergebvector_ARBEIT);
			vector<modell::masspixelergeb> vec2;
			vec2.swap(ergebnisliste);
			pixelpromassnahme.clear();
			massnahmenergebvector_ARBEIT = massnahmenergebvector_ANF;
		
		}//Ende Schleife ueber Heuristiken

		loescheMassnahmenlisten(massnahmenergebvector_ANF);

		//Bestimmen, ob Budget ok und Bestimmen des Grades der Budgetausschoepfung
		for(int k=0; k<anzHeur; k++)
		{
			bOk[k] = ausgabe[k] <= budget;
			if(bOk[k])
			{
				anzBudOk[k]++;
				durchBudAuss[k] += ausgabe[k]/double(budget);
			}
			else
				gesamtflaeche[k] = 0;//erreichte Flaeche wird Null gesetzt fuer diese Heuristik
		}

		//Bestimmen des Rankings
		aktRang = bestimmeRankingBesteAUP(gesamtflaeche, bOk, ausgabe);

		for(int k=0; k<anzHeur; k++)
			durchRang[k] = durchRang[k] + double(aktRang[k]);
		

		//Eintragen der besten Heuristik(en)
		double besterWert;
		bool keinBesterWert = true;
		for(int k=0; k<anzHeur; k++)
		{
			if(aktRang[k] == 1)
			{
				anzBeste[k]++;
				besterWert = gesamtflaeche[k];
				keinBesterWert = false;
			}
		}


		//Bestimmen des Grades der Verschlechterung fuer jede Heuristik, bezugnehmend auf beste Heuristik (max == 1)
		for(int h=0; h<anzHeur; h++)
		{
			if(keinBesterWert)
				AnteilAnBesterAkt[h] = 1;
			else if(besterWert > 0)
				AnteilAnBesterAkt[h] = gesamtflaeche[h]/besterWert;
			else 
				AnteilAnBesterAkt[h] = 1;
		}
		AnteilAnBesterGes.push_back(AnteilAnBesterAkt);

		it++;
		//zeigeVektor(durchRang);

	}//Ende des Tests [Schleife]

	//zeigeMatrix(AnteilAnBesterGes);

	//Berechnen der Durchschnitte fuer Budget und Raenge und Verschlechterung
	for(int j=0; j<anzHeur; j++)
	{
		if(anzBudOk[j] > 0)
			durchBudAuss[j] = durchBudAuss[j]/double(anzBudOk[j]);
		else
			durchBudAuss[j] = -1;
		durchRang[j] = durchRang[j]/double(anzWiederholungen);
	}
	//AfxMessageBox("Vor Berechnen Varianz und Durchschnitte");
	vector<double> AnteilAnBesterDurch = berechneDurchschnitte(AnteilAnBesterGes);
	//zeigeVektor(AnteilAnBesterDurch);
	vector<double> AnteilAnBesterVar = berechneVarianzen(AnteilAnBesterDurch, AnteilAnBesterGes);


	AfxMessageBox("AnfHeur getestet. Nach OK wird Ergebnis in DB gespeichert.",MB_YESNO,0);

	datenbank *daten = new datenbank;
	//Speichern in DB
	daten->save_heurtest(	name,
							anzWiederholungen,
							anzBeste,
							AnteilAnBesterDurch,
							AnteilAnBesterVar,
							anzBudOk,
							durchBudAuss,
							anzOhneLoes,
							durchRang);
	daten->speichereStichproben(name,mass,AnteilAnBesterGes);
	delete daten;

	schreibeInDatei( filename, _T("Ergebnis des Tests in DB abgelegt!"));
	
	return;
}




//Durchfuehren verschiedener Optimierungen mit verschiedenen Variationsvarianten
void simulation::testeVariationStatistisch(int anzWiederholungen)
{
	CString filename = _T("VariationTestProt.txt");
	schreibeInDatei(filename , _T("Statistischer Test der Variationen gestartet!"));

	vector<CString> name;
	vector<CString> varianteVar;
	
	name.push_back( _T("AstridVar Anf") );
	name.push_back( _T("AstridVar 0.33") );
	name.push_back( _T("AstridVar 0.01") );
	name.push_back( _T("AstridVar 0.0001") );
	name.push_back( _T("AstridVar 0.0000001") );

	name.push_back( _T("sehr lokal Anf") );
	name.push_back( _T("sehr lokal 0.33") );
	name.push_back( _T("sehr lokal 0.01") );
	name.push_back( _T("sehr lokal 0.0001") );
	name.push_back( _T("sehr lokal 0.0000001") );

	name.push_back( _T("lokal Anf") );
	name.push_back( _T("lokal 0.33") );
	name.push_back( _T("lokal 0.01") );
	name.push_back( _T("lokal 0.0001") );
	name.push_back( _T("lokal 0.0000001") );

	name.push_back( _T("globaler Anf") );
	name.push_back( _T("globaler 0.33") );
	name.push_back( _T("globaler 0.01") );
	name.push_back( _T("globaler 0.0001") );
	name.push_back( _T("globaler 0.0000001") );

	name.push_back( _T("linear Anf") );
	name.push_back( _T("linear 0.33") );
	name.push_back( _T("linear 0.01") );
	name.push_back( _T("linear 0.0001") );
	name.push_back( _T("linear 0.0000001") );

	/*
	name.push_back( _T("Stufen Anf") );
	name.push_back( _T("Stufen 0.33") );
	name.push_back( _T("Stufen 0.01") );
	name.push_back( _T("Stufen 0.0001") );
	name.push_back( _T("Stufen 0.0000001") );
	*/

	varianteVar.push_back( _T("Astrid") );
	varianteVar.push_back( _T("Astrid") );
	varianteVar.push_back( _T("Astrid") );
	varianteVar.push_back( _T("Astrid") );
	varianteVar.push_back( _T("Astrid") );

	varianteVar.push_back( _T("Meine4") );//sehr lokal
	varianteVar.push_back( _T("Meine4") );
	varianteVar.push_back( _T("Meine4") );
	varianteVar.push_back( _T("Meine4") );
	varianteVar.push_back( _T("Meine4") );

	varianteVar.push_back( _T("Meine1") );//lokal
	varianteVar.push_back( _T("Meine1") );
	varianteVar.push_back( _T("Meine1") );
	varianteVar.push_back( _T("Meine1") );
	varianteVar.push_back( _T("Meine1") );

	varianteVar.push_back( _T("Meine2") );//globaler
	varianteVar.push_back( _T("Meine2") );
	varianteVar.push_back( _T("Meine2") );
	varianteVar.push_back( _T("Meine2") );
	varianteVar.push_back( _T("Meine2") );
	
	varianteVar.push_back( _T("Meine3") );//linear zwischen sehr lokal und globaler
	varianteVar.push_back( _T("Meine3") );
	varianteVar.push_back( _T("Meine3") );
	varianteVar.push_back( _T("Meine3") );
	varianteVar.push_back( _T("Meine3") );

	/*
	varianteVar.push_back( _T("Stufen") );	
	varianteVar.push_back( _T("Stufen") );	
	varianteVar.push_back( _T("Stufen") );	
	varianteVar.push_back( _T("Stufen") );	
	varianteVar.push_back( _T("Stufen") );
	*/

	int anzVar = name.size();
	
	//Ergebnisse eines Durchlaufs
	double AnfFlaeche;
	vector<double> EndFlaeche(anzVar);
	vector<double> EndAusgabe(anzVar);
	vector<double> DeltaFlaeche(anzVar);
	vector<int> aktRang(anzVar);
	vector<double> VerbesserungAkt(anzVar);	

	//Anlegen der Statistik
	vector<double> durchRang(anzVar);
	vector<vector<double>> VerbesserungGes;//Zum Speichern der Ergebnisse

	vector<double> zahlungen_ANF, zahlungen_ARBEIT;
	vector<int> flaechen_ANF, flaechen_ARBEIT;

	vector < vector < modell::masspixelergeb >> massnahmenergebvector_ANF;
	vector < vector < modell::masspixelergeb >> massnahmenergebvector_ARBEIT;

	vector< simulation::mapixelliste_mit_pos> pixellisten_mit_position;
	vector< modell::masspixelergeb> ergebnisliste;
	vector< int> pixelpromassnahme;

	int tzahlung;
	vector< art*> artlist;
	vector< massnahme> mliste;
	vector< double> gewichte;
	vector< double> minqual;
	int budget;
	bool zahlung;
	int zeilen;
	int spalten;
	int bundeslandID;
	bool hoch;
	bool egal;

	CString str;
	vector<CString> mass;
	
	for(int it=0; it<anzWiederholungen; it++)
	{
		calcRandomKonfiMaxFlaeche(//zufällige Wahl einer Optimierungskonfiguration
					tzahlung,
					artlist,
					mliste,
					gewichte,
					minqual,
					budget,
					zahlung,
					zeilen,
					spalten,
					bundeslandID,
					hoch,
					egal);

		mass.push_back(toString(mliste));

		int anzIt = RandomInt(250, 250);//Gilt fuer alle Optimierungen

		str.Format("Konfiguration Nummer %d erzeugt. AnzMass=%d", it, mliste.size());
		schreibeInDatei(filename, str);	

		int AnzMass = mliste.size();
		int anzahl_arten = artlist.size();
		
		loescheMassnahmenlisten(massnahmenergebvector_ANF);
		massnahmenergebvector_ANF.resize(AnzMass);
		
		//die Modellierung erfolgt nun
		modell mod;
		mod.calculate_oekologiemodell( artlist, mliste, minqual,
				massnahmenergebvector_ANF, bundeslandID, hoch, egal);

		str.Format("Modell berechnet. AnzMass=%d ", massnahmenergebvector_ANF.size());
		schreibeInDatei(filename, str);
			
		//Sortieren des massnahmenergebvectors_ANF
		sortiereMassnahmenlisten(massnahmenergebvector_ANF);

		vector<int> AnzPixel = berechneAnzPixel(massnahmenergebvector_ANF);
		int M_greifend = bestimmeAnzahlGreifMass(AnzPixel);
		
		//Anfangsloesung wird berechnet
		CString varianteWichtung = _T("MaxErrEff");
		CString varianteKonkAufschlag = _T("AnteilKostendifferenz");
		vector<double> artflaeche = NullvektorDouble(anzahl_arten);
		double konkFak = 0.45;
		HeurMFBudgetwichtung(zahlungen_ANF, 
						     flaechen_ANF, 
						  	varianteWichtung,
							varianteKonkAufschlag,
							gewichte,
							konkFak,
							budget,
							tzahlung,
							massnahmenergebvector_ANF,
							pixellisten_mit_position,
							ergebnisliste,
							pixelpromassnahme);
		
		double AnfKosten = gesammtkosten( //Simulation der Anfangsloesung
							pixellisten_mit_position, 
							ergebnisliste,
							artflaeche, 
							flaechen_ANF, 
							pixelpromassnahme, 
							zeilen, 
							spalten,
							anzahl_arten);

		AnfFlaeche = 0;  
		for( int a = 0; a < anzahl_arten; a++)//Berechnen der Gesamtflaeche
			AnfFlaeche += artflaeche[ a] * gewichte[ a];
		
		massnahmenergebvector_ARBEIT = massnahmenergebvector_ANF;
		zahlungen_ARBEIT = zahlungen_ANF;
		flaechen_ARBEIT = flaechen_ANF;

		str.Format("Anfangsloesung bestimmt und simuliert. Flaeche=%f, Kosten=%f", AnfFlaeche, AnfKosten);
		schreibeInDatei(filename, str);	
		str.Format("%s", AUPtoString(mliste, zahlungen_ANF, flaechen_ANF) );
		schreibeInDatei(filename, str);	
		
		for(int i=0; i<anzVar; i++)
		{
			double erreichteFlaeche = AnfFlaeche;
			double erreichteKosten = AnfKosten;
			double AnfTemp;

			if(i % 5 == 0)
				AnfTemp = M_greifend*10000000;
			else if(i % 5 == 1)
				AnfTemp = berechneAnfangstemperatur(AnfFlaeche, 0.33);
			else if(i % 5 == 2)
				AnfTemp = berechneAnfangstemperatur(AnfFlaeche, 0.01);
			else if(i % 5 == 3)
				AnfTemp = berechneAnfangstemperatur(AnfFlaeche, 0.0001);
			else
				AnfTemp = berechneAnfangstemperatur(AnfFlaeche, 0.0000001);

			//CString strAT;
			//strAT.Format("AnfTemp=%f",AnfTemp);
			//name[i].Append(strAT);
	
			verbessereTest( anzIt,
						AnfTemp,
						varianteVar[i],
						zahlungen_ARBEIT,
						flaechen_ARBEIT,
						erreichteFlaeche,
						erreichteKosten,
						tzahlung,
						mliste,
						gewichte,
						budget,
						anzahl_arten,
						zeilen,
						spalten,
						artflaeche,
						massnahmenergebvector_ARBEIT,
						pixellisten_mit_position,
						ergebnisliste,
						pixelpromassnahme);
			EndAusgabe[i] = erreichteKosten;
			DeltaFlaeche[i] = erreichteFlaeche - AnfFlaeche;
			if(AnfFlaeche>0)
				VerbesserungAkt[i] = erreichteFlaeche/AnfFlaeche;
			else
				VerbesserungAkt[i] = 0;
			/*
			datenbank *daten = new datenbank;
			daten->save_optimierungsfortgang(0, 
											AUPtoString(mliste, zahlungen_ARBEIT, flaechen_ARBEIT),
											EndFlaeche[i],
											-1,
											EndAusgabe[i]);
			delete daten;
		
			*/
		
			str.Format(_T("Variation %s durchgefuehrt. AnfFlaeche=%f, EndFlaeche=%f, EndAusgabe=%f") , 
				name[i], AnfFlaeche, EndFlaeche[i], EndAusgabe[i]);
			schreibeInDatei(filename , str);
		
			loescheMassnahmenlisten(massnahmenergebvector_ARBEIT);
			massnahmenergebvector_ARBEIT = massnahmenergebvector_ANF;
			zahlungen_ARBEIT = zahlungen_ANF;
			flaechen_ARBEIT = flaechen_ANF;
			
		}

		pixellisten_mit_position.clear();
		ergebnisliste.clear();
		pixelpromassnahme.clear();

		VerbesserungGes.push_back(VerbesserungAkt);

		//Berechnen der erzielten Verbesserungen
		aktRang = bestimmeRanking(DeltaFlaeche);
		for(int j=0; j<anzVar; j++)
			durchRang[j] = durchRang[j] + aktRang[j];
	}//Test beendet

	for(int j=0; j<anzVar; j++)//Berechnen der durchschnittlichen Raenge
		durchRang[j] = durchRang[j] / double(anzWiederholungen);

	vector<double> durchVerbesserung = berechneDurchschnitte(VerbesserungGes);
	vector<double> varVerbesserung = berechneVarianzen(durchVerbesserung, VerbesserungGes);

	AfxMessageBox("Variationen getestet.->OK->Ergebnis wird in DB gespeichert.",MB_OK,0);
	datenbank *daten = new datenbank;
	//Speichern in DB
	daten->save_heurtest(	name,
							anzWiederholungen,
							NullvektorInt(anzVar),
							durchVerbesserung,
							varVerbesserung,
							NullvektorInt(anzVar),
							NullvektorDouble(anzVar),
							NullvektorInt(anzVar),
							durchRang);
	daten->speichereStichproben(name,mass,VerbesserungGes);
	delete daten;

	schreibeInDatei(filename , _T("Statistischer Test der Variationen beendet!"));

	return;
}

//Ab welcher Iterationszahl tritt keine Verbesserung mehr ein?
//Welche Iterationszahl ist am effizientesten?
void simulation::testeIterationszahlStatistisch(int anzWiederholungen)
{
	CString str;
	CString filename = _T("IterationszahlTestProt.txt");
	schreibeInDatei(filename, _T("Test verschiedener Iterationszahlen gestartet."));

	vector<int> ItZahlen;
	ItZahlen.push_back(5000);
	for(int i=1; i<6; i++)
		ItZahlen.push_back( ItZahlen.back() * 2 );

	int anzItZahl = ItZahlen.size();
	CString varianteVar = _T("Meine1");//lokale Änderung

	//Fuer ein Szenario
	double AnfFlaeche;
	vector<double> EndFlaeche(anzItZahl);
	vector<double> EndAusgabe(anzItZahl);
	vector<double> VerbesserungProzent(anzItZahl);
	vector<double> Effizienz(anzItZahl);//Speichern des Verhaeltnisses zwischen der Verbesserung und der Anzahl Iterationen

	//Für jede mögliche Anzahl greifender Massnahmen eine Statistik
	//Anz. greif Mass == 0 --> globale Statistik für alle Optimierungskonfigurationen
	int maxAnzGreifMass = 20;//Bestimmt durch Funktion, die Optimierungsszenarionen liefert
	vector<int> AnzRealDurgefWiederholJeAnzGreifMass = NullvektorInt(maxAnzGreifMass+1);
	vector< vector<vector<double> >> Statistik(maxAnzGreifMass+1);
	//Matrix in Statistik enthaelt zu jeder Iterationszahl  eine Zeile mit 6 Spalten (min,max,durch) je 2 mal
	for(int i=0; i<maxAnzGreifMass+1; i++)
	{
		for(int j=0; j<anzItZahl; j++)
		{
			Statistik[i].push_back( NullvektorDouble(6) );
			Statistik[i].back()[0] = -1;
			Statistik[i].back()[3] = -1;

		}
	}

	vector<double> zahlungen_ANF, zahlungen_ARBEIT;
	vector<int> flaechen_ANF, flaechen_ARBEIT;

	vector < vector < modell::masspixelergeb >> massnahmenergebvector_ANF;
	vector < vector < modell::masspixelergeb >> massnahmenergebvector_ARBEIT;

	vector< simulation::mapixelliste_mit_pos> pixellisten_mit_position;
	vector< modell::masspixelergeb> ergebnisliste;
	vector< int> pixelpromassnahme;

	int tzahlung;
	vector<art*> artlist;
	vector<massnahme> mliste;
	vector<double> gewichte;
	vector<double> minqual;
	int budget;
	bool zahlung;
	int zeilen;
	int spalten;
	int bundeslandID;
	bool hoch;
	bool egal;

	for(int it=0; it<anzWiederholungen; it++)
	{
		calcRandomKonfiMaxFlaeche(//zufällige Wahl einer Optimierungskonfiguration
					tzahlung,
					artlist,
					mliste,
					gewichte,
					minqual,
					budget,
					zahlung,
					zeilen,
					spalten,
					bundeslandID,
					hoch,
					egal);

		str.Format("Konfiguration Nummer %d erzeugt. AnzMass=%d", it, mliste.size());
		schreibeInDatei(filename, str);	

		int AnzMass = mliste.size();
		int anzahl_arten = artlist.size();
		
		loescheMassnahmenlisten(massnahmenergebvector_ANF);
		massnahmenergebvector_ANF.resize(AnzMass);
		
		//die Modellierung erfolgt nun
		modell mod;
		mod.calculate_oekologiemodell( artlist, mliste, minqual,
				massnahmenergebvector_ANF, bundeslandID, hoch, egal);

		str.Format("Modell berechnet. AnzMass=%d ", massnahmenergebvector_ANF.size());
		schreibeInDatei(filename, str);
			
		//Sortieren des massnahmenergebvectors_ANF
		sortiereMassnahmenlisten(massnahmenergebvector_ANF);

		vector<int> AnzPixel = berechneAnzPixel(massnahmenergebvector_ANF);
		int M_greifend = bestimmeAnzahlGreifMass(AnzPixel);
		
		//Anfangsloesung wird berechnet
		CString varianteWichtung = _T("MaxErrEff");
		CString varianteKonkAufschlag = _T("AnteilKostendifferenz");
		vector<double> artflaeche = NullvektorDouble(anzahl_arten);
		double konkFak = 0.4;
		HeurMFBudgetwichtung(zahlungen_ANF, 
						     flaechen_ANF, 
						  	varianteWichtung,
							varianteKonkAufschlag,
							gewichte,
							konkFak,
							budget,
							tzahlung,
							massnahmenergebvector_ANF,
							pixellisten_mit_position,
							ergebnisliste,
							pixelpromassnahme);
		
		double AnfKosten = gesammtkosten( //Simulation der Anfangsloesung
							pixellisten_mit_position, 
							ergebnisliste,
							artflaeche, 
							flaechen_ANF, 
							pixelpromassnahme, 
							zeilen, 
							spalten,
							anzahl_arten);

		AnfFlaeche = 0;  
		for( int a = 0; a < anzahl_arten; a++)//Berechnen der Gesamtflaeche
			AnfFlaeche += artflaeche[ a] * gewichte[ a];
		
		massnahmenergebvector_ARBEIT = massnahmenergebvector_ANF;
		zahlungen_ARBEIT = zahlungen_ANF;
		flaechen_ARBEIT = flaechen_ANF;

		str.Format("Anfangsloesung bestimmt und simuliert. Flaeche=%f, Kosten=%f", AnfFlaeche, AnfKosten);
		schreibeInDatei(filename, str);	
		str.Format("%s", AUPtoString(mliste, zahlungen_ANF, flaechen_ANF) );
		schreibeInDatei(filename, str);	

		double AnfTemp = berechneAnfangstemperatur(AnfFlaeche, 0.33);
		
		for(int i=0; i<anzItZahl; i++)
		{
			double erreichteFlaeche = AnfFlaeche;
			double erreichteKosten = AnfKosten;
			
			verbessereTest( ItZahlen[i],
						AnfTemp,
						varianteVar,
						zahlungen_ARBEIT,
						flaechen_ARBEIT,
						erreichteFlaeche,
						erreichteKosten,
						tzahlung,
						mliste,
						gewichte,
						budget,
						anzahl_arten,
						zeilen,
						spalten,
						artflaeche,
						massnahmenergebvector_ARBEIT,
						pixellisten_mit_position,
						ergebnisliste,
						pixelpromassnahme);
			EndFlaeche[i] = erreichteFlaeche;
			EndAusgabe[i] = erreichteKosten;
			/*
			datenbank *daten = new datenbank;
			daten->save_optimierungsfortgang(0, 
											AUPtoString(mliste, zahlungen_ARBEIT, flaechen_ARBEIT),
											EndFlaeche[i],
											-1,
											EndAusgabe[i]);
			delete daten;
		
			*/
		
			str.Format(_T("Variation mit %d Iterationen durchgefuehrt. AnfFlaeche=%f, EndFlaeche=%f, EndAusgabe=%f") , 
				ItZahlen[i], AnfFlaeche, EndFlaeche[i], EndAusgabe[i]);
			schreibeInDatei(filename , str);
		
			loescheMassnahmenlisten(massnahmenergebvector_ARBEIT);
			massnahmenergebvector_ARBEIT = massnahmenergebvector_ANF;
			zahlungen_ARBEIT = zahlungen_ANF;
			flaechen_ARBEIT = flaechen_ANF;
			
		}

		if(M_greifend > 0)
		{
			AnzRealDurgefWiederholJeAnzGreifMass[0]++;//Zaehlung insgesamt Wdh
			AnzRealDurgefWiederholJeAnzGreifMass[M_greifend]++;//Zaehlung nach Anz Greif Mass
		}

		//Statistik anlegen für aktuelles Szenario
		for(int i=0; i<anzItZahl; i++)
		{
			VerbesserungProzent[i] = EndFlaeche[i]/AnfFlaeche;
			Effizienz[i] = VerbesserungProzent[i]/ItZahlen[i];
		}

		//Speichern der aktuellen Statistik in der globalen Statistik
		for(int i=0; i<anzItZahl && M_greifend != 0; i++)
		{
			if(VerbesserungProzent[i] < Statistik[0][i][0] || Statistik[0][i][0] < 0)//Minimum
				Statistik[0][i][0] = VerbesserungProzent[i];
			if(VerbesserungProzent[i] > Statistik[0][i][1])//Maximum
				Statistik[0][i][1] = VerbesserungProzent[i];
			Statistik[0][i][2] += VerbesserungProzent[i];//Durchschnitt bzw. erstmal Summe

			if(Effizienz[i] < Statistik[0][i][3] || Statistik[0][i][3] < 0)//Minimum
				Statistik[0][i][3] = Effizienz[i];
			if(Effizienz[i] > Statistik[0][i][4])//Maximum
				Statistik[0][i][4] = Effizienz[i];
			Statistik[0][i][5] += Effizienz[i];//Durchschnitt bzw. erstmal Summe
		}

		//Speichern der aktuellen Statistik in der Statistik zur entsprechenden Anzahl greifender Massnahmen
		for(int i=0; i<anzItZahl && M_greifend != 0; i++)
		{
			if(VerbesserungProzent[i] < Statistik[M_greifend][i][0] || Statistik[M_greifend][i][0] < 0)//Minimum
				Statistik[M_greifend][i][0] = VerbesserungProzent[i];
			if(VerbesserungProzent[i] > Statistik[M_greifend][i][1])//Maximum
				Statistik[M_greifend][i][1] = VerbesserungProzent[i];
			Statistik[M_greifend][i][2] += VerbesserungProzent[i];//Durchschnitt bzw. erstmal Summe

			if(Effizienz[i] < Statistik[M_greifend][i][3] || Statistik[M_greifend][i][3] < 0)//Minimum
				Statistik[M_greifend][i][3] = Effizienz[i];
			if(Effizienz[i] > Statistik[M_greifend][i][4])//Maximum
				Statistik[M_greifend][i][4] = Effizienz[i];
			Statistik[M_greifend][i][5] += Effizienz[i];//Durchschnitt bzw. erstmal Summe
		}

		pixellisten_mit_position.clear();
		ergebnisliste.clear();
		pixelpromassnahme.clear();
	}//Naechste Wiederholung

	//Bilden der Durchschnitte 
	for(int i=0; i<maxAnzGreifMass+1; i++)
	{
		for(int j=0; j<anzItZahl; j++)
		{
			if(AnzRealDurgefWiederholJeAnzGreifMass[i] > 0)
			{
				Statistik[i][j][2] = Statistik[i][j][2] / AnzRealDurgefWiederholJeAnzGreifMass[i];
				Statistik[i][j][5] = Statistik[i][j][5] / AnzRealDurgefWiederholJeAnzGreifMass[i];
			}
		}
	}

	//Speichern in DB
	AfxMessageBox( _T("Test der Iterationszahl beendet. --> Nach OK in DB!") , MB_OK, 0);

	datenbank *daten = new datenbank;
	daten->save_itzahltest(Statistik, ItZahlen); 
	delete daten;
	// ...
	return;
}
	

//ANFANGSHEURISTIKEN

//Berechnet eine Anfangsloesung zur Maximierung der Flaeche
//AUP wird in zahlungen und flaechen abgelegt.
//massnahmenergebvector muss sortiert sein.
//Im Laufe des Algorithmus werden die Vektoren kostendifferenz, kostenmax und max_flaeche gefuellt
// (Diese sollen mit zurueckgeliefert werden.)
void simulation::HeurMFAstrid(vector<double> &zahlungen, 
							vector<int> &flaechen, 
							vector<double> &kostendifferenz,
							vector<double> &kostenmax,
							vector<int> &max_flaeche,
							int budget,
							int tzahlung,
							vector < vector < modell::masspixelergeb >> &massnahmenergebvector,
							vector< simulation::mapixelliste_mit_pos> &pixellisten_mit_position,
							vector< modell::masspixelergeb> &ergebnisliste,
							vector< int> &pixelpromassnahme)
{
	
	CString filename = _T("AnfHeurTestProt.txt");
	CString str;

    int anzMass = massnahmenergebvector.size();
	zahlungen = NullvektorDouble(anzMass);
	flaechen = NullvektorInt(anzMass);
	kostendifferenz.clear();
	kostenmax.clear();
	max_flaeche.clear();

	//Bestimmen wie viele Massnahmen ueberhaupt greifen
    int greifende_massnahmen = 0;

	vector< vector< modell::masspixelergeb>>::iterator me; //Iterator für die Liste der Kostenlisten aller Massnahmen
    for( me = massnahmenergebvector.begin(); me != massnahmenergebvector.end(); me++)
    { 
        if( (*me).size() > 0)
		{
            greifende_massnahmen = greifende_massnahmen + 1;
		}
    }

	//str.Format("Anz greif Maß bestimmt.");
	//schreibeInDatei(filename, str);


	int i = 0;
	//Festlegen der Zahlungen
    for( me = massnahmenergebvector.begin();
            me != massnahmenergebvector.end(); me++)
    {
        if( (*me).size() > 0)
        {
            
            if( (*me)[ 0].gewinn < 0)
            {
                double kd = (((*me).back().gewinn) * (-1))
                        - (((*me)[ 0].gewinn) * (-1));
                //str.Format( _T( "%.2f"), kd);
                //AfxMessageBox(str,MB_YESNO,0);
                zahlungen[ i] = (((*me)[ 0].gewinn) * (-1)) + 1 + tzahlung
                        + (kd / 2);

                kostendifferenz.push_back( kd);
                kostenmax.push_back( ((*me).back().gewinn) * (-1));
                max_flaeche.push_back(
                        static_cast< int>( budget
                                / (((*me).back().gewinn) * (-1))));
            } else
            {
                if( (*me)[ 0].gewinn == 0) //hier kann noch an den Werten geändert werden!!!!!!
                {

                    double kd = (((*me).back().gewinn) * (-1));
                    zahlungen[ i] = 1 + tzahlung + (kd / 2);
                    kostendifferenz.push_back( kd);
                    kostenmax.push_back( ((*me).back().gewinn) * (-1));
                    max_flaeche.push_back( static_cast< int>( budget / 1));
                } else
                {

                    double kd = (((*me).back().gewinn) * (-1));
                    zahlungen[ i] = 1 + tzahlung + (kd / 2);
                    kostendifferenz.push_back( kd);
                    kostenmax.push_back( ((*me).back().gewinn) * (-1));
                    max_flaeche.push_back( static_cast< int>( budget / 1));
                }
            }

            if( (*me).size()
                    < ((static_cast< int>( budget / zahlungen[ i]))
                            / greifende_massnahmen) / 6.25)//6.25 statt 4
                flaechen[ i] = ((*me).size()); //die maximale Fläche für die Massnahme, alle Pixel auf denen die Massnahme positiv ist
            else
                flaechen[ i] = ((static_cast< int>( budget / zahlungen[ i]))
                        / greifende_massnahmen) / 6.25;//6.25 statt 4

        } else
        {
            //AfxMessageBox("Bin hier",MB_YESNO,0);
            zahlungen[ i] = 0;
            flaechen[ i] = 0;
            max_flaeche.push_back( 0);
            kostenmax.push_back( 0);
            kostendifferenz.push_back( 0);

		}
        i++;
    }

	//str.Format("Zahlungen und Flaechen bestimmt.");
	//schreibeInDatei(filename, str);

	//zeigeVektor(zahlungen);
	//zeigeVektor(flaechen);

    //AfxMessageBox("Astrid-Algo: Zahlungen und Flaechen wurden festgelegt.",MB_YESNO,0);

	vector< modell::masspixelergeb>::iterator mp; //Iterator für die Kostenliste einer Massnahme
  
    for( i = 0; i < anzMass; i++)//Durchlaufen aller Massnahmen
    {
        if( !massnahmenergebvector[ i].empty())
        {
            for( mp = massnahmenergebvector[ i].begin();
                    mp < massnahmenergebvector[ i].end(); mp++)
            {
                (*mp).gewinn = (*mp).kosten + zahlungen[ i] - tzahlung; // die neue Zahlung muss dazu addiert werden
                (*mp).m.zahlung = zahlungen[ i];
            }
        }
        mapixelliste_mit_pos mmp;
        mmp.massnahmenergebnis = massnahmenergebvector[ i];
        mmp.position = 0;
        pixellisten_mit_position.push_back( mmp);
        pixelpromassnahme.push_back( 0);

    }

	//str.Format("Formales geklaert.");
	//schreibeInDatei(filename, str);

	return;
}




void simulation::HeurMFBudgetwichtung(vector<double> &zahlungen, 
									  vector<int> &flaechen, 
								      CString varianteWichtung,
									  CString varianteKonkAufschlag,
									  vector<double> &gewichte,
									  double konkFak,
									  int budget,
									  int tzahlung,
									  vector < vector < modell::masspixelergeb >> &massnahmenergebvector,
									  vector< simulation::mapixelliste_mit_pos> &pixellisten_mit_position,
									  vector< modell::masspixelergeb> &ergebnisliste,
									  vector< int> &pixelpromassnahme)
{

	//CString str;
	//CString filename = _T("AnfHeurTestProt.txt");
	
    int anzMass = massnahmenergebvector.size();
	zahlungen = NullvektorDouble(anzMass);
	flaechen = NullvektorInt(anzMass);

	vector<int> AnzPixel = berechneAnzPixel(massnahmenergebvector);

	CString varianteKonku = _T("MitKonku");
	vector<double> Teilbudgets = berechneTeilbudgets(budget,
													 tzahlung,
													 varianteWichtung,
													 varianteKonku,
													 gewichte,
													 massnahmenergebvector);
	//str.Format("\tTeilbudgets berechnet.");
	//schreibeInDatei(filename, str);	

	//Berechnen der Anzahl der konkurrierenden, greifenden Maßnahmen fuer jeden Pixeltyp
	vector<int> Konkurrenz = berechneGreifendeKonkurrenz(massnahmenergebvector);
	//str.Format("\tKonkurrenz berechnet.");
	//schreibeInDatei(filename, str);
	
	//Berechnen der Kostendifferenz fuer alle Massnahmen
	vector<double> Kostendifferenz = berechneKostendifferenzAst(massnahmenergebvector);

	//str.Format("\tKostendifferenz berechnet.");
	//schreibeInDatei(filename, str);	

	//Berechnen, welche Massnahme auf welchem Pixeltyp durchgefuehrt werden kann
	//-1 == nicht greifend, 0 == Wiese, 1 == Weide, 2 == Maehweide
	vector<int> MassTyp = berechneTypen(massnahmenergebvector);

	//str.Format("\tMassnahmentypen berechnet.");
	//schreibeInDatei(filename, str);	

	double Konk0 = 10;
	
	vector<double> aufschlaege = NullvektorDouble(anzMass);//Berechnen der Konkurrenzaufschlaege, falls gewuenscht
	if(varianteKonkAufschlag.Compare( _T("Pauschal") ) == 0)//konkFakt wird verwendet
	{
		for(int i=0; i<anzMass; i++)
		{
			if( MassTyp[i] != -1 && Konkurrenz[ MassTyp[i] ] > 1)//Massnahme greift nicht
			{
				//aufschlaege[i] = konkFak*log( double( Konkurrenz[ MassTyp[i] ] ) );
				aufschlaege[i] = logZwischenNullUndXMax( Konkurrenz[ MassTyp[i] ] , Konk0, konkFak);
			}
		}
	}
	else if(varianteKonkAufschlag.Compare( _T("AngleichungKostendifferenz") ) == 0)
	{
		for(int i=0; i<3; i++)//Durchlaufen des Konkurrenzvektors
		{
			if(Konkurrenz[i]>1)//D.h., es gibt mehr als eine Massnahme fuer den gleichen Pixeltyp
			{
				double minKD;
				int minKDindex;
				bool first = true;
				//Bestimmen der minimalen Kostendifferenz
				for(int j=0; j<anzMass; j++)
				{
					if(MassTyp[j] == i)//Massnahme mit Index i gehoert zum aktuell betrachteten Typ
					{
						if(first || Kostendifferenz[j] < minKD)
						{
							minKD = Kostendifferenz[j];
							minKDindex = j;
							first = false;
						}
					}
				}//Minimale Kostendifferenz bestimmt

				for(int j=0; j<anzMass; j++)
				{
					if(MassTyp[j] == i)//Massnahme mit Index i gehoert zum aktuell betrachteten Typ
					{
						if(j != minKDindex)
						{
							//aufschlaege[j] = Konkurrenz[ MassTyp[i] ] * konkFak * (Kostendifferenz[j] - minKD);
							aufschlaege[j] = logZwischenNullUndXMax( 
								Konkurrenz[i] , Konk0, konkFak*(Kostendifferenz[j] - minKD) );
						}
					}
				}//Aufschlaege fuer Massnahmen gleichen Pixeltyps bestimmt, sofern Konkurrenz besteht
			}
		}
		//zeigeVektor(aufschlaege);
	}
	else if(varianteKonkAufschlag.Compare( _T("AnteilKostendifferenz") ) == 0)
	{
		for(int i=0; i<anzMass; i++)
		{
			if(MassTyp[i] != -1)
			{
				if(Konkurrenz[ MassTyp[i] ] > 1)
				{
					//aufschlaege[i] = Konkurrenz[ MassTyp[i] ] * konkFak * Kostendifferenz[i];
					aufschlaege[i] = logZwischenNullUndXMax( Konkurrenz[ MassTyp[i] ] , Konk0, konkFak*Kostendifferenz[i] );
				}
			}
		}
	}

	//str.Format("\tAufschlaege berechnet.");
	//schreibeInDatei(filename, str);

	vector<double> aufschlaegemax = berechneMaximaleZahlungen(massnahmenergebvector, tzahlung, 1.0/2.0);
	//Zum Check der Schranken
	for(int i=0; i<anzMass; i++)
	{
		if(aufschlaege[i] > aufschlaegemax[i])
			aufschlaege[i] = aufschlaegemax[i];
	}

	//str.Format("\tSchranken fuer Zahlungen ueberprueft.");
	//schreibeInDatei(filename, str);

	//Fuer jede Massnahme wird nun das Pixel bestimmt, bei dem das Teilbudget am besten ausgeschoepft werden wuerde
	double zahlung;
	for(int i=0; i<anzMass; i++)
	{
		if( MassTyp[i] != -1)//Ausschluss nicht greifender Massnahmen
		{
			flaechen[i] = 1 + bestimmeIndexAusschoepfendesPixel(Teilbudgets[i], tzahlung, 
						aufschlaege[i], massnahmenergebvector[i]);
			if(flaechen[i]>0)//Kann sein, dass schon das erste Pixel das Budget ueberschreitet
				zahlungen[i] = berZahlung(massnahmenergebvector[i][flaechen[i]-1], tzahlung, aufschlaege[i]);
		}
	}

	//str.Format("\tZahlungen und Flaechen bestimmt.");
	//schreibeInDatei(filename, str);
	  
	klaereFormalitaeten(zahlungen, tzahlung, massnahmenergebvector,
						pixellisten_mit_position, pixelpromassnahme);
	return;
}



void simulation::HeurMFBudgetwichtungOhneKonku(vector<double> &zahlungen, 
												vector<int> &flaechen, 
												CString varianteWichtung,
												vector<double> &gewichte,
												int budget,
												int tzahlung,
												vector < vector < modell::masspixelergeb >> &massnahmenergebvector,
												vector< simulation::mapixelliste_mit_pos> &pixellisten_mit_position,
												vector< modell::masspixelergeb> &ergebnisliste,
												vector< int> &pixelpromassnahme)
{

	CString filename = "HeurOhneKonkuProt.txt";
	CString str;
	schreibeInDatei(filename , _T("Heuristik Ohne Konku gestartet!"));
	
    int anzMass = massnahmenergebvector.size();
	zahlungen = NullvektorDouble(anzMass);
	flaechen = NullvektorInt(anzMass);

	CString varianteKonku = _T("OhneKonku");
	vector<double> Teilbudgets = berechneTeilbudgets(budget, tzahlung, 
													varianteWichtung, 
													varianteKonku,
													gewichte,
													massnahmenergebvector);

	for(int i=0; i<anzMass; i++)//Zahlungen bestimmen
	{
		if( massnahmenergebvector[i].size() > 0 && Teilbudgets[i]>0)
		{
			flaechen[i] = 1 + bestimmeIndexAusschoepfendesPixel(Teilbudgets[i], tzahlung, 0, massnahmenergebvector[i]);
			if(flaechen[i]>0)//Kann sein, dass schon das erste Pixel das Budget ueberschreitet
				zahlungen[i] = berZahlung(massnahmenergebvector[i][flaechen[i]-1], tzahlung, 0);
		}
	}
	
	
    //AfxMessageBox("Astrid-Algo: Zahlungen und Flaechen wurden festgelegt.",MB_YESNO,0);
	//Formales:
	klaereFormalitaeten(zahlungen, tzahlung, massnahmenergebvector,
						pixellisten_mit_position, pixelpromassnahme);

	return;
}



//Berechnet Zahlung so, dass mpe Teil des Landnutzungsmusters werden kann
double simulation::berZahlung(modell::masspixelergeb &mpe, int tzahlung, double aufschlag)
{
	double zahlung = (-1) * mpe.kosten;
	if(zahlung < 0)
		zahlung = 0;
	zahlung += tzahlung + 0.001 + aufschlag;
	return zahlung;
}

//Bestimmt den Index des Pixel, das das Budget gerade noch ausschoepft
//Liefert -1, wenn jedes Pixel budget ueberschreitet
int simulation::bestimmeIndexAusschoepfendesPixel(double budget, 
												  int tzahlung,
												  double aufschlag,
												  vector<modell::masspixelergeb> &ergebliste)
{
	//CString filename = _T("bestimmeAusschoepfendesPixelProt.txt");
	//schreibeInDatei(filename, _T(""));
	//schreibeInDatei(filename, _T("Ausschoepfendes Pixel wird gesucht."));
	//CString str;

	//Loewenfang-Methode
	bool gefunden = false;
	bool allesAbgesucht = false;
	int leftIndex = 0;
	int rightIndex = ergebliste.size()-1;
	int midIndex;

	double zahlung1;
	double val1;

	double zahlung2;
	double val2;

	while(!gefunden && !allesAbgesucht)
	{
		midIndex = (rightIndex + leftIndex)/2;

		zahlung1 = berZahlung(ergebliste[midIndex], tzahlung, aufschlag);
		val1 = budget - 6.25 *(midIndex+1) * zahlung1;

		zahlung2 = berZahlung(ergebliste[midIndex+1], tzahlung, aufschlag);
		val2 = budget - 6.25 *(midIndex+2) * zahlung2;

		//str.Format("left=%d,right=%d,mid=%d,zahlung1=%f,zahlung2=%f,val1=%f,val2=%f", 
		//	leftIndex, rightIndex, midIndex, zahlung1, zahlung2, val1, val2);
		//schreibeInDatei(filename, str);

		gefunden = val1 >= 0 && val2 < 0;

		if(!gefunden)//midIndex ist nicht das "ausschoepfende" Pixel
		{
			if(val1 < 0 && val2 < 0)
				rightIndex = midIndex - 1;
			else
				leftIndex = midIndex + 1;
		}

	    allesAbgesucht = leftIndex > rightIndex || leftIndex == ergebliste.size() - 1;
	}

	if(gefunden)
		return midIndex;
	if(leftIndex == 0)//Nicht mal das erste Pixel kann Budget einhalten
		return -1;
	if(rightIndex == ergebliste.size()-1)//Auch nicht das letzte Pixel ueberschreitet Budget
		return ergebliste.size()-1;

	/*
	bool gefunden = false;
	int index = -1;
	int j = 0;
	double zahlung;
	while(!gefunden && j < ergebliste.size())//Durchlaufen der Pixel einer Massnahme
	{
		zahlung = berZahlung(ergebliste[j], tzahlung, aufschlag);
		double val = budget - 6.25 *(j+1) * zahlung;
		if( val < 0)//Teilbudget ueberschritten
		{
			gefunden = true;
			index = j-1;
		}
		j++;
	}
	if(!gefunden)
		index = ergebliste.size()-1;
	return index;
	*/
}

//Berechnet einen Vektor mit Teilbudgets, der das budget aufteilt
vector<double> simulation::berechneTeilbudgets(double budget,
											   int tzahlung, 
											   CString varianteWichtung,
											   CString varianteKonku,
											   vector<double> &gewichte,
											   vector<vector<modell::masspixelergeb>> &massnahmenergebvector)
{
	//CString filename = _T("AnfHeurTestProt.txt");
	//CString str;
	//schreibeInDatei(filename , _T("Teilbudgets berechnen gestartet!"));

	vector<double>::iterator buds;
	vector<vector<modell::masspixelergeb>>::iterator me;
	vector<modell::masspixelergeb>::iterator mp;
	int anzMass = massnahmenergebvector.size();
	vector<double> Teilbudgets = NullvektorDouble(anzMass);
	
	bool MaxErrEff = varianteWichtung.Compare(_T("MaxErrEff")) == 0;
	bool MaxErrEffFlaeche = varianteWichtung.Compare(_T("MaxErrEffFlaeche")) == 0;
	bool MaxErrEffGew = varianteWichtung.Find(_T("MaxErrEffGew")) != -1;

	if(MaxErrEff || MaxErrEffFlaeche)//Einfach aufsummieren der Fläche je Maßnahme
	{
		//Bestimmen der maximal erreichbaren effektiven Flache jeder Massnahme
		buds = Teilbudgets.begin();
		for(me=massnahmenergebvector.begin(); me!=massnahmenergebvector.end(); me++)
		{		
			if( (*me).size() > 0)
			{
				for(mp=(*me).begin(); mp!=(*me).end(); mp++)
				{
					(*buds) += modell::berechneFlaeche( (*mp).artenq, gewichte );
				}
			}
			buds++;
		}
	}
	else if(MaxErrEffGew)//Wichtung nach Indexen fur die Flaechen
	{
		int posIstgleich = varianteWichtung.Find( _T("=") );
		CString strPara = varianteWichtung.Mid(posIstgleich+1);
		//AfxMessageBox(strPara, MB_OK, 1);
		double GewichtErstesPixel = atoi(strPara);// > 1 (letztes Pixel hat immer Wichtung Eins)
		buds = Teilbudgets.begin();
		for(me=massnahmenergebvector.begin(); me!=massnahmenergebvector.end(); me++)
		{		
			int laengeListe = (*me).size();
	
			if(laengeListe>1)
			{
				int i = 0;
				for(mp=(*me).begin(); mp!=(*me).end(); mp++)
				{

					(*buds) += (GewichtErstesPixel - i * (GewichtErstesPixel-1.0) / double(laengeListe-1) )
								* modell::berechneFlaeche( (*mp).artenq, gewichte );
					i++;
				}
			}
			else if(laengeListe == 1)
			{
				(*buds) = modell::berechneFlaeche( (*me).front().artenq, gewichte) ;
			}	

			buds++;
						
			/*
			if( laengeListe > 0)
			{
				double delta = GewichtErstesPixel/laengeListe;
				int i = 0;
				for(mp=(*me).begin(); mp!=(*me).end(); mp++)
				{
					double gewicht = (laengeListe-i)*delta;
					(*buds) += gewicht * modell::berechneFlaeche( (*mp).artenq, gewichte );
					i++;
				}
			}
			buds++;
			*/
		}
		//zeigeVektor(Teilbudgets);
	}

	if(MaxErrEff || MaxErrEffGew)//Es muss noch durch die Kosten geteilt werden
	{
		//str.Format("Im Eff.Pfad");
		//schreibeInDatei(filename , str);
		buds = Teilbudgets.begin();

		for(me=massnahmenergebvector.begin(); me!=massnahmenergebvector.end(); me++)
		{		
			if((*me).size() > 0)
			{
				double zahlung = berZahlung( (*me).back(), tzahlung, 0);
				//str.Format("zahlung=%f", zahlung);
				//schreibeInDatei(filename , str);

				(*buds) = (*buds) / (6.25 * zahlung * (*me).size() ) ;
			}
			buds++;		
			//zeigeVektor(Teilbudgets);
		}

	}

	if(varianteKonku.Compare(_T("MitKonku")) == 0)
	{
		//Nix machen
	}
	else if(varianteKonku.Compare(_T("OhneKonku")))//Beste Massnahmen bestimmen und Rest loeschen
	{
		
		vector<int> besteMassNachTyp(3);
		besteMassNachTyp[0] = -1;//Wiese
		besteMassNachTyp[1] = -1;//Weide
		besteMassNachTyp[2] = -1;//Maehweide
		vector<double> besteFlaecheNachTyp(3);
		besteFlaecheNachTyp[0] = 0;
		besteFlaecheNachTyp[1] = 0;
		besteFlaecheNachTyp[2] = 0;

		//Fuer jeden Pixeltyp (Wiese, Weide, Maehweide) die beste Maßnahme suchen
		for(int i=0; i<anzMass; i++)
		{
			if(massnahmenergebvector[i].size() > 0)
			{
				//str.Format("i=%d %s", i, massnahmenergebvector[i][0].m);
				//schreibeInDatei(filename , str);

				if(massnahmenergebvector[i][0].m.aufWiese() )
				{
					//str.Format("aufWiese");
					//schreibeInDatei(filename , str);

					if(Teilbudgets[i] > besteFlaecheNachTyp[0])
					{
						besteMassNachTyp[0] = i;
						besteFlaecheNachTyp[0] = Teilbudgets[i];
					}
				}
				else if(massnahmenergebvector[i][0].m.aufWeide() )
				{
					//str.Format("aufWeide");
					//schreibeInDatei(filename , str);

					if(Teilbudgets[i] > besteFlaecheNachTyp[1])
					{
						besteMassNachTyp[1] = i;
						besteFlaecheNachTyp[1] = Teilbudgets[i];
					}

				}
				else if(massnahmenergebvector[i][0].m.aufMaehweide() )
				{
					//str.Format("aufMaehweide");
					//schreibeInDatei(filename , str);

					if(Teilbudgets[i] > besteFlaecheNachTyp[2])
					{
						besteMassNachTyp[2] = i;
						besteFlaecheNachTyp[2] = Teilbudgets[i];
					}
				}
				else
				{
					AfxMessageBox("Bei Anf.Heur ohne Konku haut was nicht hin.",MB_YESNO,0);
				}
			}
		}

		Teilbudgets = NullvektorDouble(anzMass);
		Teilbudgets[besteMassNachTyp[0]] = besteFlaecheNachTyp[0];
		Teilbudgets[besteMassNachTyp[1]] = besteFlaecheNachTyp[1];
		Teilbudgets[besteMassNachTyp[2]] = besteFlaecheNachTyp[2];
			
	}

	//Berechnen der Teilbudgets
	double sum = accumulate(Teilbudgets.begin(), Teilbudgets.end(), 0.0);

	for(buds=Teilbudgets.begin(); buds!=Teilbudgets.end() && sum>0; buds++)
		(*buds) = budget * (*buds) / sum;

	return Teilbudgets;
}



//Variation von AUP
//Bestimmen einer neuen Loesung (so wie es am Anfang war)
//Vektoren zahlung1 und mengeneu werden veraendert
void simulation::variiereZahlungenFlaechenAstrid(vector<double> &zahlung1,
												 vector<int> &mengeneu,
												 bool besser, bool zwischen,
												 int tzahlung, 
												 vector<double> kostenmax,
												 vector<double> kostendifferenz,
												 vector<int> max_flaeche,
												 vector<vector<modell::masspixelergeb>> &massnahmenergebvector2, 
												 vector< simulation::mapixelliste_mit_pos> &pixellisten_mit_position2,
												 vector< int> &pixelpromassnahme2)
{
	srand (time( NULL) );
	int m1 = mengeneu.size();
	int anzahl = m1;
    if( m1 == 0)
        m1 = 1;
    int m_halbe = m1 / 2;
    if( m_halbe == 0)
        m_halbe = 1;

	int addorsub;
	int zahl;
    int meng;
    int faktormeng;
    int faktorzahl;

    if( besser == false && zwischen == false)
    {
        for( int x = 0; x < m_halbe; x++)
        {
            zahl = rand() % anzahl; //Zufallszahl zwischen 0 und Anzahl an Massnahmen
            //AfxMessageBox("hier12",MB_YESNO,0);

            faktorzahl = ((double) rand() / ((double) RAND_MAX) / 2) + 0.1; //Zufallszahl zwischen 0.1 und 2
            //Die Änderung der Zahlung ist Abbhängig von der Varianz in den Kosten für eine Massnahme
            addorsub = rand() % 2;
            if( addorsub == 1)
            {
                zahlung1[ zahl] = zahlung1[ zahl]
                        + (faktorzahl * kostendifferenz[ zahl]);
                if( zahlung1[ zahl] > kostenmax[ zahl])
                    zahlung1[ zahl] = kostenmax[ zahl] + tzahlung + 100;
            } else
            {
                zahlung1[ zahl] = zahlung1[ zahl]
                        - (faktorzahl * kostendifferenz[ zahl]);

                if( zahlung1[ zahl] < 0)
                    zahlung1[ zahl] = 0;
            }
        }
    }
    if( besser == true)
    {
        zahl = rand() % anzahl;
        addorsub = rand() % 2;
        if( addorsub == 1)
        {

            zahlung1[ zahl] = zahlung1[ zahl]
                    + (faktorzahl * kostendifferenz[ zahl]);
            if( zahlung1[ zahl] > kostenmax[ zahl])
                zahlung1[ zahl] = kostenmax[ zahl] + tzahlung + 100;

        } else
        {
            zahlung1[ zahl] = zahlung1[ zahl]
                    - (faktorzahl * kostendifferenz[ zahl]);

            if( zahlung1[ zahl] < 0)
                zahlung1[ zahl] = 0;

        }
    }
    if( zwischen == true)
    {
        for( int x = 0; x < m_halbe; x++)
        {
            zahl = rand() % anzahl;
            addorsub = rand() % 2;
            if( addorsub == 1)
            {

                zahlung1[ zahl] = zahlung1[ zahl] + 30;
                if( zahlung1[ zahl] > kostenmax[ zahl])
                    zahlung1[ zahl] = kostenmax[ zahl] + tzahlung + 100;

            } else
            {

                zahlung1[ zahl] = zahlung1[ zahl] - 20;

                if( zahlung1[ zahl] < 0)
                    zahlung1[ zahl] = 0;

            }
        }
    }

	//AfxMessageBox("vor Anzahl",MB_YESNO,0);
    if( besser == false)
    {
        for( int x = 0; x < m_halbe; x++)
        {
            meng = rand() % anzahl; //Zufallszahl zwischen 0 und anzahl an Massnahmen

            //double  faktormeng =  ((double)rand() / ((double)RAND_MAX ));//Zufallszahl zwischen 0 und 1
            if( max_flaeche[ meng] != 0)
            {

                mengeneu[ meng] = rand() % max_flaeche[ meng];

            } else
                mengeneu[ meng] = 0;

        }
    } else
    {
        meng = rand() % anzahl;
        addorsub = rand() % 2;
        if( max_flaeche[ meng] != 0)
        {
            //mengeneu[meng] =  rand() % max_flaeche[meng];	
            if( addorsub == 1)
                mengeneu[ meng] = max_flaeche[ meng];
            else
                mengeneu[ meng] = 0;
        } else
            mengeneu[ meng] = 0;
    }

	//minimale Schranken überprüfen
	for(int i=0; i<m1; i++)
	{
		if(zahlung1[i] < double(tzahlung) )
		{
			zahlung1[i] = 0;
			mengeneu[i] = 0;
		}
	}

	vector< modell::masspixelergeb>::iterator mp;
	 for(int i = 0; i < anzahl; i++)
	 {
        if( !massnahmenergebvector2[ i].empty())
        {
            for( mp = massnahmenergebvector2[ i].begin();
                    mp < massnahmenergebvector2[ i].end(); mp++)
            {
                (*mp).gewinn = (*mp).kosten + zahlung1[ i] - tzahlung; // die neue Zahlung muss dazu addiert werden
                (*mp).m.zahlung = zahlung1[ i];
            }
        }
        //else
        //AfxMessageBox("Keine Pixel",MB_YESNO,0);

        mapixelliste_mit_pos mmp;
        mmp.massnahmenergebnis = massnahmenergebvector2[ i];
        mmp.position = 0;
        pixellisten_mit_position2.push_back( mmp);
        pixelpromassnahme2.push_back( 0);

    }
	return;
}


//Variation eines AUP
//Vektoren zahlungen und flaechen werden veraendert
//zufaellige Anzahl von Massnahmen wird variiert aus Intervall [1 , maxAnzVeraenderterMass]
//max. Staerke der Abweichung der Zahlung kann angegeben werden
//max. Abweichung der Pixelanzahl kann angegeben werden
//maximale Flaechen werden in Abhaengigkeit der Veraenderung der Zahlungen veraendert
void simulation::variiereZahlungenFlaechen(vector<double> &zahlungen,
										   vector<int> &flaechen,
										   vector<int> &AnzPixel,
										   vector<int> &erreichteFlaechen,
										   int maxAnzVeraenderterMass,
										   vector<double> minAbweichungZahlung,
										   vector<double> maxAbweichungZahlung,
										   vector<int> minAnzahlAbweichungFlaeche,
										   vector<int> maxAnzahlAbweichungFlaeche,
										   int tzahlung, 
										   vector<vector<modell::masspixelergeb>> &massnahmenergebvector, 
										   vector< simulation::mapixelliste_mit_pos> &pixellisten_mit_position,
										   vector< int> &pixelpromassnahme)
{
	//CString str;

	/*
	CString filename = _T("variiereZahlungenFlaechenProt.txt");
	schreibeInDatei(filename, _T("") );
	schreibeInDatei(filename, _T("Variation eines AUP beginnt.") );
	*/
	
	int AnzMass = massnahmenergebvector.size();
	int AnzVeraenderterMass = RandomInt(1, maxAnzVeraenderterMass);

	//zu veraendernde Maßnahmen(indizes) bestimmen
	vector<int> Mass;
	for(int i=0; i<AnzMass; i++)
	{
		if(AnzPixel[i]>0)
			Mass.push_back(i);
	}//Vektor mit den Indizes der greifenden Massnahmen bestimmt
	vector<int> veraenderteMass;
	int AnzMassGreif = Mass.size();
	int k = AnzMassGreif-1;
	for(int i=0; i<AnzVeraenderterMass; i++)
	{
		int nextMassIndex = RandomInt(0,k);
		veraenderteMass.push_back(Mass[nextMassIndex]);
		Mass.erase(Mass.begin()+nextMassIndex);
		k--;
	}

	int addorsub;
	int aktMass;

	double veraenderung;
	double minZahlung;
	int veraenderungFlaeche;

	//str.Format("AnzVeraenderterMass=%d", AnzVeraenderterMass);
	//schreibeInDatei(filename, str);

	//Maßnahmen (Zahlungen und Flaechen) veraendern
	for(int i=0; i<AnzVeraenderterMass; i++)
	{
		//Zahlungen veraendern
		aktMass = veraenderteMass[i];

		//str.Format("aktMass=%d, zahlungen[aktMass]=%f, flaechen[aktMass]=%d", 
		//	aktMass, zahlungen[aktMass], flaechen[aktMass]);
		//schreibeInDatei(filename, str);

		if(zahlungen[aktMass] <= 0)
			zahlungen[aktMass] = berZahlung(massnahmenergebvector[aktMass].front(), tzahlung, 0);
			//Wenn zahlung Null ist, wird sie auf das sinnvolle Minimum gesetzt
			//Mit Wkt. 0.5 wird die zahlung wieder verringert (und dann wieder auf Null gesetzt)
			//Mit Wkt. 0.5 wird sie erhoeht

		addorsub = RandomInt(0,1);//0 -> Add , 1 -> Sub
		veraenderung = RandomDouble(minAbweichungZahlung[i], maxAbweichungZahlung[i]);
		if(addorsub == 1)
			veraenderung = veraenderung * (-1);
		zahlungen[aktMass] = zahlungen[aktMass] + veraenderung;
		
		//Kontrolle sinnvoller Schranken
		minZahlung = berZahlung( massnahmenergebvector[aktMass].front(), tzahlung, 0);
		if(zahlungen[aktMass] < minZahlung)//Massnahme nimmt nicht mehr Teil
		{
			zahlungen[aktMass] = 0;
			flaechen[aktMass] = 0;
		}
		else//Veraendern der Flaechen
		{
			veraenderungFlaeche = RandomInt(minAnzahlAbweichungFlaeche[i], 
							maxAnzahlAbweichungFlaeche[i] );
			addorsub = RandomInt(0,1);//diesbezueglich keine Kopplung
			if(addorsub == 1)
				veraenderungFlaeche = veraenderungFlaeche * (-1);//Verringerrung der Flaeche


			if(erreichteFlaechen[aktMass] < flaechen[aktMass] && veraenderungFlaeche>0)//Aktuelle Flaeche reicht noch aus
					veraenderungFlaeche = 0;
						
			flaechen[aktMass] = flaechen[aktMass] + veraenderungFlaeche;;

			//Kontrolle sinnvoller Schranken
			if(flaechen[aktMass] < 0)
				flaechen[aktMass] = 0;
			else if(flaechen[aktMass] > AnzPixel[aktMass])
				flaechen[aktMass] = AnzPixel[aktMass];
		}		

		//str.Format("aktMass=%d, zahlungen[aktMass]=%f, flaechen[aktMass]=%d", 
			//aktMass, zahlungen[aktMass], flaechen[aktMass]);
		//schreibeInDatei(filename, str);
	}

	klaereFormalitaeten(zahlungen,
						tzahlung,
						massnahmenergebvector,
						pixellisten_mit_position,
						pixelpromassnahme);
	return;
}

//Bestimmen der Sprungstufen der Zahlungen, die nicht mehr als eps voneinander abweichen
void simulation::bestimmeSprungstufenZahlungen(vector<vector<double>> &Sprungstufen, 
												double eps,
												int tzahlung,
												vector<vector<modell::masspixelergeb>> &mev)
{
	int anzMass = mev.size();
	Sprungstufen.clear();
	for(int i=0; i<anzMass; i++)
	{
		vector<double> Stufen_i;
		Stufen_i.push_back( 0.0 );
		double pivotZahlung;
		double aktZahlung;
		bool nextStep = true;
		for(int j=0; j<mev[i].size(); j++)
		{
			if(nextStep)
				pivotZahlung = berZahlung(mev[i][j], tzahlung, 0);

			aktZahlung = berZahlung(mev[i][j], tzahlung, 0);
			nextStep = fabs(aktZahlung-pivotZahlung) > eps;//aktZahlung >=pivotZahlung

			if(nextStep)
				Stufen_i.push_back(aktZahlung);
		}
		Sprungstufen.push_back(Stufen_i);
	}
	return;
}
void simulation::variiereZahlungenFlaechenStufen(
												   vector<vector<double>> &Sprungstufen,
												   vector<double> &zahlungen,
												   vector<int> &flaechen,
												   vector<int> &AnzPixel,
												   vector<int> &erreichteFlaechen,
												   int maxAnzVeraenderterMass,
												   vector<int> minAnzahlAbweichungFlaeche,
												   vector<int> maxAnzahlAbweichungFlaeche,
												   int tzahlung, 
												   vector<vector<modell::masspixelergeb>> &massnahmenergebvector, 
												   vector< simulation::mapixelliste_mit_pos> &pixellisten_mit_position,
												   vector< int> &pixelpromassnahme)
{
	//CString filename = _T("variiereZahlungenFlaechenSprungstufenProt.txt");
	//CString str;
	
	int AnzMass = massnahmenergebvector.size();
	int AnzVeraenderterMass = RandomInt(1, maxAnzVeraenderterMass);

	//zu veraendernde Maßnahmen(indizes) bestimmen
	vector<int> Mass;
	for(int i=0; i<AnzMass; i++)
	{
		if(AnzPixel[i]>0)
			Mass.push_back(i);
	}//Vektor mit den Indizes der greifenden Massnahmen bestimmt
	vector<int> veraenderteMass;
	int AnzMassGreif = Mass.size();
	int k = AnzMassGreif-1;
	for(int i=0; i<AnzVeraenderterMass; i++)
	{
		int nextMassIndex = RandomInt(0,k);
		veraenderteMass.push_back(Mass[nextMassIndex]);
		Mass.erase( Mass.begin()+nextMassIndex );
		k--;
	}

	//zeigeVektor(veraenderteMass);

	int addorsub;
	int aktMass;

	double minZahlung;
	int veraenderungFlaeche;

	//str.Format("AnzVeraenderterMass=%d", AnzVeraenderterMass);
	//schreibeInDatei(filename, str);

	//Maßnahmen (Zahlungen und Flaechen) veraendern
	for(int i=0; i<AnzVeraenderterMass; i++)
	{
		//Zahlungen veraendern
		aktMass = veraenderteMass[i];

		//str.Format("aktMass=%d, zahlungen[aktMass]=%f, flaechen[aktMass]=%d", 
			//aktMass, zahlungen[aktMass], flaechen[aktMass]);
		//schreibeInDatei(filename, str);
	
		//zeigeVektor(Sprungstufen[aktMass]);

		//Suche Sprungstufe (index), der aktueller Zahlung am naechsten kommt
		int minIndex;
		double min;
		double val;
		bool first = true;
		for(int k=0; k<Sprungstufen[aktMass].size(); k++)
		{
			val = fabs(zahlungen[aktMass]-Sprungstufen[aktMass][k]);			
			if(first || val < min)
			{
				minIndex = k;
				min = val;
			}
		}
		//schreibeInDatei(filename, "aktuelle Sprungstufe gefunden.");
		addorsub = RandomInt(0,1);//0 -> eine Sprungstufe hoch , 1 -> eine Sprungstufe runter
		int neuerIndex;
		if(addorsub == 0)
			neuerIndex = minIndex+1;
		else 
			neuerIndex = minIndex-1;

		//Kontrolle Index
		if(neuerIndex < 0)
			neuerIndex = 0;
		else if(neuerIndex > Sprungstufen[aktMass].size()-1)
			neuerIndex = Sprungstufen[aktMass].size()-1;

		zahlungen[aktMass] = Sprungstufen[aktMass][neuerIndex];

		//schreibeInDatei(filename, "Zahlungen veraendert.");
		//zeigeVektor(erreichteFlaechen);
		
		veraenderungFlaeche = RandomInt(minAnzahlAbweichungFlaeche[i], 
						maxAnzahlAbweichungFlaeche[i] );
		addorsub = RandomInt(0,1);//diesbezueglich keine Kopplung
		if(addorsub == 1)
			veraenderungFlaeche = veraenderungFlaeche * (-1);//Verringerrung der Flaeche


		if(erreichteFlaechen[aktMass] < flaechen[aktMass] && veraenderungFlaeche>0)//Aktuelle Flaeche reicht noch aus
				veraenderungFlaeche = 0;
					
		flaechen[aktMass] = flaechen[aktMass] + veraenderungFlaeche;;

		//Kontrolle sinnvoller Schranken
		if(flaechen[aktMass] < 0)
			flaechen[aktMass] = 0;
		else if(flaechen[aktMass] > AnzPixel[aktMass])
			flaechen[aktMass] = AnzPixel[aktMass];

		//str.Format("aktMass=%d, zahlungen[aktMass]=%f, flaechen[aktMass]=%d", 
		//	aktMass, zahlungen[aktMass], flaechen[aktMass]);
		//schreibeInDatei(filename, str);
	}	

	//minimale Schranken überprüfen
	for(int i=0; i<AnzMass; i++)
	{
		if(zahlungen[i] < double(tzahlung) )
		{
			zahlungen[i] = 0;
			flaechen[i] = 0;
		}
	}

	klaereFormalitaeten(zahlungen,
						tzahlung,
						massnahmenergebvector,
						pixellisten_mit_position,
						pixelpromassnahme);
	return;
}
//Kostenmax, Kostendifferenz, und maxFlaeche so bestimmen, wie Astrid
//Wird bei der Variation der AUP nach Astrids Variante verwendet
vector<double> simulation::berechneKostenmaxAst(vector<vector<modell::masspixelergeb>> &massnahmenergebvector)
{
	int anzMass = massnahmenergebvector.size();
	vector<double> kostenmax = NullvektorDouble(anzMass);
	for(int i=0; i<anzMass; i++)
	{
		if(massnahmenergebvector[i].size()>0)
			kostenmax[i] = (-1) * massnahmenergebvector[i].back().kosten;
	}
	return kostenmax;
}
vector<double> simulation::berechneKostendifferenzAst(vector<vector<modell::masspixelergeb>> &massnahmenergebvector)
{
	int anzMass = massnahmenergebvector.size();
	vector<double> kostendifferenz = NullvektorDouble(anzMass);
	for(int i=0; i<anzMass; i++)
	{
		if(massnahmenergebvector[i].size()>0)
		{
			if(massnahmenergebvector[i].front().kosten < 0)
			{
				kostendifferenz[i] = (((massnahmenergebvector[i]).back().kosten) * (-1))
                        - (((massnahmenergebvector[i])[ 0].kosten) * (-1));
			}
			else if(massnahmenergebvector[i].front().kosten == 0)
			{
				kostendifferenz[i] = (((massnahmenergebvector[i]).back().kosten) * (-1));
			}
			else 
			{
				kostendifferenz[i] = (((massnahmenergebvector[i]).back().kosten) * (-1));
			}

			if(kostendifferenz[i]<0)
			{
				CString str;
				str.Format("anf=%f, end=%f", massnahmenergebvector[i].front().gewinn, massnahmenergebvector[i].back().gewinn);
				AfxMessageBox(str, MB_OK, 0);
			}
		}
	}
	return kostendifferenz;

}
vector<int> simulation::berechneMaxFlaecheAst(vector<vector<modell::masspixelergeb>> &massnahmenergebvector, double budget)
{
	int anzMass = massnahmenergebvector.size();
	vector<int> maxFlaeche = NullvektorInt(anzMass);
	for(int i=0; i<anzMass; i++)
	{	 
		if(massnahmenergebvector[i].size()>0)
		{
			if( massnahmenergebvector[i][0].gewinn < 0)
			{
				maxFlaeche[i] = static_cast< int>( budget
								/ ( massnahmenergebvector[i].back().gewinn * (-1) ));
			} 
			else if( massnahmenergebvector[i][0].gewinn == 0) //hier kann noch an den Werten geändert werden!!!!!!
			{
				maxFlaeche[i] = static_cast< int>( budget / 1);
			} 
			else
			{
				maxFlaeche[i] = static_cast< int>( budget / 1);
			}
		}
    }
	return maxFlaeche;
}
vector<int> simulation::berechneAnzPixel(vector<vector<modell::masspixelergeb>> &massnahmenergebvector)
{
	int anzMass = massnahmenergebvector.size();
	vector<int> AnzPixel = NullvektorInt(anzMass);
	for(int i=0; i<anzMass; i++)
		AnzPixel[i] = massnahmenergebvector[i].size();
	return AnzPixel;
}
int simulation::bestimmeAnzahlGreifMass(vector<int> AnzPixel)
{
	int anz=0;
	for(int i=0; i<AnzPixel.size(); i++)
	{
		if(AnzPixel[i] > 0)
			anz++;
	}
	return anz;
}
vector<int> simulation::berechneGreifendeKonkurrenz(vector<vector<modell::masspixelergeb>> &massnahmenergebvector)
{
	int anzMass = massnahmenergebvector.size();
	vector<int> Konkurrenz = NullvektorInt(3);
	for(int i=0; i<anzMass; i++)
	{
		if(massnahmenergebvector[i].size()>0)
			Konkurrenz[ massnahmenergebvector[i].front().m.berechneTyp() ]++;
	}
	return Konkurrenz;
}

vector<int> simulation::berechneTypen(vector<vector<modell::masspixelergeb>> &massnahmenergebvector)
{
	int anzMass = massnahmenergebvector.size();
	vector<int> MassTyp(anzMass);
	for(int i=0; i<anzMass; i++)
	{
		if( massnahmenergebvector[i].size() > 0)
		{
			MassTyp[i] = massnahmenergebvector[i].front().m.berechneTyp();
		}
		else
		{
			MassTyp[i] = -1;//Massnahme greift nicht
		}
	}
	return MassTyp;
}										
vector<double> simulation::berechneMaximaleZahlungen(vector<vector<modell::masspixelergeb>> &massnahmenergebvector, 
												  int tzahlung, double fak)	
{
	int anzMass = massnahmenergebvector.size();
	vector<double> kostenmax = NullvektorDouble(anzMass);
	for(int i=0; i<anzMass; i++)
	{
		if(massnahmenergebvector[i].size()>0)
			kostenmax[i] = fak * berZahlung(massnahmenergebvector[i].back(), tzahlung, 0);
	}
	return kostenmax;
}
											
																				





//statische Funktion erzeugt aus einem AUP einen String
CString simulation::AUPtoString(vector<massnahme> mlist, vector<double> zahlungen, vector<int> flaechen)
{
	CString erg = _T("");
	int N = mlist.size();
	for (int i=0; i<N; i++)
	{
		CString aktStr;
		aktStr.Format("(%s,z= %.2f,F= %d)",mlist.at(i).toString(),zahlungen.at(i), flaechen.at(i));
		erg.Append(aktStr);
	}

	return erg;
}

//statische Funktion gibt ein AUP in einer Messagebox aus.
void simulation::zeigeAUP(vector<massnahme> mlist, vector<double> zahlungen, vector<int> flaechen)
{
	CString ausgabe = AUPtoString(mlist, zahlungen, flaechen);
	AfxMessageBox( ausgabe, MB_YESNO, 0);
}
void simulation::zeigeVektor(vector<double> vec)
{
	CString ausgabe = _T("[");
	for(int i=0; i<vec.size(); i++)
	{
		CString str;
		str.Format("%f, ", vec[i]);
		ausgabe.Append(str);
	}
	ausgabe.Append( _T("]") );
	AfxMessageBox( ausgabe, MB_YESNO, 0);

}

void simulation::zeigeVektor(vector<int> vec)
{
	CString ausgabe = _T("[");
	for(int i=0; i<vec.size(); i++)
	{
		CString str;
		str.Format("%d, ", vec[i]);
		ausgabe.Append(str);
	}
	ausgabe.Append( _T("]") );
	AfxMessageBox( ausgabe, MB_YESNO, 0);

}

void simulation::zeigeMatrix(vector<vector<double>> mat)
{
	CString ausgabe = _T("[");
	for(int i=0; i<mat.size(); i++)
	{
		for(int j=0; j<mat[0].size(); j++)
		{
			CString str;
			str.Format("%f, ", mat[i][j]);
			ausgabe.Append(str);
		}

		CString str;
		str.Format("|");
		ausgabe.Append(str);
	}
	AfxMessageBox( ausgabe, MB_YESNO, 0);
}



//Berechnet den Faktor alpha, sodass bei gegebener Anfangstemperatur T0 und Abbruchtemperatur TMin. 
//eine gewünschte Iterationszahl n0 erreicht wird.
double simulation::calcAlpha(int n0, double T0, double TMin)
{
	return exp( log(TMin/T0) / n0 );
}
double simulation::berechneAnfangstemperatur(double maxVerschlechterung, double Akzeptanzwkt)
{
	return - maxVerschlechterung/log(Akzeptanzwkt);
}

//Bestimmt Wunschpixel (identifiziert durch Indizes im massnahmenergebvector)
//Methode: Effizienteste Einzelpixel
//Vektor maxPosi enthaelt maximale Indizes (Ausschluss zu teurer Pixel, Budgeteinschraenkung) für jede Massnahme
//massnahmenergebvector wird veraendert --> Effizienzen werden hinzugefuegt
vector<int> simulation::berechneWunschpixelEffPixel(vector<int> maxPosi, 
													vector<double> &gewichte,
													vector < vector < modell::masspixelergeb >> &massnahmenergebvector)
{
	
	int M = massnahmenergebvector.size();
	
	//Wird entweder neu berechnet oder aus Argumentliste übernommen
	bool allerersterVersuch = maxPosi.size() == 0;//Falls maxPosis noch keine Elemente enthaelt, 
												//wird fuer jede Massnahme der hoechste Index verwendet

	if( allerersterVersuch )//Durchlaufen aller masspixelergebs im massnahmenergebvector und Bilden der Effizienz
	{
		maxPosi.clear();
		double aktEffFlaeche;//Zwischenspeicher für Effizienzen des aktuellen Pixels

		for(int i=0; i<M; i++)
		{
			maxPosi.push_back( massnahmenergebvector[i].size()-1 );//Index des letzten Pixels auf Liste
	
			for(int j=0; j<=maxPosi[i]; j++)
			{
				aktEffFlaeche = modell::berechneFlaeche(massnahmenergebvector[i][j].artenq, gewichte);
				if(massnahmenergebvector[i][j].kosten > 0)//d.h. eigentlich kleiner Null
				{
					massnahmenergebvector[i][j].eff = 10000.0;
				}
				else
				{
					massnahmenergebvector[i][j].eff = fabs(aktEffFlaeche / massnahmenergebvector[i][j].kosten );
				}
			
				/*
				CString str;
				str.Format( "MaßnahmeNummer = %d, index = %d, aktEffFlaeche = %.4f, Kosten = %.4f, eff = %.4f", 
					i, j, aktEffFlaeche, massnahmenergebvector[i][j].kosten,  
									massnahmenergebvector[i][j].eff);
				AfxMessageBox( str, MB_YESNO, 0);
				*/
			}
			
		}
	}

	

	//Jetzt sind die Effizienzen für alle Pixel berechnet und die effizientesten Pixel sollen
	// gesucht werden.
	vector<int> flaechen(M);
	vector<int> bearbeiteteMass;
	vector<int> vergebenePixelIDs;
	int AnzBestimmterWunschpixel = 0;

	/*
	bool t = isIn(2, bearbeiteteMass);
	CString str1;
	if(t)
	{
		str1.Format( "t = true");
	}
	else
	{
		str1.Format( "t = false");
	}
	AfxMessageBox( str1, MB_YESNO, 0);
	*/

	while(AnzBestimmterWunschpixel < M)
	{
		double effChamp = -1;
		int massChamp = -1;//Nummer
		int indexChamp = -1;
		int pixelIDChamp = -1;

		for(int i=0; i<M; i++)
		{
			if(!isIn(i,bearbeiteteMass))
			{//Nur durchfuehren, wenn Maßnahme nicht schon bearbeitet wurde
			
				for(int j=0; j<=maxPosi[i]; j++)
				{
					/*
					CString str5;
					str5.Format( "MaßnahmeNummer = %d, index = %d, aktEffFlaeche = %f", 
						i, j, massnahmenergebvector[i][j].eff);
					AfxMessageBox( str5, MB_YESNO, 0);
					*/

					if(massnahmenergebvector[i][j].eff > effChamp && 
						!isIn(massnahmenergebvector[i][j].pixelID, vergebenePixelIDs))
					{
						effChamp = massnahmenergebvector[i][j].eff;
						massChamp = i;
						indexChamp = j;
						pixelIDChamp = massnahmenergebvector[i][j].pixelID;
					}
				}
			}
		}

		/*
		CString str;
		str.Format( "massChamp = %d, indexChamp = %d, pixelIDChamp = %d, effChamp = %f", massChamp, 
																		indexChamp, pixelIDChamp, effChamp);
		AfxMessageBox( str, MB_YESNO, 0);
		*/

		flaechen[massChamp] = indexChamp;//Das Pixel an dieser Stelle (Liste von massChamp an Stelle indexChamp)
										 //ist das Wunschpixel fuer Massnahme massChamp
		bearbeiteteMass.push_back(massChamp);
		vergebenePixelIDs.push_back(pixelIDChamp);
		AnzBestimmterWunschpixel++;
	}
	
	return flaechen;
	
}

//Berechnet Wunschpixel, bezieht aber das Budget mit ein.
vector<int> simulation::berechneWunschpixelEffPixelBudget(vector<int> maxPosi, 
														  int budget,	
														  int M_greifend,
														  vector<double> &gewichte,
														  vector < vector < modell::masspixelergeb >> &massnahmenergebvector)
{
	
	CString str;

	int M = massnahmenergebvector.size();
	double bud_teil = (budget+0.0)/(M_greifend+0.0);
	vector<int> posis (M);
	double aktEffFlaeche;//Zwischenspeicher für Effizienzen des aktuellen Pixels
	
	//Wird entweder neu berechnet oder aus Argumentliste übernommen
	bool allerersterVersuch = maxPosi.size() == 0;//Falls maxPosis noch keine Elemente enthaelt, 
												//wird fuer jede Massnahme der hoechste Index verwendet

	if( allerersterVersuch )//Durchlaufen aller masspixelergebs im massnahmenergebvector und Bilden der Effizienz
	{
		maxPosi.clear();
					
		for(int i=0; i<M; i++)
		{

			if(massnahmenergebvector[i].size()>0)
			{

				double min = 100000000;
				int minIndex = -1;
				maxPosi.push_back( massnahmenergebvector[i].size()-1 );//Index des letzten Pixels auf Liste
		
				for(int j=0; j<=maxPosi[i]; j++)
				{
					aktEffFlaeche = modell::berechneFlaeche(massnahmenergebvector[i][j].artenq, gewichte);
					if(massnahmenergebvector[i][j].kosten > 0)//d.h. eigentlich kleiner Null
					{
						massnahmenergebvector[i][j].eff = 10000.0;
					}
					else
					{
						massnahmenergebvector[i][j].eff = fabs(aktEffFlaeche / massnahmenergebvector[i][j].kosten );
					}
				
					/*
					str.Format( "MaßnahmeNummer = %d, index = %d, aktEffFlaeche = %.4f, Kosten = %.4f, eff = %.4f", 
						i, j, aktEffFlaeche, massnahmenergebvector[i][j].kosten,  
										massnahmenergebvector[i][j].eff);
					AfxMessageBox( str, MB_YESNO, 0);
					*/

					//Berechnen der Positionen
					double val = fabs( 6.25 *( j+1) * fabs(massnahmenergebvector[i][j].kosten) - bud_teil);
					if( val < min)
					{
						min = val;
						minIndex = j;
					}

				}

				posis[i] = minIndex;

				/*
				CString str;
				str.Format( "Mass = %d, index = %d", 
						i, posis[i]);
				AfxMessageBox( str, MB_YESNO, 0);
				*/
			}
			else
			{
				maxPosi.push_back(0);
			}

			
		}
	}

	//Für jede Massnahme wurde jetzt ein Ausgangsindex (Pixel) bestimmt, das als Ausgangspunkt fuer 
	// ein Suchintervall der effizientesten Pixel dienen soll
	vector<int> minIndizes;
	vector<int> maxIndizes;
	vector<int> flaechen;

	double proz = 0.04;
	for(int i=0; i<M; i++)
	{
		
		if(massnahmenergebvector[i].size()>0)
		{
			flaechen.push_back(-2);//Kennzeichnung von Massnahmen ohne WP
			int AnzPixel = massnahmenergebvector[i].size();
			int intvall = proz * AnzPixel;

			int u = posis[i] - intvall;
			if(u >= 0)
			{
				minIndizes.push_back( u );
			}
			else
			{
				minIndizes.push_back( 0 );
			}
			int o = posis[i] + intvall;
			if( o <= AnzPixel)
			{
				maxIndizes.push_back( o );
			}
			else
			{
				maxIndizes.push_back( AnzPixel );
			}

			
			str.Format( "AnzPixel=%d, u=%d, o=%d, posis[i]=%d, intvall=%d", AnzPixel, u, o, posis[i], intvall);
			AfxMessageBox( str, MB_YESNO, 0);
			

		}
		else
		{
			maxIndizes.push_back(0);
			minIndizes.push_back(0);
			flaechen.push_back(-1);//Kennzeichnung nichtgreifender Massnahmen
		}
	
	}

	//AfxMessageBox( "Hier", MB_YESNO, 0);


	//Jetzt sind die Effizienzen für alle Pixel berechnet und die effizientesten Pixel sollen
	// in den bestimmten Grenzen gesucht werden.
	vector<int> bearbeiteteMass;
	vector<int> vergebenePixelIDs;
	int AnzBestimmterWunschpixel = 0;
	bool fertig = false;

	while(AnzBestimmterWunschpixel < M_greifend && !fertig)
	{
		double effChamp = -1;
		int massChamp = -1;//Nummer
		int indexChamp = -1;
		int pixelIDChamp = -1;

		for(int i=0; i<M; i++)//Suche nach den effizientesten Pixeln
		{
			if(massnahmenergebvector[i].size()>0 && !isIn(i,bearbeiteteMass))
			{
			
				for(int j=minIndizes[i]; j<=maxIndizes[i]; j++)
				{
					/*
					CString str5;
					str5.Format( "MaßnahmeNummer = %d, index = %d, aktEffFlaeche = %f", 
						i, j, massnahmenergebvector[i][j].eff);
					AfxMessageBox( str5, MB_YESNO, 0);
					*/

					if(massnahmenergebvector[i][j].eff > effChamp && 
						!isIn(massnahmenergebvector[i][j].pixelID, vergebenePixelIDs))
					{
						effChamp = massnahmenergebvector[i][j].eff;
						massChamp = i;
						indexChamp = j;
						pixelIDChamp = massnahmenergebvector[i][j].pixelID;
					}
				}
				
			}
		}

		if(pixelIDChamp == -1)	//Kein Wunschpixel mehr gefunden
		{					
			fertig = true;
		}
		else
		{
			flaechen[massChamp] = indexChamp;//Das Pixel an dieser Stelle (Liste von massChamp an Stelle indexChamp)
												//ist das Wunschpixel fuer Massnahme massChamp
			bearbeiteteMass.push_back(massChamp);
			vergebenePixelIDs.push_back(pixelIDChamp);
		}

		AnzBestimmterWunschpixel++;


		/*
		CString str;
		str.Format( "massChamp = %d, indexChamp = %d, pixelIDChamp = %d, effChamp = %f", massChamp, 
																		indexChamp, pixelIDChamp, effChamp);
		AfxMessageBox( str, MB_YESNO, 0);
		*/
	}
	
	return flaechen;
	
}



//Liefert Zahlungen so, dass das gewünschte Pixel (jeder Maßnahme) Teil des Landnutzungsmusters wird
//Pixel werden durch den Index im flaechen-Vektor (Index in massnahmenergebvector) identifiziert
//Ergebnis des Algorithmus = AUP = (zahlungen, flaechen) [flaechen enthaelt Werte aber schon vorher]
vector<double> simulation::setzeWunschpixelDurch(	vector<int> flaechen,
													int tzahlung,
													vector < vector < modell::masspixelergeb >> &massnahmenergebvector,
													vector< simulation::mapixelliste_mit_pos> &pixellisten_mit_position,
													vector< modell::masspixelergeb> &ergebnisliste,
													vector< int> &pixelpromassnahme)
{
	int M = massnahmenergebvector.size();
	vector<double> zahlungen(M);

	//Setzen aller Zahlungen auf das Minimum (Kosten)
	for(int i=0; i<M; i++)
	{
		if(massnahmenergebvector[i].size()>0)
		{
			zahlungen[i] = static_cast< int>( fabs(massnahmenergebvector[i][flaechen[i]].kosten) ) + tzahlung + 1;
		}
		else
		{
			zahlungen[i] = 0;
		}

		/*
		CString str;
		str.Format( "i=%d, zahlungen[i]=%f, kosten=%f, eff = %f", 
					i, 
					zahlungen[i], 
					massnahmenergebvector[i][flaechen[i]].kosten,
					massnahmenergebvector[i][flaechen[i]].eff);
		AfxMessageBox( str, MB_YESNO, 0);
		*/


	}

	//Test, ob alle Pixel passen
	bool passt = false;//bis hierher zumindest
	int max = 2;
	int versuche = 0;

	while(!passt && versuche < max)//Variieren der Zahlungen, sodass Gewinn auf gewuenschten Pixel Maximum wird
	{

		passt = true;

		//Verändern aller Zahlungen (falls nötig)
		for(int i=0; i<M; i++)
		{

			if( massnahmenergebvector[i].size() > 0)
			{
				int WunschpixelID = massnahmenergebvector[i][flaechen[i]].pixelID;
				int mMax = -1;
				double gewMax = -1;
		
				//Bestimmen der Maßnahme mit dem maximalen  Gewinn auf dem entsprechenden Wunschpixel
				for(int j=0; j<M; j++)
				{
					int index = suchePixelID(WunschpixelID, flaechen[j], massnahmenergebvector[j]);
					
					/*
					CString str;
					str.Format( "i=%d, j=%d, index=%d",
							i, 
							j,
							index); 
					AfxMessageBox( str, MB_YESNO, 0);
					*/

					//Suchen des Wunschpixels in der Liste von Massnahme j

					if(index != -1)//Pixel in Liste wurde gefunden
					{

						/*
						CString str;
						str.Format( "i=%d, j=%d, WunschpixelID(i)=%d, index=%d, c_i(WP)=%f, c_j(WP)=%f",
								i, 
								j,
								WunschpixelID,
								index,
								massnahmenergebvector[i][flaechen[i]].kosten,
								massnahmenergebvector[j][index].kosten); 
						AfxMessageBox( str, MB_YESNO, 0);
						*/
						


						double gewAkt = zahlungen[j] + massnahmenergebvector[j][index].kosten - tzahlung;//Kosten negativ
						if( gewAkt > gewMax )
						{
							gewMax = gewAkt;
							mMax = j;
						}
					}
				}//Ende:Bestimmen der Massnahme mit maximalem Gewinn auf Wunschpixel
										
				//Die Massnahme, die sich auf dem Wunschpixel durchsetzt wurde bestimmt.

				bool passtAkt = mMax == i;
				passt = passt && passtAkt;

				if(!passtAkt)//Ist es nicht die gewuenschte Massnahme i
				{
					zahlungen[i] = static_cast< int> ( gewMax + massnahmenergebvector[i][flaechen[i]].kosten * (-1) ) + 1 + tzahlung;
				}
				//Ansonsten alles so lassen.

				/*
				CString str;
				str.Format( "i=%d, mMax=%d, zahlungen[i]=%f, kosten=%f, eff = %f",
							i, 
							mMax,
							zahlungen[i], 
							massnahmenergebvector[i][flaechen[i]].kosten,
							massnahmenergebvector[i][flaechen[i]].eff);
				AfxMessageBox( str, MB_YESNO, 0);
				*/
				
			}//Ende: massnahmenergebvector[i].size()>0

		}//Ende: Schleife ueber alle Wunschpixel


		CString str;
		if(passt)
		{
			str.Format("passt");
		}
		else
		{
			str.Format("passt nicht");
		}
		AfxMessageBox( str, MB_YESNO, 0);

		versuche++;
	}//Ende: Veraendern der Zahlungen




	//"Formales":
	vector< modell::masspixelergeb>::iterator mp; //Iterator für die Kostenliste einer Massnahme
  
    for( int i = 0; i < M; i++)//Durchlaufen aller Massnahmen
    {
        if( !massnahmenergebvector[ i].empty())
        {
            for( mp = massnahmenergebvector[ i].begin();
                    mp < massnahmenergebvector[ i].end(); mp++)
            {
                (*mp).gewinn = (*mp).kosten + zahlungen[ i] - tzahlung; // die neue Zahlung muss dazu addiert werden
                (*mp).m.zahlung = zahlungen[ i];
            }
        }
        mapixelliste_mit_pos mmp;
        mmp.massnahmenergebnis = massnahmenergebvector[ i];
        mmp.position = 0;
        pixellisten_mit_position.push_back( mmp);
        pixelpromassnahme.push_back( 0);

    }

	return zahlungen;

}

vector<double> simulation::setzeWunschpixelDurchLOA(vector<int> flaechen,
													int tzahlung,
													int M_greifend,
													vector < vector < modell::masspixelergeb >> &massnahmenergebvector,
													vector< simulation::mapixelliste_mit_pos> &pixellisten_mit_position,
													vector< modell::masspixelergeb> &ergebnisliste,
													vector< int> &pixelpromassnahme)
{
	int M = massnahmenergebvector.size();
	vector<double> zahlungen(M);

	//Aufbauen des dualen Simplex-Tableaus
	vector<vector<double>> simp_tab;

	int AnzWP = 0;
	for(int i=0; i<M; i++)
	{
		if(flaechen[i] >= 0)
		{
			AnzWP++;
		}
	}

	vector<double> zielfunktion(AnzWP+1);//Zielfunktion

	zeigeVektor(flaechen);
		
	int i = 0;
	for(int k=0; k<M; k++)
	{
		if(flaechen[k] >= 0)
		{
			int WunschpixelID = massnahmenergebvector[k][flaechen[k]].pixelID;//Restriktionen zu diesem Pixel werden berechnet

			zielfunktion[i] = flaechen[k];

			vector<double> zeile(AnzWP+1);
			zeile[i] = -1;
			zeile[AnzWP] = ((-1)*massnahmenergebvector[k][flaechen[k]].kosten + tzahlung + 1)*(-1);
			simp_tab.push_back(zeile);	//Kostenrestriktion
				
			int p = 0;
			for(int j=0; j<M; j++)//Konkurrenzrestriktionen
			{
				if(flaechen[j] >= 0)
				{
					int WPindex_j = suchePixelID(WunschpixelID, flaechen[j], massnahmenergebvector[j]);
					
					if(k != j && WPindex_j != -1)
					{
						
						vector<double> zeile2(AnzWP+1);
						zeile2[i] = -1;
						zeile2[p] = 1;
						zeile2[AnzWP] = (-1)* ( (-1)*massnahmenergebvector[k][flaechen[k]].kosten 
											- ( (-1)* massnahmenergebvector[j][WPindex_j].kosten) 
											+ 1);
						simp_tab.push_back(zeile2);	//Konkurrenzrestriktion
					}
					p++;
				}			
			}	
			i++;
		}
	}
	simp_tab.push_back(zielfunktion);

	zeigeMatrix(simp_tab);

	loa *LOA = new loa(simp_tab);
	LOA->solveDual();

	zahlungen = LOA->loesung;
	zeigeVektor(zahlungen);
	

	//"Formales":
	vector< modell::masspixelergeb>::iterator mp; //Iterator für die Kostenliste einer Massnahme
  
    for( int i = 0; i < M; i++)//Durchlaufen aller Massnahmen
    {
        if( !massnahmenergebvector[ i].empty())
        {
            for( mp = massnahmenergebvector[ i].begin();
                    mp < massnahmenergebvector[ i].end(); mp++)
            {
                (*mp).gewinn = (*mp).kosten + zahlungen[ i] - tzahlung; // die neue Zahlung muss dazu addiert werden
                (*mp).m.zahlung = zahlungen[ i];
            }
        }
        mapixelliste_mit_pos mmp;
        mmp.massnahmenergebnis = massnahmenergebvector[ i];
        mmp.position = 0;
        pixellisten_mit_position.push_back( mmp);
        pixelpromassnahme.push_back( 0);

    }

	return zahlungen;

}


//Versuch, Wunschpixel sukzessive durchzusetzen
void simulation::HeurSukWP(	vector<double> &zahlungen, 
									vector<int> &flaechen, 
									int budget,
									int tzahlung,
									int maxIt,
									CString varianteEff,
									vector<double> &gewichte,
									vector < vector < modell::masspixelergeb >> &massnahmenergebvector,
									vector< simulation::mapixelliste_mit_pos> &pixellisten_mit_position,
									vector< modell::masspixelergeb> &ergebnisliste,
									vector< int> &pixelpromassnahme)
{
	CString str;
	str.Format("Algorithmus zur sukzessiven Bestimmung der WP gestartet.");
	schreibeInDatei(_T("WPsukProt.txt"), str);	

	int AnzMass = massnahmenergebvector.size();
	vector<int> MassGreif;//Speichern der Indizes der greifenden Massnahmen. Vektor der Indizes der greifenden Maßnahmen
	vector<int> MassnahmenToGreif;//Speichert zu jeder Massnahme ihren Index im MassGreif-Vektor
	vector<int> AnzPixel(AnzMass);
	int p = 0;
	for(int i=0; i<AnzMass; i++)
	{
		AnzPixel[i] = massnahmenergebvector[i].size();
		if(AnzPixel[i]>0)
		{
			MassGreif.push_back(i);
			MassnahmenToGreif.push_back(p);
			p++;
		}
		else
		{
			MassnahmenToGreif.push_back(-1);//Massnahme greift nicht
		}
	}
	int AnzMassGreif = MassGreif.size();

	str.Format("Greifende Massnahmen berechnet.");
	schreibeInDatei(_T("WPsukProt.txt"), str);	

	
	double aktEffFlaeche;
	double sumEffFlaeche;
	double zahlung;
	bool isVarPixel = varianteEff.Compare( _T("Pixel") ) == 0;
	bool isVarGlobal = varianteEff.Compare( _T("Global") ) == 0;
	//Berechnen der Effizienz
	for(int i=0; i<AnzMassGreif; i++)
	{
		int index = MassGreif[i];	
		sumEffFlaeche = 0;
		for(int j=0; j<AnzPixel[index]; j++)
		{
			aktEffFlaeche = modell::berechneFlaeche(massnahmenergebvector[index][j].artenq, gewichte);
			if( isVarGlobal)
				sumEffFlaeche += aktEffFlaeche;
			zahlung = berZahlung(massnahmenergebvector[index][j], tzahlung, 0);
		
			if(zahlung>0)
				if( isVarPixel )
					massnahmenergebvector[index][j].eff = aktEffFlaeche / (6.25 * zahlung);
				else if( isVarGlobal )
					massnahmenergebvector[index][j].eff =  sumEffFlaeche / ( 6.25 * (j+1) * zahlung);
			else
				massnahmenergebvector[index][j].eff = 0;
					
			/*
			str.Format( "MaßnahmeNummer = %d, index = %d, aktEffFlaeche = %.4f, Kosten = %.4f, eff = %.4f", 
				i, j, aktEffFlaeche, massnahmenergebvector[i][j].kosten,  
								massnahmenergebvector[i][j].eff);
			AfxMessageBox( str, MB_YESNO, 0);
			*/
		}
		
	}//Berechnen der Effizienzen fertig

	str.Format("Effizienzen berechnet.");
	schreibeInDatei(_T("WPsukProt.txt"), str);	

	vector<int> vergebeneMass;//Speichern der WP
	vector<int> vergebenePixelIDs;//Speichern der WP
	vector<int> vergebeneIndizes;//Speichern der WP (Achtung: Index bezieht sich auf zugehoerige Liste)

	vector<int> untereSG(AnzMass);
	vector<int> obereSG(AnzMass);

	vector<double> loesung_z;
	vector<int> loesung_f;
	
	bool fertig = false;
	bool durchsetzenGelungen = true;
	int it = 0;
	int anzDurchgesetzterWP = 0;
	double laufBudget = budget;
	while(!fertig && it<maxIt && anzDurchgesetzterWP < AnzMassGreif)
	{

		str.Format("Anfang der %d. Schleife.", it);
		schreibeInDatei(_T("WPsukProt.txt"), str);	

		if(durchsetzenGelungen)//Nur dann muessen die Grenzen neu bestimmt werden
		{
			//Bestimmen der Suchgrenzen fuer Wunschpixel
			bestimmeSuchgrenzen(untereSG,
								obereSG,
								AnzMass, 
								AnzMassGreif-anzDurchgesetzterWP,
								laufBudget,
								tzahlung,
								vergebeneMass,
								gewichte,
								massnahmenergebvector);
			str.Format("Suchgrenzen neu bestimmt.");
			schreibeInDatei(_T("WPsukProt.txt"), str);	
		}

		//zeigeVektor(untereSG);
		//zeigeVektor(obereSG);

		//Bestimme naechstes WP
		double maxEff = -1;
		int maxMass = -1;
		int maxMassIndex = -1;
		int maxPixelID = -1;
		for(int i=0; i<AnzMass; i++)
		{
			if(AnzPixel[i]>0 && !isIn(i, vergebeneMass))
			{
				for(int j=untereSG[i]; j<=obereSG[i]; j++)
				{
					if(massnahmenergebvector[i][j].eff > maxEff && !isIn(massnahmenergebvector[i][j].pixelID, vergebenePixelIDs) )
					{
						maxEff = massnahmenergebvector[i][j].eff;
						maxMass = i;
						maxMassIndex = j;
						maxPixelID = massnahmenergebvector[i][j].pixelID;
					}
				}
			}
		}//Pixel mit maximaler Effizienz unter denjenigen bestimmt, die noch in Frage kommen

		str.Format("Suche nach naechstem WP beendet.");
		schreibeInDatei(_T("WPsukProt.txt"), str);	

		fertig = maxEff == -1;//Kein effizientestes Pixel gefunden
		
		if(!fertig)
		{
			str.Format("mass=%d, index auf Liste=%d , eff=%f , pixelID=%d", maxMass, maxMassIndex, maxEff, maxPixelID );
			schreibeInDatei(_T("WPsukProt.txt"), str);	

			//Versuche es durchzusetzen mit Aufbauen der linearen Optimierungsaufgabe
			int AnzBishWP = vergebeneMass.size();
			vector<vector<double>> simp_tab;
			vector<double> zielfunktion(AnzMassGreif+1);//Zielfunktion und der Zielfunktionswert
			for(int k=0; k<AnzBishWP; k++)//Durchlaufen aller bisher durchgesetzten WP
			{
				int mass = vergebeneMass[k];
				int SpalteImSimpTab = MassnahmenToGreif[mass];
				int WunschpixelID = vergebenePixelIDs[k];//Restriktionen zu diesem Pixel werden berechnet
				double kostenWP = (-1)*massnahmenergebvector[mass][vergebeneIndizes[k]].kosten + tzahlung;
				zielfunktion[SpalteImSimpTab] = vergebeneIndizes[k];

				vector<double> zeile(AnzMassGreif+1);
				zeile[SpalteImSimpTab] = -1;
				zeile[AnzMassGreif] = (kostenWP + 0.1)*(-1);
				simp_tab.push_back(zeile);	//Kostenrestriktion
					
				for(int j=0; j<AnzMassGreif; j++)//Konkurenzrestriktionen
				{
					int index = MassGreif[j];
					int WPindex_j = suchePixelID(WunschpixelID, AnzPixel[index]-1, massnahmenergebvector[index]);
					
					if(mass != index && WPindex_j != -1)
					{
						vector<double> zeile2(AnzMassGreif+1);
						zeile2[SpalteImSimpTab] = -1;
						zeile2[j] = 1;
						zeile2[AnzMassGreif] = (-1)* ( kostenWP - tzahlung ) 
											- ( (-1)* massnahmenergebvector[index][WPindex_j].kosten
											+ 0.1);
						simp_tab.push_back(zeile2);	//Konkurrenzrestriktion
					}
				}			
			}//Simplex-Tableau fuer bisherige Wunschpixel erstellt
			str.Format("Simplex-Tableau fuer bisherige WP erstellt.");
			schreibeInDatei(_T("WPsukProt.txt"), str);

			//Simplex-Tableau mit aktuellem WP erweitern
			vector<double> zeile(AnzMassGreif+1);
			int SpalteImSimpTab = MassnahmenToGreif[maxMass];
			zeile[SpalteImSimpTab] = -1;
			double kostenWP = (-1) * massnahmenergebvector[maxMass][maxMassIndex].kosten + tzahlung;
			zeile[AnzMassGreif] = (kostenWP + 0.1)*(-1);//Kostenrestriktion
			simp_tab.push_back(zeile);
			for(int j=0; j<AnzMassGreif; j++)//Konkurenzrestriktionen
			{
				int index = MassGreif[j];
				int WPindex_j = suchePixelID(maxPixelID, AnzPixel[index]-1, massnahmenergebvector[index]);

				str.Format("\tindex=%d , WPindex_j=%d", index, WPindex_j);
				schreibeInDatei(_T("WPsukProt.txt"), str);
				
				if(maxMass != index && WPindex_j != -1)
				{
					vector<double> zeile2(AnzMassGreif+1);
					zeile2[SpalteImSimpTab] = -1;
					zeile2[j] = 1;
					zeile2[AnzMassGreif] = (-1)* ( kostenWP - tzahlung ) 
										- ( (-1)* massnahmenergebvector[index][WPindex_j].kosten)
										+ 0.1;
					simp_tab.push_back(zeile2);	//Konkurrenzrestriktion
				}
			}			
			zielfunktion[SpalteImSimpTab] = maxMassIndex;
			simp_tab.push_back(zielfunktion);

			str.Format("Simplex-Tableau komplett erstellt.");
			schreibeInDatei(_T("WPsukProt.txt"), str);

			//zeigeMatrix(simp_tab);

			loa *LOA = new loa(simp_tab);
			LOA->solveDual();

			//zeigeMatrix(simp_tab);
			//zeigeVektor(zielfunktion);
			
			//Analyse der Situation
			if(LOA->optimal)//weiteres durchsetzbares WP gefunden
			{
				str.Format("Loesung fuer LOA gefunden.");
				schreibeInDatei(_T("WPsukProt.txt"), str);

				double zahlungNeuesWP = LOA->loesung[MassnahmenToGreif[maxMass]];

				str.Format("zahlungNeuesWP=%f", zahlungNeuesWP);
				//AfxMessageBox(str ,MB_OK , 0);

				anzDurchgesetzterWP++;
				vergebeneMass.push_back(maxMass);
				vergebenePixelIDs.push_back(maxPixelID);
				vergebeneIndizes.push_back(maxMassIndex);
				loesung_z = LOA->loesung;
				loesung_f.clear();
				zielfunktion.pop_back();
				for(int i=0; i<AnzMassGreif; i++)
				{
					loesung_f.push_back(zielfunktion[i]);
				}

				//Zahlungen und Flaechen erstellen
				zahlungen = NullvektorDouble(AnzMass);
				flaechen = NullvektorInt(AnzMass);
				//zeigeVektor(MassGreif);
				for(int i=0; i<AnzMassGreif; i++)
				{
					int schreibIndex = MassGreif[i];
					zahlungen[schreibIndex] = loesung_z[i];
					flaechen[schreibIndex] = loesung_f[i];
				}
				laufBudget = budget - berechneObereKostenschranke(zahlungen, flaechen);
				fertig = laufBudget<=0;
				durchsetzenGelungen = true;
			}
			else//Wunschpixel mit dieser Maßnahme nicht durchsetzbar --> Effizienz wird auf Null gesetzt
			{
				durchsetzenGelungen = false;
				massnahmenergebvector[maxMass][maxMassIndex].eff = -10;
				//Eventuell weitere Pixel auf eff=-10 setzen
				bool gef = false;
				int uI , oI;
				for(int j=0; j<AnzPixel[maxMass] && !gef; j++)//unteren (ersten) Index suchen
				{
					gef = massnahmenergebvector[maxMass][j].eff < -9.999;
					if(gef)
						uI = j;
				}
				gef = false;
				for(int j=AnzPixel[maxMass]-1; j>=0 && !gef; j--)//oberen (ersten) Index suchen
				{
					gef = massnahmenergebvector[maxMass][j].eff < -9.999;
					if(gef)
						oI = j;
				}
				if(oI != uI)//Alle dazwischen liegenden Pixel werden unbrauchbar gemacht
				{
					for(int j=uI; j<=oI; j++)
					{
						massnahmenergebvector[maxMass][j].eff = -10;
					}
				}
			}
			delete LOA;
			it++;
		}
	}

	//zeigeVektor(loesung_z);
	//zeigeVektor(loesung_f);
	str.Format("Hinter der Schleife.");
	schreibeInDatei(_T("WPsukProt.txt"), str);
	

	//"Formales":
	klaereFormalitaeten(zahlungen,
						tzahlung,
						massnahmenergebvector,
						pixellisten_mit_position,
						pixelpromassnahme);


	str.Format("Algorithmus zur sukzessiven Bestimmung der WP beendet.");
	schreibeInDatei(_T("WPsukProt.txt"), str);	
	return;
}

//Bestimmt die Suchgrenzen in Abhaengigkeit der Anzahl der Maßnahmen, eines Budgets
void simulation::bestimmeSuchgrenzen(vector<int> &untereSG,
									 vector<int> &obereSG,
									 int AnzMass, 
									 int AnzMassGreifAkt,
									 double budget,
									 int tzahlung,
									 vector<int> vergebeneMass,
									 vector<double> &gewichte,
									 vector<vector<modell::masspixelergeb>> &massnahmenergebvector)
{
	CString str;
	CString filename = _T("WPsukProt.txt");
	str.Format("Im Algo zur Bestimmung der Suchgrenzen.");
	schreibeInDatei(filename, str);	


	//Kuerzen des massnahmenergebvectors
	vector<vector<modell::masspixelergeb>> mev_gekuerzt;
	vector<int> verbliebeneMass; 

	for(int i=0; i<AnzMass; i++)
	{
		if(!isIn(i, vergebeneMass))//Massnahme kann noch verwendet werden
		{
			mev_gekuerzt.push_back( massnahmenergebvector[i] );			
			verbliebeneMass.push_back(i);
		}
	}

	vector<double> Teilbudgets0 = berechneTeilbudgets(budget, tzahlung, _T("MaxErrEff"), 
									_T("MitKonku"), gewichte, mev_gekuerzt);
	vector<double> Teilbudgets = NullvektorDouble(AnzMass);
	for(int i=0; i<verbliebeneMass.size(); i++)
	{
		Teilbudgets[ verbliebeneMass[i] ] = Teilbudgets0[i];
	}

	str.Format("Teilbudgets fuer verbliebene Mass bestimmt.");
	schreibeInDatei(filename, str);	
		
	for(int i=0; i<AnzMass; i++)
	{
		if(massnahmenergebvector[i].size()>0 && !isIn(i,vergebeneMass))
		{
			bool ogGefunden = false;
			bool ugGefunden = false;
						
			for(int j=0; j<massnahmenergebvector[i].size(); j++)
			{
				//Hier kann auch -1 rauskommen, wenn Budget schon vom ersten Pixel uberausgeschoepft wird
				untereSG[i] = bestimmeIndexAusschoepfendesPixel(Teilbudgets[i], tzahlung, 0, massnahmenergebvector[i]);
				obereSG[i] = bestimmeIndexAusschoepfendesPixel(budget, tzahlung, 0, massnahmenergebvector[i]);	
				if(untereSG[i] < 0 && obereSG[i] < 0)
				{
					untereSG[i] = -1;
					obereSG[i] = -2;
				}
				else if(untereSG[i] < 0)
					untereSG[i] = 0;
				else if(obereSG[i] < 0)
					obereSG[i] = 0;
			}
		}
		else
		{
			untereSG[i] = -1;
			obereSG[i] = -2;
		}
	}
	return;
}



/*
//Liefert den Index des groessten Elements des Vektor bis zum maximalen Index
int simulation::findArgMax(vector<double> vec, int maxIndex)
{
	int champIndex = 0;
	double champ = vec[0];
	for(int i=1; i<=maxIndex; i++)
	{
		if(vec[i] > champ)
		{
			champIndex = i;
			champ = vec[i]; 
		}
	}
	return champIndex;
}


*/

//Sucht in vec den Wert val, aber nur bis zum Index maxIndex
//Liefert den Index des gefundenen Wertes oder -1
int simulation::suchePixelID(int pID, int maxIndex, vector < modell::masspixelergeb > vec)
{
	if( vec.size() == 0 || maxIndex < 0)
	{
		return -1;
	}

	int index;
	bool gefunden = false;
	int i=0;
	while(!gefunden && i<=maxIndex)
	{
		gefunden = vec[i].pixelID == pID;
		i++;
	}

	if( gefunden )
	{
		index = i-1;//i wieder Eins zurueckzaehlen
	}
	else
	{
		index = -1;
	}
	return index;
}


//Liefert Wahrheitswert, ob val in dem vec vorkommt
bool simulation::isIn(int val, vector<int> vec)
{
	bool gefunden = false;
	int i=0;
	while(i < vec.size() && !gefunden)
	{
		gefunden = gefunden || val == vec[i];
		i++;
	}
	return gefunden;
}


//Erzeugen einer zufaelligen Konfiguration zur Maximierung der effektiven Flaeche
//d.h.: zufaellige Auswahl der Massnahmen, des Budgets, Transaktionskosten und Minqualitaeten
//Ansonsten: alle Arten, Gewichte alle Eins, Sachsen
void simulation::calcRandomKonfiMaxFlaeche(
				int &tzahlung,
				vector< art*> &artlist,
				vector< massnahme> &mliste,
				vector< double> &gewichte,
				vector< double> &minqual,
				int &budget,
				bool &zahlung,
				int &zeilen,
				int &spalten,
				int &bundeslandID,
				bool &hoch,
				bool &egal)
{

	CString str;
	//AfxMessageBox( "Anf: Erzeuge zufaelliges Optimierungsszenario zur Maximierung der Fläche.", MB_YESNO, 0);

	datenbank *daten;
	daten = new datenbank();

	hoch = false;
	egal = true;
	bundeslandID = 1;//Sachsen

	//AfxMessageBox( "Vor daten->get_matrix_referenz", MB_YESNO, 0);
	daten->get_matrix_referenz( zeilen, spalten,
                                bundeslandID);
	//AfxMessageBox( "Nach daten->get_matrix_referenz", MB_YESNO, 0);


	if(artlist.size() == 0)
	{
		artlist = daten->returnartliste("art", "name_benutzer", "Astrid");//Alle Arten holen
	}
		
	vector<double> vec1, vec2;
	gewichte.swap(vec1);
	minqual.swap(vec2);

	int N = artlist.size();
	for(int i=0; i<N; i++)
	{
		gewichte.push_back( RandomInt(1,10) );//Alle Arten werden gleich gewichtet.
		minqual.push_back( RandomDouble(0.01, 0.5) );
	}

	
	budget = RandomInt(10000, 20000000);
	
	//str.Format("gesamtbudget=%d", budget);
	//AfxMessageBox( str, MB_YESNO, 0);

	//Liste der Maßnahmen
	
	int AnzMass = RandomInt(2,20);
	tzahlung = RandomInt(0, 40);
	
	vector<massnahme> vec3;
	mliste.swap(vec3);
	vector<massnahme> alleMassListe;
	daten->returnmassnahmen_gruppe(alleMassListe);
	int AnzMassGes = alleMassListe.size();

	//str.Format("AnzMassWunsch=%d, AnzahlAllerMass=%d", AnzMass, AnzMassGes );
	//AfxMessageBox( str, MB_YESNO, 0);


	for(int i=0; i<AnzMass; i++)
	{
		int index = RandomInt(0, AnzMassGes-1);
		mliste.push_back(alleMassListe[index]);

		//str.Format(alleMassListe[index].toString(), AnzMassGes, alleMassListe.size() );
		//AfxMessageBox( str, MB_YESNO, 0);

		//str.Format(alleMassListe[index].toString());

		alleMassListe.erase( alleMassListe.begin() + index);
		AnzMassGes--;

		//str.Format("AnzahlAllerMAss=%d, AnzahlAllerMass=%d", AnzMassGes, alleMassListe.size() );
		//AfxMessageBox( str, MB_YESNO, 0);

	}

	vector<massnahme> vec4;
	alleMassListe.swap(vec4);
	delete daten;

	//AfxMessageBox( "Ende: Erzeuge zufaelliges Optimierungsszenario zu Maximierung der Fläche.", MB_YESNO, 0);
}



void simulation::schreibeInDatei(CString filename, CString text)
{
	fstream datei;
    datei.open(filename, std::ios::app);
    datei << text << endl;
	datei.close();    
}


void simulation::sortiereMassnahmenlisten(vector < vector < modell::masspixelergeb >> &massnahmenergebvector)
{
	vector< vector< modell::masspixelergeb>>::iterator me;
	//Sortieren des massnahmenergebvectors 
	for( me = massnahmenergebvector.begin();//Sortieren der Vektoren
            me != massnahmenergebvector.end(); me++)
	{
       if( (*me).size() > 0)
	   {
		   sort( (*me).begin(), (*me).end(), myfunction);
	   }
    }
}


void simulation::klaereFormalitaeten(vector<double> zahlungen,
									 int tzahlung,
									 vector < vector < modell::masspixelergeb >> &massnahmenergebvector,
									 vector< simulation::mapixelliste_mit_pos> &pixellisten_mit_position,
								     vector< int> &pixelpromassnahme)
{
	vector< modell::masspixelergeb>::iterator mp; //Iterator für die Kostenliste einer Massnahme
    for(int i=0 ; i<massnahmenergebvector.size(); i++)//Durchlaufen aller Massnahmen
    {
        if( !massnahmenergebvector[ i].empty())
        {
            for( mp = massnahmenergebvector[ i].begin();
                    mp != massnahmenergebvector[ i].end(); mp++)
            {
                (*mp).gewinn = (*mp).kosten + zahlungen[ i] - tzahlung; // die neue Zahlung muss dazu addiert werden
                (*mp).m.zahlung = zahlungen[ i];
            }
        }
        mapixelliste_mit_pos mmp;
        mmp.massnahmenergebnis = massnahmenergebvector[ i];
        mmp.position = 0;
        pixellisten_mit_position.push_back( mmp);
        pixelpromassnahme.push_back( 0);
    }
}


//Mal schauen, ob's geht
void simulation::loescheMassnahmenlisten(vector<vector<modell::masspixelergeb>> &massnahmenergebvector)
{
	vector<vector<modell::masspixelergeb>>::iterator me;
	vector<modell::masspixelergeb>::iterator mp;
	for(me=massnahmenergebvector.begin();
            me!=massnahmenergebvector.end(); ++me)
	{
		/*
       if( (*me).size() > 0)
	   {
		  for(mp = (*me).begin(); mp!=(*me).end(); ++mp)
		  {
			  delete *mp;
		  }
		  (*me).clear();
	   }
	   */
		vector<modell::masspixelergeb> vec;
		vec.swap(*me);
    }
	vector<vector<modell::masspixelergeb>> vec;
	vec.swap(massnahmenergebvector);
}


vector<double> simulation::NullvektorDouble(int length)
{
	vector<double> vec(length);
	for(int i=0; i<length; i++)
		vec[i] = 0.0;
	return vec;
}

vector<int> simulation::NullvektorInt(int length)
{
	vector<int> vec(length);
	for(int i=0; i<length; i++)
		vec[i] = 0;
	return vec;
}
//Vor.: a<b
int simulation::RandomInt(int a, int b)
{
	//srand( (unsigned) time(NULL) ) ; 
	return (int)( rand() / (((double)RAND_MAX + 1)/ (double)(b-a+1)))+a;
	//return ( rand() % (b-a+1) ) + a;
}
double simulation::RandomDouble(double a, double b)
{
	//srand( (unsigned) time(NULL) ) ; 
	double zz = double(rand())/(double(RAND_MAX));//Zahl zwischen Null und Eins
	return a + zz * (b - a);//Transformation
}

void simulation::speichereErgebnisvektoren(vector<vector<modell::masspixelergeb>> mev, CString filename, vector<double> &gewichte)
{
	CString str = _T("");
	for(int i=0; i<mev.size(); i++)
	{
		for(int j=0; j<mev[i].size(); j++)
		{
			CString str1;
			str1.Format("mass=%d, index=%d, kosten=%f, flaeche=%f \n", i, j, 
				mev[i][j].kosten, modell::berechneFlaeche(mev[i][j].artenq, gewichte));
			str.Append(str1);
		}
	}
	
	fstream datei;
    datei.open(filename, std::ios::app);
    datei << str << endl;
	datei.close();    
}

double simulation::logZwischenNullUndXMax(double x, double xMax, double A)
{
	if( fabs(x) < 0.00000001)
		return 0;
	//return ((B-A) / xMax) * x + A;
	return A/log(xMax) * log(x);
}

vector<int> simulation::bestimmeRankingBesteAUP(vector<double> gesamtflaeche,
												vector<bool> bOk,
												vector<double> ausgabe)
{
	double eps = 0.00000001;
	int anzHeur = gesamtflaeche.size();
	vector<int> aktRang = NullvektorInt(anzHeur);
	bool istBesser;
	for(int k=0; k<anzHeur; k++)
	{
		int AnzBessererHeurMitBudOk = 0;
		for(int h=0; h<anzHeur; h++)
		{
			istBesser = h != k 
						&& (   (gesamtflaeche[h] > gesamtflaeche[k] && bOk[h] )
							|| (bOk[h] && !bOk[k])
							|| (bOk[h] && bOk[k] && fabs(gesamtflaeche[k]-gesamtflaeche[h]) < eps
								 && ausgabe[h] < ausgabe[k]));
			if(istBesser)
				AnzBessererHeurMitBudOk++;
		}
		aktRang[k] = AnzBessererHeurMitBudOk+1;
	}
	return aktRang;
}

vector<int> simulation::bestimmeRanking(vector<double> vals)
{
	int anz = vals.size();
	double eps = 0.00000001;
	vector<int> aktRang = NullvektorInt(anz);
	bool istBesser;
	for(int k=0; k<anz; k++)
	{
		int AnzBessererHeurMitBudOk = 0;
		for(int h=0; h<anz; h++)
		{
			istBesser = h != k && vals[h] - vals[k] > eps;
			if(istBesser)
				AnzBessererHeurMitBudOk++;
		}
		aktRang[k] = AnzBessererHeurMitBudOk+1;
	}
	return aktRang;
}

double simulation::berechneObereKostenschranke(vector<double> zahlungen, vector<int> flaechen)
{
	double sum = 0;
	for(int i=0; i<zahlungen.size(); i++)
	{
		sum += zahlungen[i]*flaechen[i];
	}
	return 6.25*sum;
}
double simulation::lineareFkt(double x, double x0, double x1, double y0, double y1)
{
	return ( (y1-y0) / (x1-x0) ) * x + ( y0 - (y1-y0) / (x1-x0) * x0);
}
vector<double> simulation::berechneDurchschnitte(vector<vector<double>> Stichproben)
{
	int anzSP = Stichproben[0].size();
	int UmfangSP = Stichproben.size();
	vector<double> Durchschnitte = NullvektorDouble(anzSP);
	for(int j=0; j<anzSP; j++)
	{
		double sum = 0;
		for(int i=0; i<UmfangSP; i++)
		{
			sum += Stichproben[i][j];
		}
		Durchschnitte[j] = sum/double(UmfangSP);
	}
	return Durchschnitte;
}
vector<double> simulation::berechneVarianzen(vector<double> Durchschnitte, vector<vector<double>> Stichproben)
{
	int anzSP = Stichproben[0].size();
	int UmfangSP = Stichproben.size();
	vector<double> Varianzen = NullvektorDouble(anzSP);
	for(int j=0; j<anzSP; j++)
	{
		double sum=0;
		for(int i=0; i<UmfangSP; i++)
		{
			sum += (Stichproben[i][j]-Durchschnitte[j])*(Stichproben[i][j]-Durchschnitte[j]);
		}
		if(UmfangSP>1)
			Varianzen[j] = sum/double(UmfangSP-1);
	}
	return Varianzen;
}
CString simulation::toString(vector<massnahme> mliste)
{
	int anzMass = mliste.size();
	CString erg = "";
	for(int i=0; i<anzMass; i++)
	{
		erg += mliste[i].toString() + " | ";
	}
	return erg;
}


