void Map::generate(const unsigned int city_count,
		const unsigned int width,
		const unsigned int height,
		const unsigned int seed)
{
	cities.resize(city_count);
	std::default_random_engine generator(seed);
	std::uniform_int_distribution<unsigned int> width_distribution(0, width);
	std::uniform_int_distribution<unsigned int> height_distribution(0, height);
	std::uniform_int_distribution<unsigned int> city_distribution(0, city_count - 1);

	for (size_t c = 0; c < city_count; c++)
	{
		cities[c].x = width_distribution(generator);
		cities[c].y = height_distribution(generator);
	}

	start = city_distribution(generator);
	end = city_distribution(generator);
	m_adaptor = MapAdaptor(cities);

	city_tree_t city_tree(2, m_adaptor,
			nanoflann::KDTreeSingleIndexAdaptorParams(10));
	city_tree.buildIndex();

	for (size_t c = 0; c < cities.size(); c++)
	{
		// Set index of city and generate connections
		cities[c].index = c; // Do we need this?
		// Consider 5 closest
		std::vector<size_t> ret_index(CITY_SEARCH + 1);
		std::vector<unsigned int>dist_sqr(CITY_SEARCH + 1);

		city_tree.knnSearch(
				&cities[c].x,
				CITY_SEARCH + 1,
				&ret_index[0],
				&dist_sqr[0]);
		for (size_t i = 1; i < ret_index.size(); i++)
		{
			// Do we include you or not?
			// Bernoulli, do your job buddy!
			std::bernoulli_distribution city_test_distribution(CITY_RATIO);
			if (city_test_distribution(generator))
			{
				// Update our information
				cities[c].neighbors.insert(
						std::make_pair(ret_index[i],
							std::sqrt(dist_sqr[i])));
				cities[ret_index[i]].neighbors.insert(
						std::make_pair(c,
							std::sqrt(dist_sqr[i])));
			}
		}
	}
}
Example #2
0
void testNanoFLANN(CMesh& mesh, std::vector<unsigned int>& test_indeces, std::vector<vcg::Point3f> randomSamples)
{
    std::cout << "==================================================="<< std::endl;
    std::cout << "nanoFLANN" << std::endl;

    PointCloud<float> cloud;
    cloud.pts.resize(mesh.vert.size());
    for (size_t i=0; i < mesh.vert.size(); i++)
    {
        cloud.pts[i].x = mesh.vert[i].P().X();
        cloud.pts[i].y = mesh.vert[i].P().Y();
        cloud.pts[i].z = mesh.vert[i].P().Z();
    }

    typedef nanoflann::KDTreeSingleIndexAdaptor<
        nanoflann::L2_Simple_Adaptor<float, PointCloud<float> > ,
        PointCloud<float>,
        3 /* dim */
        > my_kd_tree_t;

    // Construction of the nanoFLANN KDtree
    QTime time;
    time.start();
    my_kd_tree_t   index(3, cloud, nanoflann::KDTreeSingleIndexAdaptorParams(16) );
    index.buildIndex();
    std::cout << "Build nanoFlann: " << time.elapsed() <<  " ms" << std::endl;

    // Test with the radius search
    std::cout << "Radius search (" << num_test << " tests)"<< std::endl;
    float avgTime = 0.0f;
    std::vector<std::pair<size_t,float> >   ret_matches;
    nanoflann::SearchParams params;
    for (int ii = 0; ii < num_test; ii++)
    {
        time.restart();
        const size_t nMatches = index.radiusSearch(mesh.vert[test_indeces[ii]].P().V(), queryDist, ret_matches, params);
        avgTime += time.elapsed();
    }
    std::cout << "Time (radius = " << queryDist << "): " << avgTime << " ms (mean " << avgTime / num_test << "ms)"  << std::endl;

    // Test with the k-nearest search
    std::cout << "k-Nearest search (" << num_test*10 << " tests)"<< std::endl;
    avgTime = 0.0f;
    std::vector<size_t>   ret_index(kNearest);
    std::vector<float> out_dist_sqr(kNearest);
    for (int ii = 0; ii < num_test * 10; ii++)
    {
        time.restart();
        index.knnSearch(mesh.vert[test_indeces[ii]].P().V(), kNearest, &ret_index[0], &out_dist_sqr[0]);
        avgTime += time.elapsed();
    }
    std::cout << "Time (k = " << kNearest << "): " << avgTime << " ms (mean " << avgTime / (num_test * 10) << "ms)"  << std::endl;

    // Test with the closest search
    std::cout << "Closest search (" << num_test*10 << " tests)"<< std::endl;
    avgTime = 0.0f;
    std::vector<size_t>   ret_index_clos(1);
    std::vector<float> out_dist_sqr_clos(1);
    for (int ii = 0; ii < num_test * 10; ii++)
    {
        time.restart();
        index.knnSearch(randomSamples[ii].V(), 1, &ret_index_clos[0], &out_dist_sqr_clos[0]);
        avgTime += time.elapsed();
    }
    std::cout << "Time : " << avgTime << " ms (mean " << avgTime / (num_test * 10) << "ms)"  << std::endl << std::endl;
}
void InverseDistanceInterpolation<KDDim>::interpolate_field_data (const std::vector<std::string> &field_names,
                                                                  const std::vector<Point>  &tgt_pts,
                                                                  std::vector<Number> &tgt_vals) const
{
  libmesh_experimental();

  // forcibly initialize, if needed
#ifdef LIBMESH_HAVE_NANOFLANN
  if (_kd_tree.get() == NULL)
    const_cast<InverseDistanceInterpolation<KDDim>*>(this)->construct_kd_tree();
#endif

  START_LOG ("interpolate_field_data()", "InverseDistanceInterpolation<>");

  libmesh_assert_equal_to (field_names.size(), this->n_field_variables());

  // If we already have field variables, we assume we are appending.
  // that means the names and ordering better be identical!
  if (_names.size() != field_names.size())
    {
      libMesh::err << "ERROR:  when adding field data to an existing list the\n"
                   << "varaible list must be the same!\n";
      libmesh_error();
    }
  for (unsigned int v=0; v<_names.size(); v++)
    if (_names[v] != field_names[v])
      {
        libMesh::err << "ERROR:  when adding field data to an existing list the\n"
                     << "varaible list must be the same!\n";
        libmesh_error();
      }

  tgt_vals.resize (tgt_pts.size()*this->n_field_variables());

#ifdef LIBMESH_HAVE_NANOFLANN
  {
    std::vector<Number>::iterator out_it = tgt_vals.begin();

    const size_t num_results = std::min((size_t) _n_interp_pts, _src_pts.size());

    std::vector<size_t> ret_index(num_results);
    std::vector<Real>   ret_dist_sqr(num_results);

    for (std::vector<Point>::const_iterator tgt_it=tgt_pts.begin();
         tgt_it != tgt_pts.end(); ++tgt_it)
      {
        const Point &tgt(*tgt_it);
        const Real query_pt[] = { tgt(0), tgt(1), tgt(2) };

        _kd_tree->knnSearch(&query_pt[0], num_results, &ret_index[0], &ret_dist_sqr[0]);

        this->interpolate (tgt, ret_index, ret_dist_sqr, out_it);

        // libMesh::out << "knnSearch(): num_results=" << num_results << "\n";
        // for (size_t i=0;i<num_results;i++)
        //   libMesh::out << "idx[" << i << "]="
        //       << std::setw(6) << ret_index[i]
        //       << "\t dist["<< i << "]=" << ret_dist_sqr[i]
        //       << "\t val[" << std::setw(6) << ret_index[i] << "]=" << _src_vals[ret_index[i]]
        //       << std::endl;
        // libMesh::out << "\n";

        // libMesh::out << "ival=" << _vals[0] << '\n';
      }
  }
#else

  libMesh::err << "ERROR:  This functionality requires the library to be configured\n"
               << "with nanoflann KD-Tree approximate nearest neighbor support!\n"
               << std::endl;
  libmesh_error();

#endif

  STOP_LOG ("interpolate_field_data()", "InverseDistanceInterpolation<>");
}