コード例 #1
0
bool distorted(const int v1,const int v2,const int v3,const std::vector<CVector<3,double> >& result) 
{
	if (result[v1][2]<0 || result[v2][2]<0 || result[v3][2]<0)
		return true;

	CVector<3,double> d12 = result[v2]-result[v1];
	CVector<3,double> d23 = result[v3]-result[v2];
	CVector<3,double> d31 = result[v1]-result[v3];
	double n12 = GetNorm2(d12);
	double n23 = GetNorm2(d23);
	double n31 = GetNorm2(d31);

	if (n12>m_max_edge_length || n23>m_max_edge_length || n31>m_max_edge_length)
		return true;

	double cos1=dot(d12,-d31)/(n12*n31);
	double cos2=dot(-d12,d23)/(n12*n23);
	double cos3=dot(-d23,d31)/(n23*n31);
	double maxcos = std::max(std::max(cos1,cos2),cos3);

	double t = cos(m_distortion_angle*M_PI/180);
	return maxcos > t;
}
コード例 #2
0
double SubgradientDecomposition::Maximize(int iter_max, double gap_threshold, UpperBoundFn F_upper)
{
	double theta, z, delta;
	double upper_bound_best = 1e100;
	Subproblem* s;
	int k;
	int gamma; // number of steps since the last improvement of the best objective value
	int gamma_bar = 20;
	int delta_min_num = 0;
	double norm2_max = 0;

	// init
	memset(buf, 0, n0*sizeof(double));
	n = 0;
	for (s=subproblems->ScanFirst(); s; s=subproblems->ScanNext())
	{
		if (s->weight < 0) { printf("Error: subproblem weight cannot be negative!\n"); exit(1); }
		if (s->weight == 0) continue;
		for (k=0; k<s->var_num; k++) buf[s->array[k]] += s->weight*s->weight;
		n += s->var_num;
	}
	for (k=0; k<n0; k++)
	{
		if (buf[k] <= 0) { printf("Incorrect decomposition: not all elements are covered!\n"); exit(1); }
	}

	double* vars = new double[2*n];
	double* g = vars + n;

	ReadBest(vars);
	z = theta = ProjectAndComputeSubgradient(vars, g);
	WriteBest(vars);

	gamma = 0;
	for (k=0; k<iter_max; k++)
	{
		double upper_bound = F_upper(user_arg);
		if (k==0 || upper_bound_best>upper_bound) upper_bound_best = upper_bound;
		if (k==0) delta = (upper_bound_best - z)*options.C;
		if (z>=upper_bound_best-gap_threshold) break;
		double norm2 = GetNorm2(g, n);
		if (norm2 == 0) break;
		if (norm2_max < norm2) norm2_max = norm2;
		double upper_bound_estimate = z+delta;
		//if (upper_bound_estimate > upper_bound_best) upper_bound_estimate = upper_bound_best;
		double lambda = options.alpha*(upper_bound_estimate-theta)/norm2;
		if (options.verbose) printf("%d\t%f\t%f\tstep=%f", k, theta, upper_bound, lambda);
		Add(vars, g, lambda, n);
		theta = ProjectAndComputeSubgradient(vars, g);

		if (theta > z)
		{
			if (options.verbose) printf(" *");
			delta *= options.A;
			z = theta;
			WriteBest(vars);
			gamma = 0;
		}
		else 
		{
			delta *= options.B;
			if (gamma ++ >= gamma_bar)
			{
				if (options.verbose) printf(" restart");
				gamma_bar += 10; if (gamma_bar > 50) gamma_bar = 50;
				ReadBest(vars);
				gamma = 0;
				theta = ProjectAndComputeSubgradient(vars, g);
				if (delta < (upper_bound_best - z)*0.01)
				{
					if (options.verbose) printf("\nconverged?\n");
					break;
				}
			}
		}
		if (delta < (upper_bound_best - z)*options.C)
		{
			if (options.verbose) printf(" !");
			if (delta_min_num ++ >= 30)
			{
				if (options.verbose) printf("\nconverged?\n");
				break;
			}
			delta = (upper_bound_best - z)*options.C;
		}
		if (options.verbose) printf("\n");
	}
	
	if (options.verbose) printf("lower_bound=%f\tupper_bound=%f\n", z, upper_bound_best);

	delete [] vars;

	return z;
}