[Avida-SVN] r1146 - in branches/coopcomm/source: actions main
dknoester at myxo.css.msu.edu
dknoester at myxo.css.msu.edu
Sun Dec 17 19:05:22 PST 2006
Author: dknoester
Date: 2006-12-17 22:05:22 -0500 (Sun, 17 Dec 2006)
New Revision: 1146
Modified:
branches/coopcomm/source/actions/PopulationActions.cc
branches/coopcomm/source/actions/PrintActions.cc
branches/coopcomm/source/main/cOrgMessage.h
branches/coopcomm/source/main/cOrganism.cc
branches/coopcomm/source/main/cPopulation.cc
branches/coopcomm/source/main/cPopulation.h
branches/coopcomm/source/main/cPopulationCell.cc
branches/coopcomm/source/main/cPopulationCell.h
branches/coopcomm/source/main/cStats.cc
branches/coopcomm/source/main/cStats.h
Log:
Added more detailed logging options for leader election, including:
- Changed IDs
- Elected IDs
- Message logging
and Cell IDs.
Note: The message_log.dat file has been renamed to message_summary.dat.
Modified: branches/coopcomm/source/actions/PopulationActions.cc
===================================================================
--- branches/coopcomm/source/actions/PopulationActions.cc 2006-12-18 02:23:01 UTC (rev 1145)
+++ branches/coopcomm/source/actions/PopulationActions.cc 2006-12-18 03:05:22 UTC (rev 1146)
@@ -984,14 +984,21 @@
};
+/*! A DemeFitnessFunction that also ratchets the leader when a deme has reached agreement.
+By "ratchet," we mean that the elected leader's ID is reset, and the fitness of this deme
+includes a reward for having elected that leader.
+*/
struct ratcheting_popular_vote
: public std::binary_function<cPopulation::t_CellIterator, cPopulation::t_CellIterator, double> {
+ //! Returns a description of this fitness function.
static std::string GetDescription() {
return "ratcheting popular vote";
}
- ratcheting_popular_vote(cWorld* world, const cString& args)
- : m_world(world) {
+ //! Constructor; must be supplied with the world and deme_id.
+ ratcheting_popular_vote(unsigned int deme_id, cWorld* world, const cString& args)
+ : m_demeId(deme_id)
+ , m_world(world) {
m_previousLeaders.clear();
}
@@ -1003,8 +1010,7 @@
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.
+ The resulting fitness is (current_max_votes + num_previous_leaders*100)^2.
*/
double operator()(cPopulation::t_CellIterator begin, cPopulation::t_CellIterator end) {
vote_calculator vc = std::for_each(begin, end, vote_calculator());
@@ -1012,32 +1018,41 @@
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);
+ cPopulationCell* cell = cPopulationCell::GetRandomCellIDMap()[vt.second.m_maxID];
+ m_world->GetStats().DemeElected(m_demeId, vt.second.m_maxID, cell->GetID());
vt.second.m_maxVote = 0;
// and reset the leader ID
- cPopulationCell::GetRandomCellIDMap()[vt.second.m_maxID]->ResetRandomCellID();
+ cell->ResetRandomCellID();
}
- // square it so that there's always a huge benefit to getting just one more.
+ // 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;
+ std::vector<int> m_previousLeaders; //!< The list of previous leaders.
+ unsigned int m_demeId; //!< The id of the deme associated with this fitness function.
+ cWorld* m_world; //!< Pointer to the world (for cStats).
};
+/*! A fitness function that maintains the state of the function objects used to calculate
+the fitness for each deme.
+*/
template< typename DemeFitnessFunction >
struct stateful_fitness : public std::unary_function<cPopulation::t_CellRangeList, void> {
+ //! Returns a description of the fitness function.
static std::string GetDescription() {
return "Stateful fitness:" + DemeFitnessFunction::GetDescription();
}
+ //! Constructor.
stateful_fitness(cWorld* world, const cString& args)
: m_world(world)
, m_args(args) {
reset();
}
+ //! Calculates the fitness of each deme.
void operator()(cPopulation::t_CellRangeList cell_ranges) {
typedef typename std::vector<DemeFitnessFunction>::iterator dffiter;
cPopulation::t_CellRangeList::iterator demei = cell_ranges.begin();
@@ -1048,21 +1063,34 @@
}
}
+ //! Resets the fitness function used for each deme.
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));
+ m_demeFitness.push_back(DemeFitnessFunction(i,m_world,m_args));
}
}
+ //! Retrieve the fitnesses of each deme.
const std::vector<double>& fitnesses() { return m_fitness; }
+ //! List of dunction objects that calculate deme fitness.
std::vector<DemeFitnessFunction> m_demeFitness;
- std::vector<double> m_fitness;
- cWorld* m_world;
- cString m_args;
+ std::vector<double> m_fitness; //!< Current fitnesses of each deme.
+ cWorld* m_world; //!< Pointer to the world (for cPopulation).
+ cString m_args; //!< Initialization arguments (for resetting function objects).
};
+
+/*! An adaptable compete demes event.
+This event is modeled after the STL's Adaptable{Unary,Binary} Functions, in that
+it uses templates to modify much of its behavior.
+
+- Every time this event is fired (based on events.cfg), the fitness of each deme
+is calculated using the FitnessFunction.
+- Then, if the CompetitionPredicate evaluates to true, then the demes are competed
+against each other according to the CompetitionStrategy.
+*/
template< typename FitnessFunction,
typename CompetitionStrategy=ga_competition_strategy<FitnessFunction>,
typename CompetePredicate=always_compete<FitnessFunction> >
@@ -1072,6 +1100,7 @@
typedef CompetitionStrategy competition_strategy;
typedef CompetePredicate compete_predicate;
+ //! \todo This is broken; at return the std::string is destroyed.
static const cString GetDescription() {
return std::string("Adaptable Deme Competition: " +
FitnessFunction::GetDescription() + " ; " +
@@ -1703,6 +1732,31 @@
};
+class cActionToggleMessageLog : public cAction
+{
+public:
+ cActionToggleMessageLog(cWorld* world, const cString& args)
+ : cAction(world, args) {
+ }
+
+ virtual ~cActionToggleMessageLog() { }
+
+ //! Return a string description of the arguments for this action.
+ static const cString GetDescription()
+ {
+ return "Toggles the level of detail in message logging.";
+ }
+
+ //! Perform this action.
+ void Process(cAvidaContext& ctx)
+ {
+ m_world->GetStats().ToggleMessageLog();
+ }
+};
+
+
+
+
void RegisterPopulationActions(cActionLibrary* action_lib)
{
action_lib->Register<cActionInject>("Inject");
@@ -1741,6 +1795,7 @@
action_lib->Register<cActionAddMessagePredicate>("AddMessagePredicate");
action_lib->Register<cActionAddBaseStationPredicate>("AddBaseStationPredicate");
action_lib->Register<cActionMessageRain>("MessageRain");
+ action_lib->Register<cActionToggleMessageLog>("ToggleMessageLog");
action_lib->Register<
cActionAdaptableCompeteDemes< stateful_fitness<ratcheting_popular_vote>,
ga_competition_strategy<stateful_fitness<ratcheting_popular_vote> >,
Modified: branches/coopcomm/source/actions/PrintActions.cc
===================================================================
--- branches/coopcomm/source/actions/PrintActions.cc 2006-12-18 02:23:01 UTC (rev 1145)
+++ branches/coopcomm/source/actions/PrintActions.cc 2006-12-18 03:05:22 UTC (rev 1146)
@@ -66,17 +66,16 @@
STATS_OUT_FILE(PrintMarketData, market.dat );
// Coop-comm
-STATS_OUT_FILE(PrintLeaderData, leader_log.dat);
-STATS_OUT_FILE(PrintCellData, cell_log.dat);
-STATS_OUT_FILE(PrintMessageData, message_log.dat);
+STATS_OUT_FILE(PrintCellIDs, cell_ids.dat);
+STATS_OUT_FILE(PrintMessageSummary, message_summary.dat);
STATS_OUT_FILE(PrintDemeFitness, deme_fitness.dat);
STATS_OUT_FILE(PrintDemeGenomes, deme_genomes.dat);
-STATS_OUT_FILE(PrintIDData, id_log.dat);
STATS_OUT_FILE(PrintMessageDataPerUpdate, message.dat);
-STATS_OUT_FILE(PrintMessageSnapshot, msg_snapshot.dat);
STATS_OUT_FILE(PrintPredicatedMessages, predicated_msgs.dat);
+STATS_OUT_FILE(PrintElectionRecord, election.dat);
+STATS_OUT_FILE(PrintIDChanges, id_changes.dat);
+STATS_OUT_FILE(PrintMessageLog, message_log.dat);
-
#define POP_OUT_FILE(METHOD, DEFAULT) /* 1 */ \
class cAction ## METHOD : public cAction { /* 2 */ \
private: /* 3 */ \
@@ -1529,16 +1528,18 @@
action_lib->Register<cActionSetVerbose>("SetVerbose");
// Coop-comm actions.
- action_lib->Register<cActionPrintLeaderData>("PrintLeaderData");
- action_lib->Register<cActionPrintCellData>("PrintCellData");
- action_lib->Register<cActionPrintMessageData>("PrintMessageData");
+ action_lib->Register<cActionPrintCellIDs>("PrintCellIDs");
+ action_lib->Register<cActionPrintMessageSummary>("PrintMessageSummary");
action_lib->Register<cActionPrintDemeFitness>("PrintDemeFitness");
action_lib->Register<cActionPrintDemeGenomes>("PrintDemeGenomes");
- action_lib->Register<cActionPrintIDData>("PrintIDData");
action_lib->Register<cActionPrintMessageDataPerUpdate>("PrintMessageDataPerUpdate");
- action_lib->Register<cActionPrintMessageSnapshot>("PrintMessageSnapshot");
action_lib->Register<cActionPrintPredicatedMessages>("PrintPredicatedMessages");
+ action_lib->Register<cActionPrintElectionRecord>("PrintElectionRecord");
+ action_lib->Register<cActionPrintIDChanges>("PrintIDChanges");
+ action_lib->Register<cActionPrintMessageLog>("PrintMessageLog");
+
+
// @DMB - The following actions are DEPRECATED aliases - These will be removed in 2.7.
action_lib->Register<cActionPrintAverageData>("print_average_data");
action_lib->Register<cActionPrintErrorData>("print_error_data");
Modified: branches/coopcomm/source/main/cOrgMessage.h
===================================================================
--- branches/coopcomm/source/main/cOrgMessage.h 2006-12-18 02:23:01 UTC (rev 1145)
+++ branches/coopcomm/source/main/cOrgMessage.h 2006-12-18 03:05:22 UTC (rev 1146)
@@ -26,19 +26,18 @@
unsigned int m_data;
unsigned int m_label;
- cOrgMessage() : m_pSender(NULL), m_pReceiver(NULL), m_data(0), m_label(0) { }
+ cOrgMessage()
+ : m_pSender(NULL), m_pReceiver(NULL), m_data(0), m_label(0) {
+ }
public:
- cOrgMessage(cOrganism* sender) :
- m_pSender(sender),
- m_pReceiver(NULL),
- m_data(0),
- m_label(0)
- { }
+ cOrgMessage(cOrganism* sender)
+ : m_pSender(sender), m_pReceiver(NULL), m_data(0), m_label(0) {
+ }
- explicit cOrgMessage(int data, int label) :
- m_pSender(NULL), m_pReceiver(NULL), m_data(data), m_label(label) {
- }
+ explicit cOrgMessage(int data, int label)
+ : m_pSender(NULL), m_pReceiver(NULL), m_data(data), m_label(label) {
+ }
static cOrgMessage EmptyMessage() { return cOrgMessage(); }
Modified: branches/coopcomm/source/main/cOrganism.cc
===================================================================
--- branches/coopcomm/source/main/cOrganism.cc 2006-12-18 02:23:01 UTC (rev 1145)
+++ branches/coopcomm/source/main/cOrganism.cc 2006-12-18 03:05:22 UTC (rev 1146)
@@ -87,9 +87,6 @@
cOrganism::~cOrganism()
{
- // Stat-tracking.
- m_world->GetStats().OrganismDeath(this);
-
// Clean up after organisms that think this one is their leader.
for(t_organism_list::iterator i=m_lead.begin(); i!=m_lead.end(); ++i) {
(*i)->ResetLeader();
Modified: branches/coopcomm/source/main/cPopulation.cc
===================================================================
--- branches/coopcomm/source/main/cPopulation.cc 2006-12-18 02:23:01 UTC (rev 1145)
+++ branches/coopcomm/source/main/cPopulation.cc 2006-12-18 03:05:22 UTC (rev 1146)
@@ -268,7 +268,11 @@
m_demeCellRanges.push_back(t_CellRange(cell_array.GetPtr()+i*deme_size,
cell_array.GetPtr()+(i+1)*deme_size));
}
-
+ // Cells need to know which deme they're part of (for cStats).
+ for(int i=0,j=0; i<cell_array.GetSize(); ++i) {
+ j = i / num_demes;
+ cell_array[i].SetDemeID(j);
+ }
return true;
}
@@ -1868,12 +1872,22 @@
}
+cPopulation::t_CellIterator cPopulation::CellBegin() {
+ return cell_array.GetPtr();
+}
+
+cPopulation::t_CellIterator cPopulation::CellEnd() {
+ return cell_array.GetPtr() + cell_array.GetSize();
+}
+
cPopulationCell& cPopulation::GetCell(int in_num)
{
return cell_array[in_num];
}
+
+
void cPopulation::UpdateResources(const tArray<double> & res_change)
{
resource_count.Modify(res_change);
Modified: branches/coopcomm/source/main/cPopulation.h
===================================================================
--- branches/coopcomm/source/main/cPopulation.h 2006-12-18 02:23:01 UTC (rev 1145)
+++ branches/coopcomm/source/main/cPopulation.h 2006-12-18 03:05:22 UTC (rev 1146)
@@ -185,6 +185,8 @@
int GetWorldY() { return world_y; }
t_CellArray& GetCellArray() { return cell_array; }
+ t_CellIterator CellBegin();
+ t_CellIterator CellEnd();
cPopulationCell& GetCell(int in_num);
const tArray<double>& GetResources() const { return resource_count.GetResources(); }
Modified: branches/coopcomm/source/main/cPopulationCell.cc
===================================================================
--- branches/coopcomm/source/main/cPopulationCell.cc 2006-12-18 02:23:01 UTC (rev 1145)
+++ branches/coopcomm/source/main/cPopulationCell.cc 2006-12-18 03:05:22 UTC (rev 1146)
@@ -13,6 +13,7 @@
#include "cOrganism.h"
#include "cTools.h"
#include "cWorld.h"
+#include "cStats.h"
using namespace std;
@@ -25,6 +26,7 @@
, organism(NULL)
, mutation_rates(NULL)
, cur_input(0)
+ , m_demeId(0)
, organism_count(0)
{
}
@@ -34,6 +36,7 @@
, organism(in_cell.organism)
, cur_input(in_cell.cur_input)
, cell_id(in_cell.cell_id)
+ , m_demeId(0)
, organism_count(in_cell.organism_count)
{
for (int i = 0; i < nHardware::IO_SIZE; i++) input_array[i] = in_cell.input_array[i];
@@ -52,6 +55,7 @@
for (int i = 0; i < nHardware::IO_SIZE; i++) input_array[i] = in_cell.input_array[i];
cur_input = in_cell.cur_input;
cell_id = in_cell.cell_id;
+ m_demeId = in_cell.m_demeId;
organism_count = in_cell.organism_count;
if (mutation_rates == NULL)
mutation_rates = new cMutationRates(*in_cell.mutation_rates);
@@ -231,7 +235,13 @@
*/
void cPopulationCell::ResetRandomCellID()
{
+ int old_id=m_rand_id;
+ int new_id=m_world->GetRandom().GetUInt(INT_MAX); // Max value must be an int.
+
s_rand_ids.erase(m_rand_id);
- m_rand_id = m_world->GetRandom().GetUInt(INT_MAX); // Max value must be an int.
+ m_rand_id = new_id;
s_rand_ids.insert(std::make_pair(m_rand_id, this));
+
+ // Now let's log the ID change...
+ m_world->GetStats().CellIDChange(*this, old_id, new_id);
}
Modified: branches/coopcomm/source/main/cPopulationCell.h
===================================================================
--- branches/coopcomm/source/main/cPopulationCell.h 2006-12-18 02:23:01 UTC (rev 1145)
+++ branches/coopcomm/source/main/cPopulationCell.h 2006-12-18 03:05:22 UTC (rev 1146)
@@ -44,6 +44,7 @@
int cur_input; // Next input to give organism.
int cell_id; // Unique id for position of cell in population.
+ int m_demeId; //!< The deme that this cell is part of.
int organism_count; // Total number of orgs to ever inhabit this cell.
unsigned int m_rand_id; //!< Random identifier for this cell.
@@ -79,6 +80,9 @@
bool IsOccupied() const { return organism != NULL; }
bool OK();
+ void SetDemeID(int id) { m_demeId = id; }
+ int GetDemeID() const { return m_demeId; }
+
//! Returns the random ID for this cell.
unsigned int GetRandomCellID() const { return m_rand_id; }
//!< Retrieves the position (x,y) coordinates of this cell.
Modified: branches/coopcomm/source/main/cStats.cc
===================================================================
--- branches/coopcomm/source/main/cStats.cc 2006-12-18 02:23:01 UTC (rev 1145)
+++ branches/coopcomm/source/main/cStats.cc 2006-12-18 03:05:22 UTC (rev 1146)
@@ -92,13 +92,13 @@
, num_sold(0)
, num_used(0)
, num_own_used(0)
- , m_count_org_died(0)
, m_count_msgs(0)
, m_max_id(0)
, m_data_is_id(0)
, m_data_is_sender(0)
, m_data_is_id_and_grt_sender(0)
, m_data_is_leader(0)
+ , m_detailedMessageLog(false)
{
task_cur_count.Resize( m_world->GetNumTasks() );
task_last_count.Resize( m_world->GetNumTasks() );
@@ -893,6 +893,14 @@
*/
void cStats::SentMessage(cOrgMessage& msg)
{
+ if(m_detailedMessageLog) {
+ // Create a message record.
+ m_messagesByDeme[msg.GetSender()->GetCell()->GetDemeID()].push_back(
+ MessageRecord(m_update, msg.GetSender()->GetCellID(),
+ msg.GetReceiver()->GetCellID(),
+ msg.GetLabel(), msg.GetData()));
+ }
+
++m_count_msgs;
num_msg_sent++; // added because m_count_msgs is reset in cStats::PrintMessageData
m_msg_data.Add(msg.GetData());
@@ -943,60 +951,76 @@
}
-/*! This captures all information related to an organism's death.
-
-This is different than RecordDeath() (above), in that we have a handle to the
-organism that is about to die. This lets us record things like the max message
-sent by the organism, correlate that to the cell, etc.
-
-\todo mean max-valued message per cell.
-\todo mean message per cell
+/*! Records the leader elected by the given deme.
*/
-void cStats::OrganismDeath(cOrganism* org)
+void cStats::DemeElected(unsigned int deme_id, int leader_id, int cell_id)
{
- ++m_count_org_died;
+ m_electionRecord.push_back(ElectionRecord(GetUpdate(), deme_id, leader_id, cell_id));
}
-/*! The format of this data file is:
-<update> <id>:<#votes>...
-
-\todo Not yet implemented.
-*/
-void cStats::PrintLeaderData(const cString& filename)
+void cStats::PrintElectionRecord(const cString& filename)
{
- cDataFile& df = m_world->GetDataFile(filename);
- df.Write(m_update, "Update");
+ cDataFile& df = m_world->GetDataFile(filename);
+ df.WriteColumnDesc("Update.");
+ df.WriteColumnDesc("{update of election, deme id, leader id, cell_id}...");
+
+ df.WriteAnonymous(m_update);
+ std::ofstream& out = df.GetOFStream();
+ for(std::vector<ElectionRecord>::iterator i=m_electionRecord.begin();
+ i!=m_electionRecord.end(); ++i) {
+ out << "{" << i->m_update << "," << i->m_demeId << "," <<
+ i->m_leaderId << "," << i->m_cellId << "} ";
+ }
df.Endl();
+ m_electionRecord.clear();
}
-/*! The format of this data file is:
-<update> \
-<# died orgs> \
-<mean max-valued msg> \
-<#cells that sent the leader's id> \
-<cell-id that sent leader>...
+/*! Records an ID change.
*/
-void cStats::PrintCellData(const cString& filename)
+void cStats::CellIDChange(const cPopulationCell& cell, int old_id, int new_id)
{
- cDataFile& df = m_world->GetDataFile(filename);
+ m_idChangeRecord.push_back(IdChangeRecord(GetUpdate(),
+ cell.GetDemeID(), cell.GetID(), old_id, new_id));
+}
+
+
+void cStats::PrintIDChanges(const cString& filename)
+{
+ cDataFile& df = m_world->GetDataFile(filename);
df.WriteColumnDesc("Update.");
- df.WriteColumnDesc("Count of organisms that have died.");
- df.WriteColumnDesc("Number of cells that sent a message containing the leader's ID.");
- df.WriteColumnDesc("IDs of cells that sent a message carrying the leader's ID (may be empty).");
- df.FlushComments();
+ df.WriteColumnDesc("{update of change, deme id, old_id, new_id}...");
+
+ df.WriteAnonymous(m_update);
+ std::ofstream& out = df.GetOFStream();
+ for(std::vector<IdChangeRecord>::iterator i=m_idChangeRecord.begin();
+ i!=m_idChangeRecord.end(); ++i) {
+ out << "{" << i->m_update << "," << i->m_demeId << "," <<
+ i->m_oldId << "," << i->m_newId << "} ";
+ }
+ df.Endl();
+ m_idChangeRecord.clear();
+}
+
+void cStats::PrintMessageLog(const cString& filename)
+{
+ cDataFile& df = m_world->GetDataFile(filename);
+ df.WriteColumnDesc("Update.");
+ df.WriteColumnDesc("{update, deme id, sender cell-seq. id, recvr cell-seq. id, label, data}...");
+
df.WriteAnonymous(m_update);
- df.WriteAnonymous(m_count_org_died);
- df.WriteAnonymous((unsigned int)m_cell_sent_leader.size());
- for(std::set<int>::iterator i=m_cell_sent_leader.begin(); i!=m_cell_sent_leader.end(); ++i) {
- df.WriteAnonymous(*i);
+ std::ofstream& out = df.GetOFStream();
+ for(t_MessageLog::iterator i=m_messagesByDeme.begin();
+ i!=m_messagesByDeme.end(); ++i) {
+ for(t_MessageRecord::iterator j=i->second.begin(); j!=i->second.end(); ++j) {
+ out << "{" << j->m_update << "," << i->first << "," << j->m_sender << "," << j->m_receiver
+ << "," << j->m_label << "," << j->m_data << "} ";
+ }
}
df.Endl();
-
- m_count_org_died = 0;
- m_cell_sent_leader.clear();
+ m_messagesByDeme.clear();
}
@@ -1011,7 +1035,7 @@
<# msgs: data==leader's ID> \
<mean non-sender data field and data==ID>
*/
-void cStats::PrintMessageData(const cString& filename)
+void cStats::PrintMessageSummary(const cString& filename)
{
cDataFile& df = m_world->GetDataFile(filename);
df.Write(m_update, "Update");
@@ -1064,11 +1088,18 @@
cDataFile& df = m_world->GetDataFile(filename);
df.WriteComment("Genomes that comprise the deme with maximum fitness.");
df.WriteColumnDesc("Update.");
+ df.WriteColumnDesc("Deme ID.");
+ df.WriteColumnDesc("Cell begin.");
+ df.WriteColumnDesc("Cell end.");
df.WriteColumnDesc("Genome ID...");
df.WriteAnonymous(m_update);
+ df.WriteAnonymous(m_maxDemeIndex);
cPopulation::t_CellRangeList demes = m_world->GetPopulation().GetDemes();
assert(demes.size()>m_maxDemeIndex);
+ df.WriteAnonymous(demes[m_maxDemeIndex].first - m_world->GetPopulation().CellBegin());
+ df.WriteAnonymous(demes[m_maxDemeIndex].second - m_world->GetPopulation().CellBegin());
+
for(cPopulation::t_CellIterator i=demes[m_maxDemeIndex].first;
i!=demes[m_maxDemeIndex].second; ++i) {
if(i->IsOccupied()) {
@@ -1078,18 +1109,7 @@
df.Endl();
}
-/*! The format of this data file is:
-<update> <cell id>:<id>...
-\todo Not yet implemented.
-*/
-void cStats::PrintIDData(const cString& filename)
-{
- cDataFile& df = m_world->GetDataFile(filename);
- df.Write(m_update, "Update");
- df.Endl();
-}
-
//added by ben
/*! prints message numbers for an update
*/
@@ -1115,33 +1135,20 @@
}
-/*! This method iterates through every cell in the population, and for every
-organism that it finds, it prints:
-<cell_id:random_cell_id:mean_data_field:mean_label_field>...
-
-The intent is that these snapshots can be strung together in order to get a picture
-of the types of messages that are being sent throughout the population.
-
-Note: This will generate a large data file.
+/*! This method iterates through every cell in the population and prints the
+cell-sequential and cell-random IDs.
*/
-void cStats::PrintMessageSnapshot(const cString& filename)
+void cStats::PrintCellIDs(const cString& filename)
{
cDataFile& df = m_world->GetDataFile(filename);
df.WriteColumnDesc("Update.");
- df.WriteColumnDesc("<cell_id:random_cell_id:mean_data_field:mean_label_field>...");
+ df.WriteColumnDesc("Cell-sequential ID:Cell-random ID...");
df.WriteAnonymous(m_update);
std::ofstream& out = df.GetOFStream();
cPopulation::t_CellArray& cells = m_world->GetPopulation().GetCellArray();
for(int i=0; i<cells.GetSize(); ++i) {
- if(cells[i].IsOccupied()) {
- cOrganism::t_message_list& sent = cells[i].GetOrganism()->GetSentMessages();
- if(sent.empty()) continue;
- cOrgMessage_Sum sum = std::for_each(sent.begin(), sent.end(), cOrgMessage_Sum());
- out << cells[i].GetID() << ":" << cells[i].GetRandomCellID()
- << ":" << sum.MeanData()
- << ":" << sum.MeanLabel() << " ";
- }
+ out << cells[i].GetID() << ":" << cells[i].GetRandomCellID() << " ";
}
df.Endl();
}
Modified: branches/coopcomm/source/main/cStats.h
===================================================================
--- branches/coopcomm/source/main/cStats.h 2006-12-18 02:23:01 UTC (rev 1145)
+++ branches/coopcomm/source/main/cStats.h 2006-12-18 03:05:22 UTC (rev 1146)
@@ -15,6 +15,7 @@
#include <fstream>
#include <iostream>
#include <set>
+#include <map>
#ifndef defs_h
#include "defs.h"
@@ -247,7 +248,6 @@
int num_own_used;
// Stats for coop-comm.
- unsigned int m_count_org_died; //!< Count of the number of organisms that died.
unsigned int m_count_msgs; //!< Count of the number of messages sent.
cDoubleSum m_msg_data; //!< Sum of all message data fields.
unsigned int m_max_id; //!< The maximum ID in the population.
@@ -262,7 +262,63 @@
//! The index of the deme with maximum fitness within m_maxDemeFitness; correlates to
//! the index of the cell range from cPopulation::GetDemes().
unsigned int m_maxDemeIndex;
+
+ //! An ElectionRecord is created every time a deme elects a leader.
+ struct ElectionRecord {
+ ElectionRecord(int update, unsigned int deme_id, int leader_id, int cell_id)
+ : m_update(update)
+ , m_demeId(deme_id)
+ , m_leaderId(leader_id)
+ , m_cellId(cell_id) {
+ }
+
+ int m_update;
+ unsigned int m_demeId;
+ int m_leaderId;
+ int m_cellId;
+ };
+ //! A log of all the elections that have occured since the last PrintElectionRecord.
+ std::vector<ElectionRecord> m_electionRecord;
+
+ //! An IdChangeRecord is created every time a cell ID changes.
+ struct IdChangeRecord {
+ IdChangeRecord(int update, unsigned int deme_id, int cell_id, int old_id, int new_id)
+ : m_update(update)
+ , m_demeId(deme_id)
+ , m_cellId(cell_id)
+ , m_oldId(old_id)
+ , m_newId(new_id) {
+ }
+
+ int m_update;
+ unsigned int m_demeId;
+ int m_cellId, m_oldId, m_newId;
+ };
+
+ //! A log of all the ID changes that have occured since the last PrintIdChangeRecord.
+ std::vector<IdChangeRecord> m_idChangeRecord;
+
+ struct MessageRecord {
+ MessageRecord(int update, int sender, int receiver, int label, int data)
+ : m_update(update)
+ , m_sender(sender)
+ , m_receiver(receiver)
+ , m_label(label)
+ , m_data(data) {
+ }
+
+ int m_update, m_sender, m_receiver, m_label, m_data;
+ };
+
+ typedef std::vector<MessageRecord> t_MessageRecord;
+ typedef std::map<unsigned int, t_MessageRecord > t_MessageLog;
+ //! Messages by deme id.
+ t_MessageLog m_messagesByDeme;
+
+ //! A flag to indicate if we should be recording all messages.
+ bool m_detailedMessageLog;
+
cStats(); // @not_implemented
cStats(const cStats&); // @not_implemented
cStats& operator=(const cStats&); // @not_implemented
@@ -613,26 +669,32 @@
void DemeFitness(const std::vector<double>& deme_fitness);
//! Capture information related to organism death.
void OrganismDeath(cOrganism* org);
- //! Log leadership-specific data.
- void PrintLeaderData(const cString& filename);
+ //! Called when a deme has elected a leader.
+ void DemeElected(unsigned int deme_id, int leader_id, int cell_id);
+ //! Print the election records.
+ void PrintElectionRecord(const cString& filename);
+ //! Record that a cell's ID has changed.
+ void CellIDChange(const cPopulationCell& cell, int old_id, int new_id);
+ //! Print the change id records.
+ void PrintIDChanges(const cString& filename);
+ //! Prints a log of all messages sent.
+ void PrintMessageLog(const cString& filename);
//! Log cell-specific data.
- void PrintCellData(const cString& filename);
+ void PrintCellIDs(const cString& filename);
//! Log message-specific data.
- void PrintMessageData(const cString& filename);
+ void PrintMessageSummary(const cString& filename);
//! Log the max fitnesses of demes.
void PrintDemeFitness(const cString& filename);
//! Log the constituent genomes of the deme with the highest fitness.
void PrintDemeGenomes(const cString& filename);
- //! Log ID-specific data.
- void PrintIDData(const cString& filename);
//! Print message data file.
void PrintMessageDataPerUpdate(const cString& filename);
- //! Print a snapshot of specific message activity.
- void PrintMessageSnapshot(const cString& filename);
//! Prints information regarding messages that "passed" their predicate.
void PrintPredicatedMessages(const cString& filename);
//! Adds a predicate that will be evaluated for each message.
void AddMessagePredicate(cOrgMessage_Predicate* predicate);
+ //! Toggles detailed recording of message activity.
+ void ToggleMessageLog() { m_detailedMessageLog = !m_detailedMessageLog; }
//added by ben for messaging stats
void IncSent() {num_msg_sent++;} //!< inc. number of messages sent
More information about the Avida-cvs
mailing list