void do_optimize(static_lattice_swarming_pattern&swp, ind_t&ind, params_t¶ms, RNG_t&rng) { lattice_moves_generator<static_lattice_swarming_pattern::Dimension,RNG_t> mutator(rng); LatticeDisplayFarm<params_t> displayfarm; displayfarm.inheritParametersFrom(params); BoostDotGraphController<static_lattice_swarming_pattern::graph_t, params_t,true> opt_animation; opt_animation.add_vertex_property("color", make_color_temperature(swp.lattice.graph)); opt_animation.add_vertex_property("pos", //make_vertex_id(swp.lattice.graph,80)); // vertex_location_map<static_lattice_swarming_pattern::Dimension, // static_lattice_swarming_pattern::graph_t> // (swp.lattice.graph,80,2)); place_vertex<static_lattice_swarming_pattern::Dimension, static_lattice_swarming_pattern::graph_t> (swp.lattice.graph,80)); // this is silly for an undirected graph // opt_animation.add_edge_property("style", // make_bool_string_property("bold","", // belongs_to_a_2_loop<static_lattice_swarming_pattern::graph_t>, // swp.lattice.graph)); if (swp.n_individuals() < 40) { displayfarm.installController(opt_animation); opt_animation.params.setdisplayToScreen( displayfarm.params.animate_optimization()); //opt_animation.params.setdisplayEvery(50); } //hill_climb(swp,ind,mutator,¶ms,&displayfarm); swp.setannealing_rate_factor(swp.n_individuals()); simulated_annealing(swp,ind,mutator,¶ms,rng,&displayfarm); }
void simulated_annealing(scene & mesh, physics & phys, int kmax, float emax, unsigned int minbasecount, int baserange, StoreBestFunctorT store_best_functor, RunningFunctorT running_functor) { int modifiedHelix, previousBaseCount; physics::transform_type previousTransform; scene::HelixContainer & helices(mesh.getHelices()); const scene::HelixContainer::size_type helixCount(helices.size()); simulated_annealing(mesh, [](scene & mesh) { return mesh.getTotalSeparation(); }, [&helixCount](float k) { return float(std::max(0., (exp(-k) - 1 / M_E) / (1 - 1 / M_E))) * helixCount; }, [&modifiedHelix, &helices, &helixCount, &previousBaseCount, &previousTransform, &phys, &minbasecount, &baserange, &running_functor](scene & mesh) { for (Helix & helix : helices) helix.setTransform(helix.getInitialTransform()); modifiedHelix = rand() % helixCount; Helix & helix(helices[modifiedHelix]); previousBaseCount = helix.getBaseCount(); previousTransform = helix.getTransform(); helix.recreateRigidBody( phys, std::max(minbasecount, helix.getInitialBaseCount() + (rand() % 2 * 2 - 1) * (1 + rand() % (baserange))), helix.getInitialTransform()); while (!mesh.isSleeping() && running_functor()) { phys.scene->simulate(1.0f / 60.0f); phys.scene->fetchResults(true); } }, probability_functor<float, float>(), [&modifiedHelix, &helices, &previousBaseCount, &previousTransform, &phys](scene & mesh) { Helix & helix(helices[modifiedHelix]); helix.recreateRigidBody(phys, previousBaseCount, helix.getInitialTransform()); }, store_best_functor, running_functor, kmax, emax); }
int main(int argc, char *argv[]) { int c; sat_t *sat; uint32_t sa_repeat = 100; uint32_t sa_best = 0; uint32_t sa_sum = 0; bool run_bruteforce = 0; bool sa_run = true; srand(time(0)); while ((c = getopt(argc, argv, "bc:l:r:sSP")) != -1) { switch (c) { case 'b': run_bruteforce = true; break; case 'c': switch (atoi(optarg)) { case 1: cost = &cost1; break; case 2: cost = &cost2; break; case 3: cost = &cost3; break; default: assert(0); break; } break; case 'l': g_limit = atoi(optarg); break; case 'r': sa_repeat = (uint32_t) atoi(optarg); break; case 's': g_just_solved = true; break; case 'S': sa_run = false; break; case 'P': g_print_progress = true; break; case '?': fprintf(stderr, "unknown opt\n"); return (EXIT_FAILURE); break; default: abort(); break; } } sat = sat_load(); //sat_print(sat); // sat_simulated_evolution(sat, 100); if (run_bruteforce) { sat_bruteforce(sat); } if (sa_run) { assert(cost != NULL); double sa_time = omp_get_wtime(); for (uint32_t i = 0; i < sa_repeat; i++) { uint32_t res = simulated_annealing(sat, 0.01, 10000); // fprintf(stderr, "[%u]", i); // fflush(stdout); sa_sum += res; if (sa_best < res) { sa_best = res; } } sa_time = (omp_get_wtime() - sa_time) / (double) sa_repeat; // fprintf(stderr, "\n"); if (g_just_solved) { if (sa_best > 0) { fprintf(stderr, "1"); } else { fprintf(stderr, "0"); } } else { fprintf(stderr, "saavg= %u sabest= %u satime= %lf \n", (uint32_t) ((double) sa_sum / (double) sa_repeat), sa_best, sa_time); } } sat_free(sat); return (EXIT_SUCCESS); }
int main(int argc, const char **argv) { seed(); physics::settings_type physics_settings; scene::settings_type scene_settings; Helix::settings_type helix_settings; std::string input_file, output_file; parse_settings::parse(argc, argv, physics_settings, scene_settings, helix_settings, input_file, output_file); if (input_file.empty() || output_file.empty() || argc < 3) { std::cerr << parse_settings::usage(argv[0]) << std::endl; return 0; } scene mesh(scene_settings, helix_settings); physics phys(physics_settings); try { if (!mesh.read(phys, input_file)) { std::cerr << "Failed to read scene \"" << input_file << "\"" << std::endl; return 1; } } catch (const std::runtime_error & e) { std::cerr << "Failed to read scene \"" << input_file << "\": " << e.what() << std::endl; return 1; } physics::real_type initialmin, initialmax, initialaverage, initialtotal, min, max, average, total; mesh.getTotalSeparationMinMaxAverage(initialmin, initialmax, initialaverage, initialtotal); std::cerr << "Running simulation for scene loaded from \"" << input_file << " outputting to " << output_file << "\"." << std::endl << "Initial: min: " << initialmin << ", max: " << initialmax << ", average: " << initialaverage << ", total: " << initialtotal << " nm" << std::endl << "Connect with NVIDIA PhysX Visual Debugger to " << PVD_HOST << ':' << PVD_PORT << " to visualize the progress. " << std::endl << "Press ^C to stop the relaxation...." << std::endl; setinterrupthandler<handle_exit>(); SceneDescription best_scene; Helix helix1 = Helix(helix_settings, phys, 20, physics::transform_type(physics::vec3_type(1,20,1))); Helix helix2 = Helix(helix_settings, phys, 20, physics::transform_type(physics::vec3_type(1, 20, 8))); helix1.attach(phys, helix2, Helix::AttachmentPoint::kBackwardFivePrime, Helix::AttachmentPoint::kBackwardThreePrime); #if 0 best_scene = simulated_rectification(mesh, phys, []() { return running; }); #else #if 0 simulated_annealing(mesh, phys, 100, 0, 7, 1, [&best_scene](scene & mesh, float e) { std::cerr << "Store best energy: " << e << std::endl; best_scene = SceneDescription(mesh); }, []() { return running; }); #else gradient_descent(mesh, phys, 7, [&best_scene, &min, &max, &average, &total](scene & mesh, physics::real_type min_, physics::real_type max_, physics::real_type average_, physics::real_type total_) { min = min_; max = max_; average = average_; total = total_; std::cerr << "State: min: " << min << ", max: " << max << ", average: " << average << " total: " << total << " nm" << std::endl; best_scene = SceneDescription(mesh); }, []() { return running; }); #endif #endif std::cerr << "Result: min: " << min << ", max: " << max << ", average: " << average << ", total: " << total << " nm" << std::endl; { std::ofstream outfile(output_file); outfile << "# Relaxation of original " << input_file << " file. " << mesh.getHelixCount() << " helices." << std::endl << "# Total separation: Initial: min: " << initialmin << ", max: " << initialmax << ", average: " << initialaverage << ", total: " << initialtotal << " nm" << ", final: min: " << min << ", max: " << max << ", average: " << average << ", total: " << total << " nm" << std::endl; if (!best_scene.write(outfile)) std::cerr << "Failed to write resulting mesh to \"" << output_file << "\"" << std::endl; outfile.close(); } sleepms(2000); return 0; }