void Collective::calcNextState(double t, const VectorAccess<double>*x, VectorAccess<double>*nx) { SiteOutputController *oc = site->outputcontroller; oc->log( "at time %g, seeking consensus on proposal %s\n", t, currentProposal.hexString() ); string strat = lparameters.facilitationStrategy(); //oc->log("facilitation strategy is '%s'\n", strat.c_str()); for (int i = 0; i < nX; ++i) oc->log( "Individual %d values %s at %g\n", i, currentProposal.hexString(), individuals[i].evaluate(currentProposal) ); if (strat == "each proposes one") { vector<BitString> amendments(nX); vector< set<unsigned> > blocks(nX); copyTo(x, nx); for (int i = 0; i < nX; ++i) { // ask each individual to make proposed improvements amendments[i] = individuals[i].makeProposal(currentProposal); if (amendments[i] != currentProposal) { oc->log( "Individual %d proposes %s\n", i, amendments[i].hexString() ); oc->log( "Individual %d values %s at %g\n", i, amendments[i].hexString(), individuals[i].evaluate(amendments[i]) ); // is the new proposal acceptable to everyone (or to anyone)? for (int j = 0; j < nX; ++j) if (j != i) { oc->log( "Individual %d values %s at %g\n", j, amendments[i].hexString(), individuals[j].evaluate(amendments[i]) ); if ( ! individuals[j].acceptableReplacement(amendments[i], currentProposal) ) { oc->log( "Individual %d blocks %s\n", j, amendments[i].hexString() ); blocks[i].insert(j); } } } else oc->log( "Individual %d has no proposal\n", i ); } // any proposals get no blocks? finished = true; for (int i = 0; i < nX; ++i) if (blocks[i].size() == 0 && amendments[i] != currentProposal) { oc->log( "Proposal %s has no objections\n", amendments[i].hexString() ); // FIXME: we can't just take the first one each time currentProposal = amendments[i]; finished = false; break; } } else if (strat == "one proposal at a time" or strat == "anyone proposes" or strat == "blockers propose") { unsigned ind; if (strat == "blockers propose") { vector<unsigned> blockers; for (unsigned call_on = 0; call_on < individuals.size(); ++call_on) if ( ! individuals[call_on].acceptable(currentProposal) ) { oc->log("Individual %d blocks the proposal.\n", call_on); blockers.push_back(call_on); } if (blockers.empty()) { oc->log("Nobody blocks the proposal.\n"); finished = true; return; } ind = blockers[rand_index(blockers.size())]; } else ind = rand_index(individuals.size()); finished = false; BitString newProposal = individuals[ind].makeProposal(currentProposal); int mnpf = lparameters.maxNumberOfProposalFailures(); if (mnpf == -1) mnpf = 2*currentProposal.nBits(); if (newProposal == currentProposal) { oc->log("Individual %d has no proposal\n", ind); ++n_failures; if (n_failures > mnpf) { finished = true; } } else { oc->log("Individual %d proposes %s\n", ind, newProposal.hexString()); oc->log("Individual %d values %s at %g\n", ind, newProposal.hexString(), individuals[ind].evaluate(newProposal)); bool accept = true; for (unsigned judge = 0; judge < individuals.size(); ++judge) if (judge != ind) { oc->log("Individual %d values %s at %g\n", judge, newProposal.hexString(), individuals[judge].evaluate(newProposal)); if ( ! individuals[judge].acceptableReplacement(newProposal, currentProposal) ) { oc->log("Individual %d blocks %s\n", judge, newProposal.hexString()); accept = false; break; } } if (accept) { oc->log("Proposal %s is accepted\n", newProposal.hexString()); currentProposal = newProposal; } else { oc->log("Proposal %s is rejected\n", newProposal.hexString()); ++n_failures; if (n_failures > mnpf) { finished = true; } } } } else if (strat == "search minimum landscape") { //unsigned triesRemaining = lparameters.maxNumberOfProposalFailures(); typedef individuals_landscape_iterator< typeof individuals.begin(), typeof individuals[0].fitnesslandscape> LandscapeIteratorT; LandscapeIteratorT li(individuals.begin(), individuals.end()), le(individuals.end(), individuals.end()); MinimumLandscape<LandscapeIteratorT> ml(li, le); oc->log("Search minimum landscape for improvement to %s\n", currentProposal.hexString()); BitString nextProposal = ml.bestNeighbor(currentProposal); oc->log("Next proposal is %s\n", nextProposal.hexString()); if (nextProposal == currentProposal) finished = true; else currentProposal = nextProposal; } else { oc->log("Unknown strategy '%s'!\n", strat.c_str()); finished = true; } }