Real sensingRange=0.3
Real samplingsPerMeter2=100000;
Real  arena_radius=1.26;

Real CalculateObjectiveFunction() {
    std::list<CNetAgent> agents;
    /* create a list with the agents positions (using the objects CNetAgents) */
    for (CSpace::TAnyEntityMap::iterator itEPuckEntity =
            m_tEPuckEntityMap.begin(); itEPuckEntity != m_tEPuckEntityMap.end(); itEPuckEntity++) {
        CEPuckEntity* cEPuckEntity = any_cast<CEPuckEntity*> (
                (*itEPuckEntity).second);
        CVector2 pos = cEPuckEntity->GetEmbodiedEntity().GetPosition().ProjectOntoXY();
        agents.push_back(CNetAgent(pos));
    }

    /* Cluster the agents in groups with maximum distance MAX_COMM_DIST */
    UInt32 maxUsedID = 0;
    for (std::list<CNetAgent>::iterator ag=agents.begin(); ag!=agents.end(); ++ag){
        if (ag->clusterID != 0) continue;
        ag->clusterID = ++maxUsedID;
        AddNeighs(agents, ag);
    }

    /* Determine the biggest group */
    size_t maxGroupSize = 0;
    UInt32 biggestGroupID = 0;
    for (UInt32 i = 1; i <= maxUsedID; i++){
        size_t size = 0;
        for (std::list<CNetAgent>::iterator ag=agents.begin(); ag!=agents.end(); ++ag){
            if (ag->clusterID == i){
                size++;
            }
        }
        if (maxGroupSize < size){
            maxGroupSize = size;
            biggestGroupID = i;
        }
    }

    /* create a list of positions of only the elements in the biggest group */
    /* and at the same time, calculate the extreme coordinates of the group */
    std::list<CVector2> biggestGroup;
    Real min_x = std::numeric_limits<double>::max();
    Real min_y = std::numeric_limits<double>::max();
    Real max_x = 0;
    Real max_y = 0;
    for (std::list<CNetAgent>::iterator ag=agents.begin(); ag!=agents.end(); ++ag){
        if (ag->clusterID == biggestGroupID){
            min_x = (ag->pos.GetX() < min_x)? ag->pos.GetX() : min_x;
            min_y = (ag->pos.GetY() < min_y)? ag->pos.GetY() : min_y;
            max_x = (ag->pos.GetX() > max_x)? ag->pos.GetX() : max_x;
            max_y = (ag->pos.GetY() > max_y)? ag->pos.GetY() : max_y;
            biggestGroup.push_back(ag->pos);
        }
    }

    /* calculate the bounding box sizes (ranges) */
    CRange<Real> width( min_x - sensingRange, max_x + sensingRange);
    CRange<Real> height(min_y - sensingRange, max_y + sensingRange);

    /* Monte-Carlo sampling to estimate the ratio of the bounding box that is covered by the sensing range */
    Real avg = 0;
    for (size_t i = 0; i < (UInt32)Ceil((width.GetSpan()*height.GetSpan())*samplingsPerMeter2); i++ ){
        Real rx = m_pcRNG->Uniform(width);
        Real ry = m_pcRNG->Uniform(height);
        CVector2 rndPoint(rx, ry);

        for (std::list<CVector2>::iterator pos=biggestGroup.begin(); pos!=biggestGroup.end(); ++pos){
            if ( Distance(rndPoint, *pos) <= sensingRange && Distance(rndPoint, arenaCenter) < arenaRadius){
                avg++;
                break;
            }
        }
    }

    /* Compute the coverage-ratio */
    avg = avg / Ceil((width.GetSpan()*height.GetSpan())*samplingsPerMeter2);
    /* Multiply the area size (bounding box) by the coverage-ratio */
    Real performance = width.GetSpan() * height.GetSpan() * avg;
    return performance;
}