AgentProgram crossover(const AgentProgram &prog_a, const AgentProgram &prog_b) { AgentProgram child; // either one rule priority order or the other (don't try to mix!) if (pafrand() % 2) { for (int i = 0; i < 4; i++) { child.m_rule_order[i] = prog_a.m_rule_order[i]; } } else { for (int i = 0; i < 4; i++) { child.m_rule_order[i] = prog_b.m_rule_order[i]; } } // for each rule, either one rule threshold / probability or the other: for (int i = 0; i < 4; i++) { if (pafrand() % 2) { child.m_rule_threshold[i] = prog_a.m_rule_threshold[i]; } else { child.m_rule_threshold[i] = prog_b.m_rule_threshold[i]; } if (pafrand() % 2) { child.m_rule_probability[i] = prog_a.m_rule_probability[i]; } else { child.m_rule_probability[i] = prog_b.m_rule_probability[i]; } } return child; }
void AgentProgram::mutate() { // do mutate rule order occassionally: if (pafrand() % 20 == 0) { // rule order relies on putting rules into slots: for (int i = 0; i < 4; i++) { m_rule_order[i] = -1; } for (int j = 0; j < 4; j++) { int choice = pafrand() % (4 - j); for (int k = 0; k < choice + 1; k++) { if (m_rule_order[k] != -1) { choice++; } } m_rule_order[choice] = j; } } // mutate the rule threshold / probabilities for (int i = 0; i < 4; i++) { if (pafrand() % 20 == 0) { // 5% mutation rate m_rule_threshold[i] = float(prandom() * 100.0); } if (pafrand() % 20 == 0) { // 5% mutation rate m_rule_probability[i] = float(prandom()); } } }
void AgentProgram::mutate() { // don't mutate program type /* if (pafrand() % 20 == 0) { m_vbin = (pafrand() % 7) + 1; } if (pafrand() % 20 == 0) { m_vahead = (pafrand() % m_vbin); } if (pafrand() % 20 == 0) { m_ahead_threshold = prandom() * 19.0 + 1.0; } if (pafrand() % 20 == 0) { m_feeler_threshold = prandom() * 4.0 + 1.0; } if (pafrand() % 20 == 0) { m_feeler_probability = prandom(); } */ // do mutate rule order occassionally: if (pafrand() % 20 == 0) { // rule order relies on putting rules into slots: for (int i = 0; i < 4; i++) { m_rule_order[i] = -1; } for (int j = 0; j < 4; j++) { int choice = pafrand() % (4 - j); for (int k = 0; k < choice + 1; k++) { if (m_rule_order[k] != -1) { choice++; } } m_rule_order[choice] = j; } } // mutate the rule threshold / probabilities for (int i = 0; i < 4; i++) { if (pafrand() % 20 == 0) { // 5% mutation rate m_rule_threshold[i] = float(prandom() * 100.0); } if (pafrand() % 20 == 0) { // 5% mutation rate m_rule_probability[i] = float(prandom()); } } }
std::pair<std::vector<TaggedLine>, std::vector<TaggedLine>> BSPTree::makeLines(Communicator *, time_t, const std::vector<TaggedLine> &lines, BSPNode *base) { std::vector<TaggedLine> leftlines; std::vector<TaggedLine> rightlines; // for optimization of the tree (this reduced a six-minute gen time to a 38 second gen time) int chosen = -1; if (lines.size() > 3) { chosen = BSPTree::pickMidpointLine(lines, base->m_parent); } else { chosen = pafrand() % lines.size(); } Line chosenLine = lines[chosen].line; int chosenTag = lines[chosen].tag; base->setLine(chosenLine); base->setTag(chosenTag); Point2f v0 = chosenLine.end() - chosenLine.start(); v0.normalise(); for (size_t i = 0; i < lines.size(); i++) { if (i == static_cast<unsigned int>(chosen)) { continue; } const Line &testline = lines[i].line; int tag = lines[i].tag; Point2f v1 = testline.start() - chosenLine.start(); v1.normalise(); Point2f v2 = testline.end() - chosenLine.start(); v2.normalise(); // should use approxeq here: double a = testline.start() == chosenLine.start() ? 0 : det(v0, v1); double b = testline.end() == chosenLine.start() ? 0 : det(v0, v2); // note sure what to do if a == 0 and b == 0 (i.e., it's parallel... this test at least ensures on the line is // one or the other side) if (a >= 0 && b >= 0) { leftlines.push_back(TaggedLine(testline, tag)); } else if (a <= 0 && b <= 0) { rightlines.push_back(TaggedLine(testline, tag)); } else { Point2f p = intersection_point(chosenLine, testline); Line x = Line(testline.start(), p); Line y = Line(p, testline.end()); if (a >= 0) { if (x.length() > 0.0) // should use a tolerance here too leftlines.push_back(TaggedLine(x, tag)); if (y.length() > 0.0) // should use a tolerance here too rightlines.push_back(TaggedLine(y, tag)); } else { if (x.length() > 0.0) // should use a tolerance here too rightlines.push_back(TaggedLine(x, tag)); if (y.length() > 0.0) // should use a tolerance here too leftlines.push_back(TaggedLine(y, tag)); } } } return std::make_pair(leftlines, rightlines); }
void AgentSet::init(int agent, int trail_num) { if (m_release_locations.size()) { int which = pafrand() % m_release_locations.size(); at(agent).onInit( m_release_locations[which], trail_num ); } else { const PointMap& map = at(agent).getPointMap(); PixelRef pix; do { pix = map.pickPixel(prandom()); } while (!map.getPoint(pix).filled()); at(agent).onInit(pix, trail_num); } }
bool SegmentTulipDepth::run(Communicator *comm, const Options &options, ShapeGraph &map, bool simple_version) { AttributeTable &attributes = map.getAttributeTable(); std::string stepdepth_col_text = "Angular Step Depth"; int stepdepth_col = attributes.insertOrResetColumn(stepdepth_col_text.c_str()); // The original code set tulip_bins to 1024, divided by two and added one // in order to duplicate previous code (using a semicircle of tulip bins) size_t tulip_bins = 513; std::vector<bool> covered(map.getConnections().size()); for (size_t i = 0; i < map.getConnections().size(); i++) { covered[i] = false; } std::vector<std::vector<SegmentData> > bins(tulip_bins); int opencount = 0; for (auto& sel: map.getSelSet()) { int row = depthmapX::getMapAtIndex(map.getAllShapes(), sel)->first; if (row != -1) { bins[0].push_back(SegmentData(0,row,SegmentRef(),0,0.0,0)); opencount++; } } int depthlevel = 0; auto binIter = bins.begin(); int currentbin = 0; while (opencount) { while (binIter->empty()) { depthlevel++; binIter++; currentbin++; if (binIter == bins.end()) { binIter = bins.begin(); } } SegmentData lineindex; if (binIter->size() > 1) { // it is slightly slower to delete from an arbitrary place in the bin, // but it is necessary to use random paths to even out the number of times through equal paths int curr = pafrand() % binIter->size(); auto currIter = binIter->begin() + curr; lineindex = *currIter; binIter->erase(currIter); // note: do not clear choice values here! } else { lineindex = binIter->front(); binIter->pop_back(); } opencount--; if (!covered[lineindex.ref]) { covered[lineindex.ref] = true; Connector& line = map.getConnections()[lineindex.ref]; // convert depth from tulip_bins normalised to standard angle // (note the -1) double depth_to_line = depthlevel / ((tulip_bins - 1) * 0.5); map.getAttributeRowFromShapeIndex(lineindex.ref).setValue(stepdepth_col,depth_to_line); register int extradepth; if (lineindex.dir != -1) { for (auto& segconn: line.m_forward_segconns) { if (!covered[segconn.first.ref]) { extradepth = (int) floor(segconn.second * tulip_bins * 0.5); auto currIter = binIter; bins[(currentbin + tulip_bins + extradepth) % tulip_bins].push_back( SegmentData(segconn.first,lineindex.ref,lineindex.segdepth+1,0.0,0)); opencount++; } } } if (lineindex.dir != 1) { for (auto& segconn: line.m_back_segconns) { if (!covered[segconn.first.ref]) { extradepth = (int) floor(segconn.second * tulip_bins * 0.5); bins[(currentbin + tulip_bins + extradepth) % tulip_bins].push_back( SegmentData(segconn.first,lineindex.ref,lineindex.segdepth+1,0.0,0)); opencount++; } } } } } map.setDisplayedAttribute(-2); // <- override if it's already showing map.setDisplayedAttribute(stepdepth_col); return true; }
AgentProgram crossover(const AgentProgram& prog_a, const AgentProgram& prog_b) { AgentProgram child; // either one sel type or the other: /* if (pafrand() % 2) { child.m_sel_type = prog_a.m_sel_type; } else { child.m_sel_type = prog_b.m_sel_type; } */ /* // either one bin radius or the other if (pafrand() % 2) child.m_vbin = prog_a.m_vbin; else child.m_vbin = prog_b.m_vbin; if (pafrand() % 2) child.m_vahead = prog_a.m_vahead; else child.m_vahead = prog_b.m_vahead; if (pafrand() % 2) child.m_ahead_threshold = prog_a.m_ahead_threshold; else child.m_ahead_threshold = prog_b.m_ahead_threshold; if (pafrand() % 2) child.m_feeler_threshold = prog_a.m_feeler_threshold; else child.m_feeler_threshold = prog_b.m_feeler_threshold; if (pafrand() % 2) child.m_feeler_probability = prog_a.m_feeler_probability; else child.m_feeler_probability = prog_b.m_feeler_probability; */ // either one rule priority order or the other (don't try to mix!) if (pafrand() % 2) { for (int i = 0; i < 4; i++) { child.m_rule_order[i] = prog_a.m_rule_order[i]; } } else { for (int i = 0; i < 4; i++) { child.m_rule_order[i] = prog_b.m_rule_order[i]; } } // for each rule, either one rule threshold / probability or the other: for (int i = 0; i < 4; i++) { if (pafrand() % 2) { child.m_rule_threshold[i] = prog_a.m_rule_threshold[i]; } else { child.m_rule_threshold[i] = prog_b.m_rule_threshold[i]; } if (pafrand() % 2) { child.m_rule_probability[i] = prog_a.m_rule_probability[i]; } else { child.m_rule_probability[i] = prog_b.m_rule_probability[i]; } } return child; }