Esempio n. 1
0
bool multiset_test()
{
#if ( ! (__GNUC__==4 && __GNUC_MINOR__==6) )
  data_buffer buffer;
  buffer.buffer().open("./test2_.bin");
  buffer.buffer().reserve(TEST_COUNT*sizeof(data)+TEST_COUNT);
  buffer.buffer().clear();

  index123_type index123( (cmp123(buffer)) );
  index123.clear();

  return
    init(buffer, index123)
    
    && check(buffer, index123)
    && stress(buffer, index123, 10000)
    && check(buffer, index123)
    && clear(buffer, index123)
    && init(buffer, index123)
    && erase_begin(buffer, index123)
    && check(buffer, index123);
#else
  return true;
#endif
  
}
Esempio n. 2
0
/**
 * This method should be used both as a solution to 3D cases, and as a general termination method for algorithms that reduce D-dimensional problem to 3-dimensional one.
 *
 * This is the implementation of the algorithm for computing hypervolume as it was presented by Nicola Beume et al.
 * The implementation uses std::multiset (which is based on red-black tree data structure) as a container for the sweeping front.
 * Original implementation by Beume et. al uses AVL-tree.
 * The difference is insiginificant as the important characteristics (maintaining order when traversing, self-balancing) of both structures and the asymptotic times (O(log n) updates) are guaranteed.
 * Computational complexity: O(n*log(n))
 *
 * @param[in] points vector of points containing the 3-dimensional points for which we compute the hypervolume
 * @param[in] r_point reference point for the points
 *
 * @return hypervolume.
 */
double hv3d::compute(std::vector<fitness_vector> &points, const fitness_vector &r_point) const
{
	if (m_initial_sorting) {
		sort(points.begin(), points.end(), fitness_vector_cmp(2,'<'));
	}
	double V = 0.0; // hypervolume
	double A = 0.0; // area of the sweeping plane
	std::multiset<fitness_vector, fitness_vector_cmp> T(fitness_vector_cmp(0, '>'));

	// sentinel points (r_point[0], -INF, r_point[2]) and (-INF, r_point[1], r_point[2])
	const double INF = std::numeric_limits<double>::max();
	fitness_vector sA(r_point.begin(), r_point.end()); sA[1] = -INF;
	fitness_vector sB(r_point.begin(), r_point.end()); sB[0] = -INF;

	T.insert(sA);
	T.insert(sB);
	double z3 = points[0][2];
	T.insert(points[0]);
	A = fabs((points[0][0] - r_point[0]) * (points[0][1] - r_point[1]));

	std::multiset<fitness_vector>::iterator p;
	std::multiset<fitness_vector>::iterator q;
	for(std::vector<fitness_vector>::size_type idx = 1 ; idx < points.size() ; ++idx) {
		p = T.insert(points[idx]);
		q = (p);
		++q; //setup q to be a successor of p
		if ( (*q)[1] <= (*p)[1] ) { // current point is dominated
			T.erase(p); // disregard the point from further calculation
		} else {
			V += A * fabs(z3 - (*p)[2]);
			z3 = (*p)[2];
			std::multiset<fitness_vector>::reverse_iterator rev_it(q);
			++rev_it;

			std::multiset<fitness_vector>::reverse_iterator erase_begin (rev_it);
			std::multiset<fitness_vector>::reverse_iterator rev_it_pred;
			while((*rev_it)[1] >= (*p)[1] ) {
				rev_it_pred = rev_it;
				++rev_it_pred;
				A -= fabs(((*rev_it)[0] - (*rev_it_pred)[0])*((*rev_it)[1] - (*q)[1]));
				++rev_it;
			}
			A += fabs(((*p)[0] - (*(rev_it))[0])*((*p)[1] - (*q)[1]));
			T.erase(rev_it.base(),erase_begin.base());
		}
	}
	V += A * fabs(z3 - r_point[2]);

	return V;
}