/*************************************************************************
* Project: Library of Evolutionary Algoriths
*************************************************************************
* Author: Changhe Li & Ming Yang
* Email: changhe.lw@google.com Or yangming0702@gmail.com
* Language: C++
*************************************************************************
*  This file is part of EAlib. This library is free software;
*  you can redistribute it and/or modify it under the terms of the
*  GNU General Public License as published by the Free Software
*  Foundation; either version 2, or (at your option) any later version.
*************************************************************************/
// Created: 21 July 2011
// Last modified:

#include"Optima.h"

Optima::Optima():mp_optima(0),m_number(0){

}
Optima::Optima(const int num):m_number(num){
    mp_optima=new Optimum[m_number];
}
Optima::Optima(const Optima & l):m_number(l.m_number){
    mp_optima=new Optimum[m_number];
}
Optima::~Optima(){
    freeMemory();
};
void Optima::alocateMemory(const int num){
    if(num<1) {
        Throw(Runtime_error("The number of local mp_optima < 1 in Alocate_Memory of Optima"));
        system(0);
    }
    m_number=num;
    mp_optima=new Optimum[m_number];
}
void Optima::freeMemory(){
    if(m_number>0) {
        delete [] mp_optima;
        mp_optima=0;
    }
    m_number=0;
}
Optima * Optima::operator+( Optimum & l){

    Optima *lo=new Optima(m_number+1);
    for(int i=0;i<m_number;i++){
        lo->mp_optima[i]=mp_optima[i];
    }
    lo->mp_optima[m_number]=l;

    return lo;
}
Optima * Optima::operator+( Optima &l){
    if(m_number+l.m_number<=0) return this;
    Optima *lo=new Optima(m_number+l.m_number);
    int i;
    for(i=0;i<m_number;i++)
        lo->mp_optima[i]=mp_optima[i];

    for(int j=0;j<l.m_number;j++,i++){
        lo->mp_optima[i]=l.mp_optima[j];
    }
    return lo;
}
Optima & Optima::operator=( Optima &l){
    if(this==&l) return *this;
    if(m_number!=l.m_number){
        freeMemory();
        alocateMemory(l.m_number);
    }
    for( int i=0;i<l.m_number;i++)	mp_optima[i]=l.mp_optima[i];

    return *this;
}
void  Optima::deleteOptimum(const int index){
    if(m_number<2){
        freeMemory();
        return;
    }
    int old_numbers=m_number;
    Optimum *lo =new Optimum[old_numbers-1];

    for(int i=0,j=0;i<old_numbers;i++,j++){
        if(i!=index)
        lo[j]=mp_optima[i];
        else
            j--;
    }
    freeMemory();
    mp_optima=lo;
    m_number=old_numbers-1;
}
void Optima::updateFitness(){
    for(int i=0;i<m_number;i++)	mp_optima[i].getLocation().evaluate();
}
const Optimum & Optima::findBest(){
    int index=0;
    for(int i=1;i<m_number;i++)
        if(mp_optima[i].getLocation()>(mp_optima[index].getLocation())){
            index=i;
        }
    return mp_optima[index];
}
