void G1MarkSweep::mark_sweep_phase2() { // Now all live objects are marked, compute the new object addresses. // It is imperative that we traverse perm_gen LAST. If dead space is // allowed a range of dead object may get overwritten by a dead int // array. If perm_gen is not traversed last a klassOop may get // overwritten. This is fine since it is dead, but if the class has dead // instances we have to skip them, and in order to find their size we // need the klassOop! // // It is not required that we traverse spaces in the same order in // phase2, phase3 and phase4, but the ValidateMarkSweep live oops // tracking expects us to do so. See comment under phase4. G1CollectedHeap* g1h = G1CollectedHeap::heap(); Generation* pg = g1h->perm_gen(); EventMark m("2 compute new addresses"); TraceTime tm("phase 2", PrintGC && Verbose, true, gclog_or_tty); GenMarkSweep::trace("2"); FindFirstRegionClosure cl; g1h->heap_region_iterate(&cl); HeapRegion *r = cl.result(); CompactibleSpace* sp = r; if (r->isHumongous() && oop(r->bottom())->is_gc_marked()) { sp = r->next_compaction_space(); } G1PrepareCompactClosure blk(sp); g1h->heap_region_iterate(&blk); CompactPoint perm_cp(pg, NULL, NULL); pg->prepare_for_compaction(&perm_cp); }
void G1MarkSweep::mark_sweep_phase3() { G1CollectedHeap* g1h = G1CollectedHeap::heap(); Generation* pg = g1h->perm_gen(); // Adjust the pointers to reflect the new locations EventMark m("3 adjust pointers"); TraceTime tm("phase 3", PrintGC && Verbose, true, gclog_or_tty); GenMarkSweep::trace("3"); SharedHeap* sh = SharedHeap::heap(); sh->process_strong_roots(true, // activate StrongRootsScope true, // Collecting permanent generation. SharedHeap::SO_AllClasses, &GenMarkSweep::adjust_root_pointer_closure, NULL, // do not touch code cache here &GenMarkSweep::adjust_pointer_closure); g1h->ref_processor()->weak_oops_do(&GenMarkSweep::adjust_root_pointer_closure); // Now adjust pointers in remaining weak roots. (All of which should // have been cleared if they pointed to non-surviving objects.) g1h->g1_process_weak_roots(&GenMarkSweep::adjust_root_pointer_closure, &GenMarkSweep::adjust_pointer_closure); GenMarkSweep::adjust_marks(); G1AdjustPointersClosure blk; g1h->heap_region_iterate(&blk); pg->adjust_pointers(); }
void G1MarkSweep::mark_sweep_phase4() { // All pointers are now adjusted, move objects accordingly // It is imperative that we traverse perm_gen first in phase4. All // classes must be allocated earlier than their instances, and traversing // perm_gen first makes sure that all klassOops have moved to their new // location before any instance does a dispatch through it's klass! // The ValidateMarkSweep live oops tracking expects us to traverse spaces // in the same order in phase2, phase3 and phase4. We don't quite do that // here (perm_gen first rather than last), so we tell the validate code // to use a higher index (saved from phase2) when verifying perm_gen. G1CollectedHeap* g1h = G1CollectedHeap::heap(); Generation* pg = g1h->perm_gen(); EventMark m("4 compact heap"); TraceTime tm("phase 4", PrintGC && Verbose, true, gclog_or_tty); GenMarkSweep::trace("4"); pg->compact(); G1SpaceCompactClosure blk; g1h->heap_region_iterate(&blk); }
void CardTableRS::clear_into_younger(Generation* gen, bool clear_perm) { GenCollectedHeap* gch = GenCollectedHeap::heap(); // Generations younger than gen have been evacuated. We can clear // card table entries for gen (we know that it has no pointers // to younger gens) and for those below. The card tables for // the youngest gen need never be cleared, and those for perm gen // will be cleared based on the parameter clear_perm. // There's a bit of subtlety in the clear() and invalidate() // methods that we exploit here and in invalidate_or_clear() // below to avoid missing cards at the fringes. If clear() or // invalidate() are changed in the future, this code should // be revisited. 20040107.ysr Generation* g = gen; for(Generation* prev_gen = gch->prev_gen(g); prev_gen != NULL; g = prev_gen, prev_gen = gch->prev_gen(g)) { MemRegion to_be_cleared_mr = g->prev_used_region(); clear(to_be_cleared_mr); } // Clear perm gen cards if asked to do so. if (clear_perm) { MemRegion to_be_cleared_mr = gch->perm_gen()->prev_used_region(); clear(to_be_cleared_mr); } }
void CardTableRS::invalidate_or_clear(Generation* gen, bool younger, bool perm) { GenCollectedHeap* gch = GenCollectedHeap::heap(); // For each generation gen (and younger and/or perm) // invalidate the cards for the currently occupied part // of that generation and clear the cards for the // unoccupied part of the generation (if any, making use // of that generation's prev_used_region to determine that // region). No need to do anything for the youngest // generation. Also see note#20040107.ysr above. Generation* g = gen; for(Generation* prev_gen = gch->prev_gen(g); prev_gen != NULL; g = prev_gen, prev_gen = gch->prev_gen(g)) { MemRegion used_mr = g->used_region(); MemRegion to_be_cleared_mr = g->prev_used_region().minus(used_mr); if (!to_be_cleared_mr.is_empty()) { clear(to_be_cleared_mr); } invalidate(used_mr); if (!younger) break; } // Clear perm gen cards if asked to do so. if (perm) { g = gch->perm_gen(); MemRegion used_mr = g->used_region(); MemRegion to_be_cleared_mr = g->prev_used_region().minus(used_mr); if (!to_be_cleared_mr.is_empty()) { clear(to_be_cleared_mr); } invalidate(used_mr); } }
Generation random_generation(int size, int code_length) { Generation gen; while (size--) //Add a newprogram gen.push_back(random_chromosome(code_length)); return gen; }
void CardTableRS::clear_into_gen_and_younger(Generation* gen) { GenCollectedHeap* gch = GenCollectedHeap::heap(); // Gen and all younger have been evacuated. We can clear // remembered set entries for the next highest generation // (we know that it has no pointers to younger gens) and // those below. Generation* g = gch->next_gen(gen); while (g != NULL) { clear(g->reserved()); g = gch->prev_gen(gen); } }
HeapWord* GenCollectorPolicy::expand_heap_and_allocate(size_t size, bool is_tlab) { GenCollectedHeap *gch = GenCollectedHeap::heap(); HeapWord* result = NULL; for (int i = number_of_generations() - 1; i >= 0 && result == NULL; i--) { Generation *gen = gch->get_gen(i); if (gen->should_allocate(size, is_tlab)) { result = gen->expand_and_allocate(size, is_tlab); } } assert(result == NULL || gch->is_in_reserved(result), "result not in heap"); return result; }
genetic::Cell genetic::gaoptimize() { //srand(seed); Generation ancestor; for(int g = 0; g < gainput.max_generation; ++g) { Generation nextgen; nextgen.Generate(ancestor); ancestor = nextgen; } return ancestor.Min(); }
status_t DynamicThreadVector::_ResizeVector(unsigned minimumSize) { static const unsigned kInitialSize = 4; unsigned size = std::max(minimumSize, kInitialSize); unsigned oldSize = _Size(); if (size <= oldSize) return B_OK; void* newVector = realloc(*fVector, (size + 1) * sizeof(TLSBlock)); if (newVector == NULL) return B_NO_MEMORY; *fVector = (TLSBlock*)newVector; memset(*fVector + oldSize + 1, 0, (size - oldSize) * sizeof(TLSBlock)); if (fGeneration == NULL) { fGeneration = new Generation; if (fGeneration == NULL) return B_NO_MEMORY; } *(Generation**)*fVector = fGeneration; fGeneration->SetSize(size); return B_OK; }
unsigned DynamicThreadVector::_Generation() const { if (fGeneration != NULL) return fGeneration->Counter(); return unsigned(-1); }
TLSBlock& DynamicThreadVector::operator[](unsigned dso) { unsigned generation = TLSBlockTemplates::Get().GetGeneration(-1); if (_Generation() < generation) { for (unsigned i = 0; i < _Size(); i++) { TLSBlock& block = (*fVector)[i + 1]; unsigned dsoGeneration = TLSBlockTemplates::Get().GetGeneration(dso); if (_Generation() < dsoGeneration && dsoGeneration <= generation) block.Destroy(); } fGeneration->SetCounter(generation); } if (_Size() <= dso) { status_t result = _ResizeVector(dso + 1); if (result != B_OK) return fNullBlock; } TLSBlock& block = (*fVector)[dso + 1]; if (block.IsInvalid()) { status_t result = block.Initialize(dso); if (result != B_OK) return fNullBlock; }; return block; }
ScoredGeneration score_generation(const Generation &generation, std::function<unsigned int(Code)> fitness_fct) { ScoredGeneration scored_generation; for (int i = 0; i < generation.size(); i++) { auto fitness = fitness_fct(generation[i]); scored_generation.push_back(std::make_pair(fitness, generation[i])); } return scored_generation; }
void CardTableRS::verify() { // At present, we only know how to verify the card table RS for // generational heaps. VerifyCTGenClosure blk(this); CollectedHeap* ch = Universe::heap(); // We will do the perm-gen portion of the card table, too. Generation* pg = SharedHeap::heap()->perm_gen(); HeapWord* pg_boundary = pg->reserved().start(); if (ch->kind() == CollectedHeap::GenCollectedHeap) { GenCollectedHeap::heap()->generation_iterate(&blk, false); _ct_bs->verify(); // If the old gen collections also collect perm, then we are only // interested in perm-to-young pointers, not perm-to-old pointers. GenCollectedHeap* gch = GenCollectedHeap::heap(); CollectorPolicy* cp = gch->collector_policy(); if (cp->is_mark_sweep_policy() || cp->is_concurrent_mark_sweep_policy()) { pg_boundary = gch->get_gen(1)->reserved().start(); } } VerifyCTSpaceClosure perm_space_blk(this, pg_boundary); SharedHeap::heap()->perm_gen()->space_iterate(&perm_space_blk, true); }
HeapWord* GenCollectorPolicy::expand_heap_and_allocate(size_t size, bool is_tlab) { GenCollectedHeap *gch = GenCollectedHeap::heap(); HeapWord* result = NULL; Generation *old = gch->old_gen(); if (old->should_allocate(size, is_tlab)) { result = old->expand_and_allocate(size, is_tlab); } if (result == NULL) { Generation *young = gch->young_gen(); if (young->should_allocate(size, is_tlab)) { result = young->expand_and_allocate(size, is_tlab); } } assert(result == NULL || gch->is_in_reserved(result), "result not in heap"); return result; }
virtual void object_iterate(ObjectClosure* cl) { Generation* g = as_gen(); assert(g != NULL, "as_gen() NULL"); g->object_iterate(cl); }
// Performance Counter support virtual void update_counters() { Generation* g = as_gen(); assert(g != NULL, "as_gen() NULL"); g->update_counters(); }
HeapWord* GenCollectorPolicy::mem_allocate_work(size_t size, bool is_tlab, bool* gc_overhead_limit_was_exceeded) { GenCollectedHeap *gch = GenCollectedHeap::heap(); debug_only(gch->check_for_valid_allocation_state()); assert(gch->no_gc_in_progress(), "Allocation during gc not allowed"); // In general gc_overhead_limit_was_exceeded should be false so // set it so here and reset it to true only if the gc time // limit is being exceeded as checked below. *gc_overhead_limit_was_exceeded = false; HeapWord* result = NULL; // Loop until the allocation is satisfied, or unsatisfied after GC. for (uint try_count = 1, gclocker_stalled_count = 0; /* return or throw */; try_count += 1) { HandleMark hm; // Discard any handles allocated in each iteration. // First allocation attempt is lock-free. Generation *young = gch->young_gen(); assert(young->supports_inline_contig_alloc(), "Otherwise, must do alloc within heap lock"); if (young->should_allocate(size, is_tlab)) { result = young->par_allocate(size, is_tlab); if (result != NULL) { assert(gch->is_in_reserved(result), "result not in heap"); return result; } } uint gc_count_before; // Read inside the Heap_lock locked region. { MutexLocker ml(Heap_lock); log_trace(gc, alloc)("GenCollectorPolicy::mem_allocate_work: attempting locked slow path allocation"); // Note that only large objects get a shot at being // allocated in later generations. bool first_only = ! should_try_older_generation_allocation(size); result = gch->attempt_allocation(size, is_tlab, first_only); if (result != NULL) { assert(gch->is_in_reserved(result), "result not in heap"); return result; } if (GCLocker::is_active_and_needs_gc()) { if (is_tlab) { return NULL; // Caller will retry allocating individual object. } if (!gch->is_maximal_no_gc()) { // Try and expand heap to satisfy request. result = expand_heap_and_allocate(size, is_tlab); // Result could be null if we are out of space. if (result != NULL) { return result; } } if (gclocker_stalled_count > GCLockerRetryAllocationCount) { return NULL; // We didn't get to do a GC and we didn't get any memory. } // If this thread is not in a jni critical section, we stall // the requestor until the critical section has cleared and // GC allowed. When the critical section clears, a GC is // initiated by the last thread exiting the critical section; so // we retry the allocation sequence from the beginning of the loop, // rather than causing more, now probably unnecessary, GC attempts. JavaThread* jthr = JavaThread::current(); if (!jthr->in_critical()) { MutexUnlocker mul(Heap_lock); // Wait for JNI critical section to be exited GCLocker::stall_until_clear(); gclocker_stalled_count += 1; continue; } else { if (CheckJNICalls) { fatal("Possible deadlock due to allocating while" " in jni critical section"); } return NULL; } } // Read the gc count while the heap lock is held. gc_count_before = gch->total_collections(); } VM_GenCollectForAllocation op(size, is_tlab, gc_count_before); VMThread::execute(&op); if (op.prologue_succeeded()) { result = op.result(); if (op.gc_locked()) { assert(result == NULL, "must be NULL if gc_locked() is true"); continue; // Retry and/or stall as necessary. } // Allocation has failed and a collection // has been done. If the gc time limit was exceeded the // this time, return NULL so that an out-of-memory // will be thrown. Clear gc_overhead_limit_exceeded // so that the overhead exceeded does not persist. const bool limit_exceeded = size_policy()->gc_overhead_limit_exceeded(); const bool softrefs_clear = all_soft_refs_clear(); if (limit_exceeded && softrefs_clear) { *gc_overhead_limit_was_exceeded = true; size_policy()->set_gc_overhead_limit_exceeded(false); if (op.result() != NULL) { CollectedHeap::fill_with_object(op.result(), size); } return NULL; } assert(result == NULL || gch->is_in_reserved(result), "result not in heap"); return result; } // Give a warning if we seem to be looping forever. if ((QueuedAllocationWarningCount > 0) && (try_count % QueuedAllocationWarningCount == 0)) { log_warning(gc, ergo)("GenCollectorPolicy::mem_allocate_work retries %d times," " size=" SIZE_FORMAT " %s", try_count, size, is_tlab ? "(TLAB)" : ""); } } }
HeapWord* TwoGenerationCollectorPolicy::satisfy_failed_allocation(size_t size, bool is_large_noref, bool is_tlab, bool* notify_ref_lock) { GenCollectedHeap *gch = GenCollectedHeap::heap(); GCCauseSetter x(gch, GCCause::_allocation_failure); HeapWord* result = NULL; // The gc_prologues have not executed yet. The value // for incremental_collection_will_fail() is the remanent // of the last collection. if (!gch->incremental_collection_will_fail()) { // Do an incremental collection. gch->do_collection(false /* full */, false /* clear_all_soft_refs */, size /* size */, is_large_noref /* is_large_noref */, is_tlab /* is_tlab */, number_of_generations() - 1 /* max_level */, notify_ref_lock /* notify_ref_lock */); } else { // The incremental_collection_will_fail flag is set if the // next incremental collection will not succeed (e.g., the // DefNewGeneration didn't think it had space to promote all // its objects). However, that last incremental collection // continued, allowing all older generations to collect (and // perhaps change the state of the flag). // // If we reach here, we know that an incremental collection of // all generations left us in the state where incremental collections // will fail, so we just try allocating the requested space. // If the allocation fails everywhere, force a full collection. // We're probably very close to being out of memory, so forcing many // collections now probably won't help. if (PrintGC && Verbose) { gclog_or_tty->print_cr("TwoGenerationCollectorPolicy::satisfy_failed_allocation:" " attempting allocation anywhere before full collection"); } result = gch->attempt_allocation(size, is_large_noref, is_tlab, false /* first_only */); if (result != NULL) { assert(gch->is_in(result), "result not in heap"); return result; } // Allocation request hasn't yet been met; try a full collection. gch->do_collection(true /* full */, false /* clear_all_soft_refs */, size /* size */, is_large_noref /* is_large_noref */, is_tlab /* is_tlab */, number_of_generations() - 1 /* max_level */, notify_ref_lock /* notify_ref_lock */); } result = gch->attempt_allocation(size, is_large_noref, is_tlab, false /*first_only*/); if (result != NULL) { assert(gch->is_in(result), "result not in heap"); return result; } // OK, collection failed, try expansion. for (int i = number_of_generations() - 1 ; i>= 0; i--) { Generation *gen = gch->get_gen(i); if (gen->should_allocate(size, is_large_noref, is_tlab)) { result = gen->expand_and_allocate(size, is_large_noref, is_tlab); if (result != NULL) { assert(gch->is_in(result), "result not in heap"); return result; } } } // If we reach this point, we're really out of memory. Try every trick // we can to reclaim memory. Force collection of soft references. Force // a complete compaction of the heap. Any additional methods for finding // free memory should be here, especially if they are expensive. If this // attempt fails, an OOM exception will be thrown. { IntFlagSetting flag_change(MarkSweepAlwaysCompactCount, 1); // Make sure the heap is fully compacted gch->do_collection(true /* full */, true /* clear_all_soft_refs */, size /* size */, is_large_noref /* is_large_noref */, is_tlab /* is_tlab */, number_of_generations() - 1 /* max_level */, notify_ref_lock /* notify_ref_lock */); } result = gch->attempt_allocation(size, is_large_noref, is_tlab, false /* first_only */); if (result != NULL) { assert(gch->is_in(result), "result not in heap"); return result; } // What else? We might try synchronous finalization later. If the total // space available is large enough for the allocation, then a more // complete compaction phase than we've tried so far might be // appropriate. return NULL; }
Generation::Generation(Generation ancestors, bool debug) { for (int s = 0; s < GENERATION_SIZE; s++) { this->solutions[s] = Solution(ancestors.solutions[s], ancestors.getSolution()); } }
void GeneticAlgorithm::run_optimization(std::vector<exp_signal> const& signals_exp, Spin const& spinA, Spin const& spinB, std::vector<int> const& param_numbers, std::vector<int> const& param_modes, std::vector<bound> const& param_bounds, genetic_parameters const& genetic_param, output_parameters const& output_param) const { // Initialize the calculator of PELDOR signals PeldorCalculator* peldor_calc = new PeldorCalculator(genetic_param.num_avg); peldor_calc->calculate_spinA_excitation(signals_exp, spinA); // Calculate the spectrum of the spin system if (output_param.record_spectrum) { std::cout << " Recording the spectrum... "; peldor_calc->save_spectrum(signals_exp, spinA, spinB, output_param); std::cout << "Done!" << std::endl; } // Start optimization int n = 1; std::cout << " Optimization step " << n << "/" << genetic_param.num_generations_max << std::endl; // Create a first generation Generation* generation = new Generation(genetic_param); generation->create_initial_generation(param_bounds, genetic_param); // Score first generation generation->score_chromosomes(*peldor_calc, signals_exp, spinA, spinB, param_numbers, param_modes, genetic_param); generation->sort_chromosomes(); std::vector<double> best_fitness; best_fitness.reserve(genetic_param.num_generations_max); best_fitness.push_back(generation->chromosomes[0].fitness); // Proceed with next generations for (int n = 2; n <= genetic_param.num_generations_max; ++n) { // loop over generations std::cout << " Optimization step " << n << "/" << genetic_param.num_generations_max << std::endl; // Create next generation generation->produce_offspring(genetic_param, param_bounds); // Score the generation generation->score_chromosomes(*peldor_calc, signals_exp, spinA, spinB, param_numbers, param_modes, genetic_param); generation->sort_chromosomes(); best_fitness.push_back(generation->chromosomes[0].fitness); } // Save the fitness of the best chromosome if (output_param.record_score) { std::cout << " Recording the fitness vs the number of optimization steps... "; record_score(best_fitness, genetic_param, output_param); std::cout << "Done!" << std::endl; } // Save the calculated fit to the PELDOR signals for the best chromosome if (output_param.record_fit) { std::cout << " Recording the fit to the PELDOR signals... "; record_fit(*peldor_calc, generation->chromosomes[0], signals_exp, spinA, spinB, param_numbers, param_modes, output_param); std::cout << "Done!" << std::endl; } // Save the genes of the best chromosome if (output_param.record_parameters) { std::cout << " Recording the best values of fitting parameters... "; record_parameters(generation->chromosomes[0], param_numbers, param_modes, output_param); std::cout << "Done!" << std::endl; } // Record the calculated for-factors for the PELDOR signals if (output_param.record_form_factor) { std::cout << " Recording the form-factors of PELDOR signals... "; record_form_factor(*peldor_calc, generation->chromosomes[0], signals_exp, spinA, spinB, param_numbers, param_modes, output_param); std::cout << "Done!" << std::endl; } // Record the symmetry-related sets of fitting parameters if (output_param.record_symmetric_solutions) { std::cout << " Recording the symmetry-related sets of fitting parameters... "; record_symmetric_parameters(*peldor_calc, generation->chromosomes[0], signals_exp, spinA, spinB, param_numbers, param_modes, param_bounds, genetic_param, output_param); std::cout << "Done!" << std::endl; } // Record the error plots if (output_param.record_error_plot) { std::cout << " Recording the error plot... "; record_error_plot(*peldor_calc, generation->chromosomes[0], signals_exp, spinA, spinB, param_numbers, param_modes, param_bounds, genetic_param, output_param); std::cout << "Done!" << std::endl; } // Clean up delete peldor_calc; delete generation; }
size_t used_in_bytes() { return _gen->used(); }
virtual void oop_iterate(OopClosure* cl) { Generation* g = as_gen(); assert(g != NULL, "as_gen() NULL"); g->oop_iterate(cl); }
int main(int argc, char* argv[]) { if (argc < 5) { std::cout << argv[0] << " <numberOfGenerations> <sizeOfPopulation> <numberOfAtoms> <percentageMutation>" << std::endl; return EXIT_FAILURE; } std::fstream out; out.open("../results/ga-out", std::ios::out); assert(out.is_open()); int maxDistance = 1000; int numberOfGenerations = std::stoi(argv[1]); int sizeOfPopulation = std::stoi(argv[2]); int numberOfAtoms = std::stoi(argv[3]); int percentage = std::stoi(argv[4]); Randomize* randomize = new Randomize(); Evolution* evolution = new Evolution(); out << "genetico" << std::endl; out << numberOfAtoms << std::endl; // generate random generation Generation* pGen = randomize->randomGeneration(maxDistance, sizeOfPopulation, numberOfAtoms); Molecule** pMol = pGen->molecules(); // calculate potential for (int i = 0; i < sizeOfPopulation; i++) { Molecule* m = pMol[i]; m->setPotential(evolution->lennardJones(m)); } // ordering molecules QuickSort<Molecule>::sort(pMol, 0, sizeOfPopulation - 1); Atom** pAtom = pMol[0]->atoms(); for (int i = 0; i < pMol[0]->numberOfAtoms(); i++) { out << "Au" << "\t" << pAtom[i]->_x << "\t" << pAtom[i]->_y << "\t" << pAtom[i]->_z << std::endl; } // calculates next generations Molecule* idv1 = NULL; Molecule* idv2 = NULL; Generation* nGen = NULL; Molecule** nMol = NULL; int generationID = 1; while (numberOfGenerations > 0) { // create new generation nGen = new Generation(generationID); for (int i = 0; i < sizeOfPopulation; i++) { // select individuals idv1 = pMol[randomize->randomInt(sizeOfPopulation)]; idv2 = pMol[randomize->randomInt(sizeOfPopulation)]; // create new individual nGen->addMolecule(*evolution->reprodution(idv1, idv2, maxDistance, percentage)); } delete pGen; pGen = nGen; pMol = pGen->molecules(); // calculate potential for (int i = 0; i < sizeOfPopulation; i++) { Molecule* m = pMol[i]; m->setPotential(evolution->lennardJones(m)); } // ordering molecules QuickSort<Molecule>::sort(pMol, 0, sizeOfPopulation - 1); pAtom = pMol[0]->atoms(); for (int j = 0; j < pMol[0]->numberOfAtoms(); j++) { out << "Au" << "\t" << pAtom[j]->_x << "\t" << pAtom[j]->_y << "\t" << pAtom[j]->_z << std::endl; } // increment generationID++; numberOfGenerations--; } out.close(); delete pGen; // delete nGen; delete randomize; delete evolution; return EXIT_SUCCESS; }
int main(int argc, char *argv[]) { Generation moms; Generation dads; Generation x; Individual *mom; Individual *dad; Individual *child; UniformRNG r(0.0,1.0); int i; init(); // Create 10 males and 10 females, and give them each 2 mutations. // Then create a child and put it in generation x: for (i=0; i<gsize; i++) { dad = new Individual; dad->set_sex(MALE); dad->genes->add_mutations(2); cout << dad->get_id() << ": " << *dad; dads.insert(dad); mom = new Individual; mom->set_sex(FEMALE); mom->genes->add_mutations(2); moms.insert(mom); cout << mom->get_id() << ": " << *mom; child = new Individual; child->set_sex((++r < 0.5) ? MALE : FEMALE); child->genes->combine(dad->genes,mom->genes); x.insert(child); cout << child->get_id() << ": " << *child; cout << endl; } // Test the remove function and error detection in the Generation class. // Print the first three, remove the second, and print again: cout << "First three individuals in x: \n "; for (i=0; i<3; i++) cout << x[i]->get_id() << " "; cout << endl; child = x.remove(1); cout << "individual removed: " << child->get_id() << endl; cout << "First three individuals remaining in x: \n "; for (i=0; i<3; i++) cout << x[i]->get_id() << " "; cout << endl << endl; // Same test, but now remove the first one (special case): cout << "First three individuals in x: \n "; for (i=0; i<3; i++) cout << x[i]->get_id() << " "; cout << endl; child = x.remove(0); cout << "individual removed: " << child->get_id() << endl; cout << "First three individuals remaining in x: \n "; for (i=0; i<3; i++) cout << x[i]->get_id() << " "; cout << endl << endl; // There are now gsize-2 individuals in x. Whittle it down to 2: for (i = 0; i < gsize-4; i++) child = x.remove(0); // Print the remaining two individuals: cout << "last two individuals in x: " << x[0]->get_id() << " and " << x[1]->get_id() << endl; // These should cause an error message: child = x[2]; child = x.remove(2); // Test removing the last item: child = x.remove(1); cout << child->get_id() << endl; child = x.remove(0); cout << child->get_id() << endl; // Gen X should now be empty: cout << "Gen X size = " << x.size() << endl; }