typename DownhillSimplexMethod< DIM >::Converged DownhillSimplexMethod< DIM >::optimize( const ParamsT& initial )
    {
        assert( m_refl > 0.0 );
        assert( m_exp > 1.0 );
        assert( m_exp > m_refl );
        assert( 0 < m_contr && m_contr < 1 );
        assert( 0 < m_shri && m_shri < 1 );
        assert( m_initFactor > 0.0 );

        // Prepare optimization
        m_iterations = 0;
        createInitials( initial );

        Converged conv = CONVERGED_NO;
        Step next = STEP_START;
        while( next != STEP_EXIT )
        {
            switch( next )
            {
                case STEP_START:
                    order();
                    conv = converged();
                    if( conv != CONVERGED_NO )
                    {
                        next = STEP_EXIT;
                        break;
                    }
                    ++m_iterations;
                    centroid();
                    next = STEP_REFLECTION;
                    break;
                case STEP_REFLECTION:
                    next = reflection();
                    break;
                case STEP_EXPANSION:
                    next = expansion();
                    break;
                case STEP_CONTRACTION:
                    next = contraction();
                    break;
                case STEP_SHRINKAGE:
                    next = shrinkage();
                    break;
                default:
                    std::cerr << "Undefined control flow!";
                    next = STEP_EXIT;
                    break;
            }
        }

        return conv;
    }
예제 #2
0
파일: 3237.cpp 프로젝트: miskcoo/oicode
void divide(int now, int n, int l, int r, int connect)
{
	for(int i = 0; i != n; ++i)
	{
		d[i] = edge[now][i];
		map[d[i].id] = i;
	}

	for(int i = l; i <= r; ++i)
	{
		for(int j = 0; j != ques[i].num; ++j)
			d[map[ques[i].d[j]]].mark = 1;
	}

	if(l == r)
	{
		for(int i = 0; i != n; ++i)
		{
			int u = ms.find(d[i].u), v = ms.find(d[i].v);
			if(u != v && !d[i].mark) 
			{
				ms.fa[u] = ms.fa[v];
				--connect;
			}
		}

		ms.reset(n, d);
		ques[l].ans = connect;
		return;
	} 

	connect -= contraction(n);
	reduction(n, l, r);

	for(int i = 0; i != n; ++i)
		edge[now + 1][i] = d[i];

	int m = (l + r) >> 1;
	divide(now + 1, n, l, m, connect);
	divide(now + 1, n, m + 1, r, connect);
}
예제 #3
0
파일: simplex.c 프로젝트: kalaee/numeric
// simplex routine
// f is n dimensional function to be minimised, lower and upper are bounds of coordinates for initial vertices
// simplex_goal_size is tolerance for convergene and W is workspace for simplex routine of dimension n
// out termination the vector W->ce will contain coordinates for lowest vertex
int simplex(double f(gsl_vector* x),double lower, double upper, double simplex_goal_size, simplex_workspace* W)
{
	int steps = 0;
	double fp1, fp2, flo, fhi;
	// initialize system by generating vertices and
	// finding their function values
	simplex_generate(lower,upper,W);
	simplex_initialize(f,W);
	do
	{
		// make an update for higher, lower and centroid
		simplex_update(W);
		fhi = gsl_vector_get(W->fp,W->hi);
		flo = gsl_vector_get(W->fp,W->lo);
		// make reflection
		reflection(W);
		fp1 = f(W->p1);
		if (fp1 < flo)
		{
			// if f(reflected) < f(lower) attempt expansion
			expansion(W);
			fp2 = f(W->p2);
			if (fp2 < fp1)
			{
				// if f(expanded) < f(reflecred) accept expansion
				gsl_matrix_set_row(W->simplex,W->hi,W->p2);
				gsl_vector_set(W->fp,W->hi,fp2);
			}
			else
			{
				// if not, accept reflection
				gsl_matrix_set_row(W->simplex,W->hi,W->p1);
				gsl_vector_set(W->fp,W->hi,fp1);
			}
		}
		else
		{
			if (fp1 < fhi)
			{
				// if f(reflected) < f(higher) accept reflection
				gsl_matrix_set_row(W->simplex,W->hi,W->p1);
				gsl_vector_set(W->fp,W->hi,fp1);			
			}
			else
			{
				// if not, attempt contraction
				contraction(W);
				fp2 = f(W->p2);
				if (fp2 < fhi)
				{
					// if f(contracted) < f(higher), accept contraction
					gsl_matrix_set_row(W->simplex,W->hi,W->p2);
					gsl_vector_set(W->fp,W->hi,fp2);
				}
				else
				{
					// if not, we must be in a valley, perform reduction
					reduction(f,W);
				}
			}
		}
	steps++;
	// if simplex has reduced sufficiently, that is size(simplex) < simplex_goal_size
	// convergence is achieved. Return number of steps before convergence.
	} while (simplex_size(W) > simplex_goal_size);
	// copy lowest vertex to centroid vector
	gsl_matrix_get_row(W->ce,W->simplex,W->lo);
	return steps;
}