static order *monster_move(region * r, unit * u) { direction_t d = NODIRECTION; if (monster_is_waiting(u)) { return NULL; } switch (old_race(u_race(u))) { case RC_FIREDRAGON: case RC_DRAGON: case RC_WYRM: d = richest_neighbour(r, u->faction, 1); break; case RC_TREEMAN: d = treeman_neighbour(r); break; default: d = random_neighbour(r, u); break; } /* falls kein geld gefunden wird, zufaellig verreisen, aber nicht in * den ozean */ if (d == NODIRECTION) return NULL; reduce_weight(u); return create_order(K_MOVE, u->faction->locale, "%s", LOC(u->faction->locale, directions[d])); }
//_________________________________________________________________________ double graph_molloy_hash::effective_K(int K, int quality) { if(K<3) return 0.0; long sum_K = 0; int *Kbuff = new int[K]; bool *visited = new bool[n]; int i; for(i=0; i<n; i++) visited[i] = false; for(int i=0; i<quality; i++) { // assert(verify()); int f1,f2,t1,t2; int *f1t1, *f2t2; do { // Pick two random vertices do { f1 = pick_random_vertex(); f2 = pick_random_vertex(); } while(f1==f2); // Pick two random neighbours f1t1 = random_neighbour(f1); t1 = *f1t1; f2t2 = random_neighbour(f2); t2 = *f2t2; // test simplicity } while (t1==t2 || f1==t2 || f2==t1 || is_edge(f1,t2) || is_edge(f2,t1)); // swap swap_edges(f1,t2,f2,t1); // assert(verify()); sum_K += effective_isolated(deg[f1]>deg[t2] ? f1 : t2, K, Kbuff, visited); // assert(verify()); sum_K += effective_isolated(deg[f2]>deg[t1] ? f2 : t1, K, Kbuff, visited); // assert(verify()); // undo swap swap_edges(f1,t2,f2,t1); // assert(verify()); } delete[] Kbuff; delete[] visited; return double(sum_K)/double(2*quality); }
particle_swarm_optimisation<T, N>::particle_swarm_optimisation() noexcept : optimiser<T, N>(), initial_velocity(T(0.5)), maximal_acceleration(T(1.0) / (T(2.0) * std::log(T(2.0)))), maximal_local_attraction(T(0.5) + std::log(T(2.0))), maximal_global_attraction(maximal_local_attraction) { this->optimisation_function = [this](const mant::problem<T, N>& problem, std::vector<std::array<T, N>> parameters) { assert(initial_velocity >= T(0.0)); assert(maximal_acceleration >= T(0.0)); assert(maximal_local_attraction >= T(0.0)); assert(maximal_global_attraction >= T(0.0)); auto&& start_time = std::chrono::steady_clock::now(); optimise_result<T, N> result; std::vector<std::array<T, N>> velocities(parameters.size()); for (auto& velocity : velocities) { std::generate( velocity.begin(), std::next(velocity.begin(), this->active_dimensions.size()), std::bind(std::uniform_real_distribution<T>(-initial_velocity, initial_velocity), std::ref(random_number_generator())) ); } std::vector<std::array<T, N>> local_parameters = parameters; std::vector<T> local_objective_values(local_parameters.size()); for (std::size_t n = 0; n < parameters.size(); ++n) { const auto& parameter = parameters.at(n); const auto objective_value = problem.objective_function(parameter); ++result.evaluations; result.duration = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now() - start_time); local_objective_values.at(n) = objective_value; if (objective_value <= result.objective_value) { result.parameter = parameter; result.objective_value = objective_value; if (result.objective_value <= this->acceptable_objective_value) { return result; } } if (result.evaluations >= this->maximal_evaluations) { return result; } else if (result.duration >= this->maximal_duration) { return result; } } while (result.duration < this->maximal_duration && result.evaluations < this->maximal_evaluations && result.objective_value > this->acceptable_objective_value) { const auto n = result.evaluations % parameters.size(); auto& parameter = parameters.at(n); const auto& local_parameter = local_parameters.at(n); std::array<T, N> attraction_center; const auto weigthed_local_attraction = maximal_local_attraction * std::uniform_real_distribution<T>(0, 1)(random_number_generator()); const auto weigthed_global_attraction = maximal_global_attraction * std::uniform_real_distribution<T>(0, 1)(random_number_generator()); for (std::size_t k = 0; k < this->active_dimensions.size(); ++k) { attraction_center.at(k) = ( weigthed_local_attraction * (local_parameter.at(k) - parameter.at(k)) + weigthed_global_attraction * (result.parameter.at(k) - parameter.at(k))) / T(3.0); } const auto&& random_velocity = random_neighbour( attraction_center, T(0.0), std::sqrt(std::inner_product( attraction_center.cbegin(), attraction_center.cend(), attraction_center.cbegin(), T(0.0))), this->active_dimensions.size()); auto& velocity = velocities.at(n); const auto weigthed_acceleration = maximal_acceleration * std::uniform_real_distribution<T>(0, 1)(random_number_generator()); for (std::size_t k = 0; k < this->active_dimensions.size(); ++k) { auto& parameter_element = parameter.at(k); auto& velocity_element = velocity.at(k); velocity_element = weigthed_acceleration * velocity_element + random_velocity.at(k); parameter_element += velocity_element; if (parameter_element < T(0.0)) { parameter_element = T(0.0); velocity_element *= -T(0.5); } else if(parameter_element > T(1.0)) { parameter_element = T(1.0); velocity_element *= -T(0.5); } } const auto objective_value = problem.objective_function(parameter); ++result.evaluations; result.duration = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now() - start_time); if (objective_value < result.objective_value) { result.parameter = parameter; result.objective_value = objective_value; local_parameters.at(n) = parameter; local_objective_values.at(n) = objective_value; } else if (objective_value < local_objective_values.at(n)) { local_parameters.at(n) = parameter; local_objective_values.at(n) = objective_value; } } return result; }; }
//_________________________________________________________________________ bool graph_molloy_hash::isolated(int v, int K, int *Kbuff, bool *visited) { if(K<2) return false; #ifdef OPT_ISOLATED if(K<=deg[v]+1) return false; #endif //OPT_ISOLATED int *seen = Kbuff; int *known = Kbuff; int *max = Kbuff + K; *(known++) = v; visited[v] = true; bool is_isolated = true; while(known != seen) { v = *(seen++); int *ww = neigh[v]; int w; for(int d=HASH_SIZE(deg[v]); d--; ww++) if((w=*ww)!=HASH_NONE && !visited[w]) { #ifdef OPT_ISOLATED if(K<=deg[w]+1 || known == max) { #else //OPT_ISOLATED if(known == max) { #endif //OPT_ISOLATED is_isolated = false; goto end_isolated; } visited[w] = true; *(known++) = w; } } end_isolated: // Undo the changes to visited[]... while(known != Kbuff) visited[*(--known)] = false; return is_isolated; } //_________________________________________________________________________ int graph_molloy_hash::random_edge_swap(int K, int *Kbuff, bool *visited) { // Pick two random vertices a and c int f1 = pick_random_vertex(); int f2 = pick_random_vertex(); // Check that f1 != f2 if(f1==f2) return 0; // Get two random edges (f1,*f1t1) and (f2,*f2t2) int *f1t1 = random_neighbour(f1); int t1 = *f1t1; int *f2t2 = random_neighbour(f2); int t2 = *f2t2; // Check simplicity if(t1==t2 || f1==t2 || f2==t1) return 0; if(is_edge(f1,t2) || is_edge(f2,t1)) return 0; // Swap int *f1t2 = H_rpl(neigh[f1],deg[f1],f1t1,t2); int *f2t1 = H_rpl(neigh[f2],deg[f2],f2t2,t1); int *t1f2 = H_rpl(neigh[t1],deg[t1],f1,f2); int *t2f1 = H_rpl(neigh[t2],deg[t2],f2,f1); // isolation test if(K<=2) return 1; if( !isolated(f1, K, Kbuff, visited) && !isolated(f2, K, Kbuff, visited) ) return 1; // undo swap H_rpl(neigh[f1],deg[f1],f1t2,t1); H_rpl(neigh[f2],deg[f2],f2t1,t2); H_rpl(neigh[t1],deg[t1],t1f2,f1); H_rpl(neigh[t2],deg[t2],t2f1,f2); return 0; }