[Avida-SVN] r1123 - in branches/coopcomm: Avida.xcodeproj source/actions source/main source/tools
dknoester at myxo.css.msu.edu
dknoester at myxo.css.msu.edu
Mon Dec 11 08:18:26 PST 2006
Author: dknoester
Date: 2006-12-11 11:18:25 -0500 (Mon, 11 Dec 2006)
New Revision: 1123
Modified:
branches/coopcomm/Avida.xcodeproj/project.pbxproj
branches/coopcomm/source/actions/PopulationActions.cc
branches/coopcomm/source/actions/PrintActions.cc
branches/coopcomm/source/main/cOrgMessage.h
branches/coopcomm/source/main/cPopulation.cc
branches/coopcomm/source/main/cPopulation.h
branches/coopcomm/source/main/cStats.cc
branches/coopcomm/source/main/cStats.h
branches/coopcomm/source/tools/tArray.h
Log:
Added an adaptable compete demes action (rather like a combination of
ReplicateDemes and CompeteDemes) where:
- state information of each deme may be stored at intervals between competes.
- deme fitness may be calculated based on this state information.
- competes occur based on a predicate.
The "adaptable" part of this action is in the heavy use of templates to
determine the action's behavior.
Modified: branches/coopcomm/Avida.xcodeproj/project.pbxproj
===================================================================
--- branches/coopcomm/Avida.xcodeproj/project.pbxproj 2006-12-10 03:59:19 UTC (rev 1122)
+++ branches/coopcomm/Avida.xcodeproj/project.pbxproj 2006-12-11 16:18:25 UTC (rev 1123)
@@ -360,23 +360,6 @@
E626209E0A372C2A00C07685 /* SaveLoadActions.cc in Sources */ = {isa = PBXBuildFile; fileRef = 708051A80A1F65FE00CBB8B6 /* SaveLoadActions.cc */; };
/* End PBXBuildFile section */
-/* Begin PBXBuildStyle section */
- B532BFFC0B1B4911008BEB97 /* Development */ = {
- isa = PBXBuildStyle;
- buildSettings = {
- COPY_PHASE_STRIP = NO;
- };
- name = Development;
- };
- B532BFFD0B1B4911008BEB97 /* Deployment */ = {
- isa = PBXBuildStyle;
- buildSettings = {
- COPY_PHASE_STRIP = YES;
- };
- name = Deployment;
- };
-/* End PBXBuildStyle section */
-
/* Begin PBXCopyFilesBuildPhase section */
700E2B6D085DE50C00CF158A /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
@@ -1762,12 +1745,6 @@
DCC30C4D0762532C008F7A48 /* Project object */ = {
isa = PBXProject;
buildConfigurationList = 702442D70859E0B00059BD9B /* Build configuration list for PBXProject "Avida" */;
- buildSettings = {
- };
- buildStyles = (
- B532BFFC0B1B4911008BEB97 /* Development */,
- B532BFFD0B1B4911008BEB97 /* Deployment */,
- );
hasScannedForEncodings = 0;
mainGroup = DCC30C490762532C008F7A48;
productRefGroup = DCC3164E07626CF3008F7A48 /* Products */;
Modified: branches/coopcomm/source/actions/PopulationActions.cc
===================================================================
--- branches/coopcomm/source/actions/PopulationActions.cc 2006-12-10 03:59:19 UTC (rev 1122)
+++ branches/coopcomm/source/actions/PopulationActions.cc 2006-12-11 16:18:25 UTC (rev 1123)
@@ -7,6 +7,9 @@
*
*/
#include <set>
+#include <functional>
+#include <algorithm>
+#include <vector>
#include "PopulationActions.h"
@@ -818,6 +821,285 @@
};
+/*! \brief Determines all the different votes within a single deme.
+This is a function object that is compatible with the STL. It is designed to be
+run iteratively over all the cells within a deme:
+
+std::for_each(cell_begin, cell_end, vote_calculator());
+*/
+struct vote_calculator : public unary_function<cPopulationCell, void> {
+ typedef std::set<cOrganism*> organism_set;
+ typedef std::map<int, organism_set > forward_votes;
+ typedef std::map<cOrganism*, organism_set*> reverse_votes;
+ typedef std::vector<std::pair<int, unsigned int> > vote_tally;
+
+ forward_votes m_fvotes; //!< An ID-to-voters map.
+ reverse_votes m_rvotes; //!< A voter-to-group map.
+
+ //! Called iteratively to record votes.
+ void operator()(cPopulationCell& cell) {
+ if(!cell.IsOccupied()) return;
+ cOrganism* org = cell.GetOrganism();
+ if(org->GetLeaderID() == 0) return;
+ if(!cPopulationCell::IsRandomCellID(org->GetLeaderID())) return;
+
+ std::pair<forward_votes::iterator, bool> ins =
+ m_fvotes.insert(std::make_pair(org->GetLeaderID(), organism_set()));
+ m_fvotes[org->GetLeaderID()].insert(org);
+ m_rvotes[org] = &m_fvotes[org->GetLeaderID()];
+ }
+
+ template< typename Iterator >
+ void remove_votes(Iterator begin, Iterator end) {
+ for(; begin!=end; ++begin) {
+ m_fvotes.erase(*begin);
+ }
+ }
+
+ //! Called after all votes have been recorded to tally the results.
+ template< typename TallyRider > std::pair<vote_tally, TallyRider> tally(TallyRider tr) {
+ vote_tally t;
+ for(forward_votes::const_iterator i=m_fvotes.begin(); i!=m_fvotes.end(); ++i) {
+ t.push_back(std::make_pair(i->first, i->second.size()));
+ tr(i);
+ }
+ return std::make_pair(t, tr);
+ }
+};
+
+
+/*! \brief A predicate that always competes demes.
+This is an STL-compatible function object that may be used by
+cActionAdaptableCompeteDemes to always compete demes upon every execution of the
+event.
+*/
+template< typename FitnessFunction >
+struct always_compete : public std::unary_function<FitnessFunction, bool> {
+ static std::string GetDescription() {
+ return "Always compete";
+ }
+
+ always_compete(cWorld* world, const cString& args) { }
+ bool operator()(FitnessFunction& f) { return true; }
+};
+
+
+/*! \brief A predicate that competes demes at specified intervals.
+This is just a quick hack for every 100 updates...
+*/
+template< typename FitnessFunction >
+struct modulo_compete : public std::unary_function<FitnessFunction, bool> {
+ static std::string GetDescription() {
+ return "Modulo compete";
+ }
+
+ modulo_compete(cWorld* world, const cString& args)
+ : m_world(world) {
+ }
+
+ bool operator()(FitnessFunction& f) {
+ if(m_world->GetStats().GetUpdate() % 100 == 0) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ cWorld* m_world;
+};
+
+/*! \brief Performs the standard GA-style deme competition.
+An STL-compatible function object designed to be used with
+cActionAdaptableCompeteDemes.
+*/
+template<typename FitnessFunction>
+struct ga_competition_strategy : public std::unary_function<FitnessFunction, void> {
+ static std::string GetDescription() {
+ return "GA comp. strategy";
+ }
+
+ ga_competition_strategy(cWorld* world, const cString& args)
+ : m_world(world) { }
+
+ void operator()(FitnessFunction& f) {
+ m_world->GetPopulation().CompeteDemes(f.fitnesses());
+ f.reset();
+ }
+
+ cWorld* m_world;
+};
+
+
+struct max_vote
+: public std::unary_function<vote_calculator::forward_votes::const_iterator, void> {
+ max_vote() : m_maxID(0), m_maxVote(0) { }
+ void operator()(vote_calculator::forward_votes::const_iterator i) {
+ if(i->second.size() > m_maxVote) {
+ m_maxVote = i->second.size();
+ m_maxID = i->first;
+ }
+ }
+ int m_maxID;
+ unsigned int m_maxVote;
+};
+
+
+struct popular_vote
+: public std::binary_function<cPopulation::t_CellIterator, cPopulation::t_CellIterator, double> {
+ static std::string GetDescription() {
+ return "popular vote";
+ }
+
+ double operator()(cPopulation::t_CellIterator begin, cPopulation::t_CellIterator end) {
+ vote_calculator vc = std::for_each(begin, end, vote_calculator());
+ return vc.tally(max_vote()).second.m_maxVote;
+ }
+};
+
+
+template< typename DemeFitnessFunction >
+struct default_fitness : public std::unary_function<cPopulation::t_CellRangeList, void> {
+ static std::string GetDescription() {
+ return "Default fitness:" + DemeFitnessFunction::GetDescription();
+ }
+
+ default_fitness(cWorld* world, const cString& args) { }
+
+ void operator()(cPopulation::t_CellRangeList cell_ranges) {
+ m_fitness.clear();
+ for(cPopulation::t_CellRangeList::iterator i=cell_ranges.begin();
+ i!=cell_ranges.end();
+ ++i) {
+ DemeFitnessFunction df;
+ m_fitness.push_back(df(i->first, i->second));
+ }
+ }
+
+ void reset() {
+ }
+
+ const std::vector<double>& fitnesses() { return m_fitness; }
+
+ std::vector<double> m_fitness;
+};
+
+
+struct ratcheting_popular_vote
+: public std::binary_function<cPopulation::t_CellIterator, cPopulation::t_CellIterator, double> {
+ static std::string GetDescription() {
+ return "ratcheting popular vote";
+ }
+
+ ratcheting_popular_vote(cWorld* world, const cString& args)
+ : m_world(world) {
+ m_previousLeaders.clear();
+ }
+
+ /*! Calculate this deme's fitness.
+ We're guaranteed that the same ratcheting_popular_vote object will be used for
+ the same deme, so it's safe to hold some state here. Note that state must be
+ reset after a competition event.
+
+ In this case, we want to do the following: First, run the vote calculator. Then,
+ tally up the votes, and remove the votes for a given set of IDs.
+
+ The resulting fitness is max_vote^r_1 + max_vote^r_2..., where r is the number
+ of times that this deme has beeen ratcheted.
+ */
+ double operator()(cPopulation::t_CellIterator begin, cPopulation::t_CellIterator end) {
+ vote_calculator vc = std::for_each(begin, end, vote_calculator());
+ vc.remove_votes(m_previousLeaders.begin(), m_previousLeaders.end());
+ std::pair<vote_calculator::vote_tally, max_vote> vt = vc.tally(max_vote());
+ if(vt.second.m_maxVote == 100) {
+ m_previousLeaders.push_back(vt.second.m_maxID);
+ vt.second.m_maxVote = 0;
+ // and reset the leader ID
+ cPopulationCell::GetRandomCellIDMap()[vt.second.m_maxID]->ResetRandomCellID();
+ }
+
+ // square it so that there's always a huge benefit to getting just one more.
+ return pow(vt.second.m_maxVote + m_previousLeaders.size()*100, 2);
+ }
+
+ std::vector<int> m_previousLeaders;
+ cWorld* m_world;
+};
+
+
+template< typename DemeFitnessFunction >
+struct stateful_fitness : public std::unary_function<cPopulation::t_CellRangeList, void> {
+ static std::string GetDescription() {
+ return "Stateful fitness:" + DemeFitnessFunction::GetDescription();
+ }
+
+ stateful_fitness(cWorld* world, const cString& args)
+ : m_world(world)
+ , m_args(args) {
+ reset();
+ }
+
+ void operator()(cPopulation::t_CellRangeList cell_ranges) {
+ typedef typename std::vector<DemeFitnessFunction>::iterator dffiter;
+ cPopulation::t_CellRangeList::iterator demei = cell_ranges.begin();
+ dffiter fiti = m_demeFitness.begin();
+ m_fitness.clear();
+ for(; demei!=cell_ranges.end(); ++demei,++fiti) {
+ m_fitness.push_back((*fiti)(demei->first, demei->second));
+ }
+ }
+
+ void reset() {
+ m_demeFitness.clear();
+ for(unsigned int i=0; i<m_world->GetPopulation().GetDemes().size(); ++i) {
+ m_demeFitness.push_back(DemeFitnessFunction(m_world,m_args));
+ }
+ }
+
+ const std::vector<double>& fitnesses() { return m_fitness; }
+
+ std::vector<DemeFitnessFunction> m_demeFitness;
+ std::vector<double> m_fitness;
+ cWorld* m_world;
+ cString m_args;
+};
+
+template< typename FitnessFunction,
+ typename CompetitionStrategy=ga_competition_strategy<FitnessFunction>,
+ typename CompetePredicate=always_compete<FitnessFunction> >
+class cActionAdaptableCompeteDemes : public cAction {
+public:
+ typedef FitnessFunction fitness_function;
+ typedef CompetitionStrategy competition_strategy;
+ typedef CompetePredicate compete_predicate;
+
+ static const cString GetDescription() {
+ return std::string("Adaptable Deme Competition: " +
+ FitnessFunction::GetDescription() + " ; " +
+ CompetitionStrategy::GetDescription() + " ; " +
+ CompetePredicate::GetDescription()).c_str();
+ }
+
+ cActionAdaptableCompeteDemes(cWorld* world, const cString& args)
+ : cAction(world,args)
+ , m_fit(world,args)
+ , m_comp(world,args)
+ , m_pred(world,args) {
+ }
+
+ void Process(cAvidaContext& ctx) {
+ m_fit(m_world->GetPopulation().GetDemes());
+ if(m_pred(m_fit)) {
+ m_comp(m_fit);
+ }
+ }
+
+private:
+ FitnessFunction m_fit;
+ CompetitionStrategy m_comp;
+ CompetePredicate m_pred;
+};
+
+
/*
Designed to serve as a control for the compete_demes. Each deme is
copied into itself and the parameters reset.
@@ -1459,6 +1741,11 @@
action_lib->Register<cActionAddMessagePredicate>("AddMessagePredicate");
action_lib->Register<cActionAddBaseStationPredicate>("AddBaseStationPredicate");
action_lib->Register<cActionMessageRain>("MessageRain");
+ action_lib->Register<
+ cActionAdaptableCompeteDemes< stateful_fitness<ratcheting_popular_vote>,
+ ga_competition_strategy<stateful_fitness<ratcheting_popular_vote> >,
+ modulo_compete<stateful_fitness<ratcheting_popular_vote> >
+ > >("AdaptableCompeteDemes");
// @DMB - The following actions are DEPRECATED aliases - These will be removed in 2.7.
action_lib->Register<cActionInject>("inject");
Modified: branches/coopcomm/source/actions/PrintActions.cc
===================================================================
--- branches/coopcomm/source/actions/PrintActions.cc 2006-12-10 03:59:19 UTC (rev 1122)
+++ branches/coopcomm/source/actions/PrintActions.cc 2006-12-11 16:18:25 UTC (rev 1123)
@@ -69,6 +69,7 @@
STATS_OUT_FILE(PrintLeaderData, leader_log.dat);
STATS_OUT_FILE(PrintCellData, cell_log.dat);
STATS_OUT_FILE(PrintMessageData, message_log.dat);
+STATS_OUT_FILE(PrintDemeFitness, deme_fitness.dat);
STATS_OUT_FILE(PrintIDData, id_log.dat);
STATS_OUT_FILE(PrintMessageDataPerUpdate, message.dat);
STATS_OUT_FILE(PrintMessageSnapshot, msg_snapshot.dat);
@@ -1530,6 +1531,7 @@
action_lib->Register<cActionPrintLeaderData>("PrintLeaderData");
action_lib->Register<cActionPrintCellData>("PrintCellData");
action_lib->Register<cActionPrintMessageData>("PrintMessageData");
+ action_lib->Register<cActionPrintDemeFitness>("PrintDemeFitness");
action_lib->Register<cActionPrintIDData>("PrintIDData");
action_lib->Register<cActionPrintMessageDataPerUpdate>("PrintMessageDataPerUpdate");
action_lib->Register<cActionPrintMessageSnapshot>("PrintMessageSnapshot");
Modified: branches/coopcomm/source/main/cOrgMessage.h
===================================================================
--- branches/coopcomm/source/main/cOrgMessage.h 2006-12-10 03:59:19 UTC (rev 1122)
+++ branches/coopcomm/source/main/cOrgMessage.h 2006-12-11 16:18:25 UTC (rev 1123)
@@ -129,7 +129,7 @@
cOrgMessage_PredSinkReceiverEQU(unsigned int data) : m_data(data) { }
virtual bool operator()(cOrgMessage& msg) {
- if(m_data==msg.GetReceiver()->GetCellID()) {
+ if(m_data==(unsigned int)msg.GetReceiver()->GetCellID()) {
m_cell_ids.insert(msg.GetData());
}
}
Modified: branches/coopcomm/source/main/cPopulation.cc
===================================================================
--- branches/coopcomm/source/main/cPopulation.cc 2006-12-10 03:59:19 UTC (rev 1122)
+++ branches/coopcomm/source/main/cPopulation.cc 2006-12-11 16:18:25 UTC (rev 1123)
@@ -40,6 +40,7 @@
#include <fstream>
#include <vector>
#include <algorithm>
+#include <numeric>
#include <set>
#include <map>
@@ -261,6 +262,13 @@
}
}
+ // And just for fun, let's make it a little easier to actually GET AT the list
+ // of demes and associated cells.
+ for(int i=0; i<num_demes; ++i) {
+ m_demeCellRanges.push_back(t_CellRange(cell_array.GetPtr()+i*deme_size,
+ cell_array.GetPtr()+(i+1)*deme_size));
+ }
+
return true;
}
@@ -746,53 +754,48 @@
}
break;
- case 7:
- {
- // Competing demes based on the number of organisms that have agreed on a leader.
- //
- // For each deme, build up the number of organisms that have "elected"
- // leaders. Total fitness is the sum of the deme_fitness; deme_fitness is
- // the max number of organisms that have agreed on a single leader.
- //
- for(int cur_deme=0; cur_deme<num_demes; ++cur_deme) {
- // for each deme...
- cDoubleSum single_deme_fitness;
- std::map<int, std::set<int> > votes;
- unsigned int max=0;
- unsigned int org_count=0;
-
- for (int i=0; i<deme_size; ++i) {
- // for each cell in the deme
- int cur_cell = cur_deme * deme_size + i;
- // ... that has an organism
- if (cell_array[cur_cell].IsOccupied() == false) continue;
- // ... record the vote:
- ++org_count;
- cOrganism* org = GetCell(cur_cell).GetOrganism();
- // Skip orgs that haven't set a leader.
- if(org->GetLeaderID() == 0) continue;
- // And skip orgs that didn't set an organism ID
- if(!cPopulationCell::IsRandomCellID(org->GetLeaderID())) continue;
- if(votes.find(org->GetLeaderID()) == votes.end()) {
- votes.insert(std::make_pair(org->GetLeaderID(), std::set<int>()));
- }
- votes[org->GetLeaderID()].insert(org->GetRandomCellID());
- // ... and keep track of the winning organism.
- if(votes[org->GetLeaderID()].size() > max) {
- max = votes[org->GetLeaderID()].size();
- }
- }
-
-// if(org_count > 0) {
- m_world->GetStats().Demes_Leadership(max, org_count);//(double)max/org_count);
- deme_fitness[cur_deme] = (double)max;///org_count;
- total_fitness += deme_fitness[cur_deme];
-// } else {
-// deme_fitness[cur_deme] = 0;
+// case 7:
+// {
+// // Competing demes based on the number of organisms that have agreed on a leader.
+// //
+// // For each deme, build up the number of organisms that have "elected"
+// // leaders. Total fitness is the sum of the deme_fitness; deme_fitness is
+// // the max number of organisms that have agreed on a single leader.
+// //
+// for(int cur_deme=0; cur_deme<num_demes; ++cur_deme) {
+// // for each deme...
+// std::map<int, std::set<int> > votes;
+// unsigned int max=0;
+// unsigned int org_count=0;
+//
+// for (int i=0; i<deme_size; ++i) {
+// // for each cell in the deme
+// int cur_cell = cur_deme * deme_size + i;
+// // ... that has an organism
+// if (cell_array[cur_cell].IsOccupied() == false) continue;
+// // ... record the vote:
+// ++org_count;
+// cOrganism* org = GetCell(cur_cell).GetOrganism();
+// // Skip orgs that haven't set a leader.
+// if(org->GetLeaderID() == 0) continue;
+// // And skip orgs that didn't set an organism ID
+// if(!cPopulationCell::IsRandomCellID(org->GetLeaderID())) continue;
+// if(votes.find(org->GetLeaderID()) == votes.end()) {
+// votes.insert(std::make_pair(org->GetLeaderID(), std::set<int>()));
+// }
+// votes[org->GetLeaderID()].insert(org->GetRandomCellID());
+// // ... and keep track of the winning organism.
+// if(votes[org->GetLeaderID()].size() > max) {
+// max = votes[org->GetLeaderID()].size();
+// }
// }
- }
- break;
- }
+//
+// m_world->GetStats().Demes_Leadership(max, org_count);//(double)max/org_count);
+// deme_fitness[cur_deme] = (double)max;///org_count;
+// total_fitness += deme_fitness[cur_deme];
+// } // end deme-loop.
+// break;
+// } // end case.
}
// Pick which demes should be in the next generation.
@@ -868,6 +871,86 @@
}
+void cPopulation::CompeteDemes(const std::vector<double>& deme_fitness) {
+ double total_fitness = std::accumulate(deme_fitness.begin(),
+ deme_fitness.end(), 0.0);
+ m_world->GetStats().DemeFitness(deme_fitness);
+
+ // Pick which demes should be in the next generation.
+ tArray<int> new_demes(num_demes);
+
+ if(total_fitness > 0.0) {
+ for (int i = 0; i < num_demes; i++) {
+ double birth_choice = (double) m_world->GetRandom().GetDouble(total_fitness);
+ double test_total = 0;
+ for (int test_deme = 0; test_deme < num_demes; test_deme++) {
+ test_total += deme_fitness[test_deme];
+ if (birth_choice < test_total) {
+ new_demes[i] = test_deme;
+ break;
+ }
+ }
+ }
+ } else {
+ for(int i=0; i<num_demes; ++i) {
+ new_demes[i] = i;
+ }
+ }
+
+ // Track how many of each deme we should have.
+ tArray<int> deme_count(num_demes);
+ deme_count.SetAll(0);
+ for (int i = 0; i < num_demes; i++) {
+ deme_count[new_demes[i]]++;
+ }
+
+ tArray<bool> is_init(num_demes);
+ is_init.SetAll(false);
+
+ // Copy demes until all deme counts are 1.
+ while (true) {
+ // Find the next deme to copy...
+ int from_deme, to_deme;
+ for (from_deme = 0; from_deme < num_demes; from_deme++) {
+ if (deme_count[from_deme] > 1) break;
+ }
+ if (from_deme == num_demes) break; // If we don't find another deme to copy
+
+ for (to_deme = 0; to_deme < num_demes; to_deme++) {
+ if (deme_count[to_deme] == 0) break;
+ }
+
+ // We now have both a from and a to deme....
+ deme_count[from_deme]--;
+ deme_count[to_deme]++;
+
+ // Do the actual copy!
+ for (int i = 0; i < deme_size; i++) {
+ int from_cell = from_deme * deme_size + i;
+ int to_cell = to_deme * deme_size + i;
+ if (cell_array[from_cell].IsOccupied() == true) {
+ InjectClone( to_cell, *(cell_array[from_cell].GetOrganism()) );
+ }
+ }
+ is_init[to_deme] = true;
+ }
+
+ // Now re-inject all remaining demes into themselves to reset them.
+ for (int cur_deme = 0; cur_deme < num_demes; cur_deme++) {
+ if (is_init[cur_deme] == true) continue;
+ for (int i = 0; i < deme_size; i++) {
+ int cur_cell = cur_deme * deme_size + i;
+ if (cell_array[cur_cell].IsOccupied() == false) continue;
+ InjectClone( cur_cell, *(cell_array[cur_cell].GetOrganism()) );
+ }
+ }
+
+ deme_birth_count.SetAll(0);
+}
+
+
+
+
// Reset Demes goes through each deme and resets the individual organisms as
// if they were just injected into the population.
Modified: branches/coopcomm/source/main/cPopulation.h
===================================================================
--- branches/coopcomm/source/main/cPopulation.h 2006-12-10 03:59:19 UTC (rev 1122)
+++ branches/coopcomm/source/main/cPopulation.h 2006-12-11 16:18:25 UTC (rev 1123)
@@ -41,6 +41,8 @@
#include "tVector.h"
#endif
+#include <vector>
+#include <utility>
class cAvidaContext;
class cCodeLabel;
@@ -59,6 +61,12 @@
{
public:
typedef tArray<cPopulationCell> t_CellArray;
+ //! So we can iterate over ranges of cells.
+ typedef cPopulationCell* t_CellIterator;
+ //! Represents a range of cells; iteration between them must be valid.
+ typedef std::pair<cPopulationCell*, cPopulationCell*> t_CellRange;
+ //! A list of cell ranges.
+ typedef std::vector<t_CellRange> t_CellRangeList;
private:
// Components...
@@ -69,6 +77,8 @@
cBirthChamber birth_chamber; // Global birth chamber.
tArray<tList<cSaleItem> > market; // list of lists of items for sale, each list goes with 1 label
+ t_CellRangeList m_demeCellRanges; //!< Alternate representation of deme cells.
+
// Data Tracking...
tList<cPopulationCell> reaper_queue; // Death order in some mass-action runs
tVector<int> baseStations;
@@ -141,12 +151,17 @@
void Kaboom(cPopulationCell& in_cell, int distance=0);
void AddSellValue(const int data, const int label, const int sell_price, const int org_id, const int cell_id);
int BuyValue(const int label, const int buy_price, const int cell_id);
+
// Deme-related methods
void CompeteDemes(int competition_type);
+ void CompeteDemes(const std::vector<double>& deme_fitness);
void ResetDemes();
void CopyDeme(int deme1_id, int deme2_id);
void PrintDemeStats();
-
+ //! Returns the cell ranges that correspond to the demes in this population (assumes demes).
+ inline const t_CellRangeList GetDemes() { return m_demeCellRanges; }
+
+
// Process a single organism one instruction...
int ScheduleOrganism(); // Determine next organism to be processed.
void ProcessStep(cAvidaContext& ctx, double step_size, int cell_id);
Modified: branches/coopcomm/source/main/cStats.cc
===================================================================
--- branches/coopcomm/source/main/cStats.cc 2006-12-10 03:59:19 UTC (rev 1122)
+++ branches/coopcomm/source/main/cStats.cc 2006-12-11 16:18:25 UTC (rev 1123)
@@ -98,8 +98,6 @@
, m_data_is_sender(0)
, m_data_is_id_and_grt_sender(0)
, m_data_is_leader(0)
- , m_max_deme_leadership(0)
- , m_max_deme_count(0)
{
task_cur_count.Resize( m_world->GetNumTasks() );
task_last_count.Resize( m_world->GetNumTasks() );
@@ -922,14 +920,18 @@
}
-/*! This captures information related to using demes to elect a leader.
+/*! This captures the maximum fitness of each deme since the last stat reset.
+The max of all elements in m_maxDemeFitnesses is the global max deme fitness.
*/
-void cStats::Demes_Leadership(unsigned int max, unsigned int org_count)//double maxPct)
-{
- if(max > m_max_deme_leadership) {
- m_max_deme_leadership = max;
- m_max_deme_count = org_count;
+void cStats::DemeFitness(const std::vector<double>& deme_fitness) {
+ if(m_maxDemeFitnesses.size()!=deme_fitness.size()) {
+ m_maxDemeFitnesses.resize(deme_fitness.size());
+ std::copy(deme_fitness.begin(), deme_fitness.end(), m_maxDemeFitnesses.begin());
+ return;
}
+ for(unsigned int i=0; i<deme_fitness.size(); ++i) {
+ m_maxDemeFitnesses[i] = std::max(deme_fitness[i], m_maxDemeFitnesses[i]);
+ }
}
@@ -1013,19 +1015,39 @@
df.Write(m_data_is_id_and_grt_sender, "Count of messages where the data field carries an ID, and is greater than the sender's ID.");
df.Write(m_data_is_leader, "Count of messages where the data field is the leader's ID.");
df.Write(m_data_is_id_not_sender.Ave(), "Mean of message data fields where the data field is an ID that is not the sender's ID.");
- df.Write(m_max_deme_leadership, "Maximum number of organisms that agreed on a leader.");
- df.Write(m_max_deme_count, "Size of deme corresponding to max. that agreed on leader.");
df.Endl();
m_msg_data.Clear();
m_data_is_id_not_sender.Clear();
m_count_msgs = m_max_id = m_data_is_id = m_data_is_sender = m_data_is_id_and_grt_sender = m_data_is_leader = 0;
- m_max_deme_leadership = 0;
- m_max_deme_count = 0;
}
/*! The format of this data file is:
+<update> \
+<max deme fitness> \
+<max fitness of deme>...
+*/
+void cStats::PrintDemeFitness(const cString& filename)
+{
+ cDataFile& df = m_world->GetDataFile(filename);
+ df.WriteColumnDesc("Update.");
+ df.WriteColumnDesc("Max. deme fitness");
+ df.WriteColumnDesc("<max fitness of deme>...");
+
+ df.WriteAnonymous(m_update);
+ df.WriteAnonymous(*std::max_element(m_maxDemeFitnesses.begin(), m_maxDemeFitnesses.end()));
+
+ for(unsigned int i=0; i<m_maxDemeFitnesses.size(); ++i) {
+ df.WriteAnonymous(m_maxDemeFitnesses[i]);
+ }
+
+ df.Endl();
+ m_maxDemeFitnesses.clear();
+}
+
+
+/*! The format of this data file is:
<update> <cell id>:<id>...
\todo Not yet implemented.
Modified: branches/coopcomm/source/main/cStats.h
===================================================================
--- branches/coopcomm/source/main/cStats.h 2006-12-10 03:59:19 UTC (rev 1122)
+++ branches/coopcomm/source/main/cStats.h 2006-12-11 16:18:25 UTC (rev 1123)
@@ -258,8 +258,8 @@
cDoubleSum m_data_is_id_not_sender; //!< Sum of message data fields where the data field is an ID that is not the sender's ID.
std::set<int> m_cell_sent_leader; //!< Set of all cells that sent a message carrying the leader's ID.
t_predicate_list m_predicate_list; //!< The list of predicates used to choose which messages to track.
- unsigned int m_max_deme_leadership; //!< The maximum percentage of organisms agreeing on a leader.
- unsigned int m_max_deme_count; //!< Count of organisms that selected a leader.
+ std::vector<double> m_maxDemeFitnesses; //!< The max fitness of each deme.
+
cStats(); // @not_implemented
cStats(const cStats&); // @not_implemented
cStats& operator=(const cStats&); // @not_implemented
@@ -606,8 +606,8 @@
// Coop-comm.
//! Capture information related to sending a message.
void SentMessage(cOrgMessage& msg);
- //! Info about leadership demes.
- void Demes_Leadership(unsigned int max, unsigned int org_count);//double maxPct);
+ //! Captures stats related to the fitness of each deme.
+ void DemeFitness(const std::vector<double>& deme_fitness);
//! Capture information related to organism death.
void OrganismDeath(cOrganism* org);
//! Log leadership-specific data.
@@ -616,6 +616,8 @@
void PrintCellData(const cString& filename);
//! Log message-specific data.
void PrintMessageData(const cString& filename);
+ //! Log the max fitnesses of demes.
+ void PrintDemeFitness(const cString& filename);
//! Log ID-specific data.
void PrintIDData(const cString& filename);
//! Print message data file.
Modified: branches/coopcomm/source/tools/tArray.h
===================================================================
--- branches/coopcomm/source/tools/tArray.h 2006-12-10 03:59:19 UTC (rev 1122)
+++ branches/coopcomm/source/tools/tArray.h 2006-12-11 16:18:25 UTC (rev 1123)
@@ -38,6 +38,9 @@
~tArray() { delete [] m_data; }
+ //! For those cases where an unchecked pointer to the data is needed...
+ inline T* GetPtr() { return m_data; }
+
tArray& operator=(const tArray& rhs) {
if (m_size != rhs.GetSize()) ResizeClear(rhs.GetSize());
for(int i = 0; i < m_size; i++) m_data[i] = rhs[i];
More information about the Avida-cvs
mailing list