コード例 #1
0
ファイル: monsters.c プロジェクト: philbooth/server
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]));
}
コード例 #2
0
//_________________________________________________________________________
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);
}
コード例 #3
0
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;
  };
}
コード例 #4
0
//_________________________________________________________________________
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;
}