예제 #1
0
int main() {
    int v1, v2;
    scanf("%d %d", &v1, &v2);
    int t;
    scanf("%d %d", &t, &d);
    int result = findMaxDistance(v1, v2, t);
    printf("%d\n", result);
    return 0;
}
예제 #2
0
int findMaxDistance(int v1, int v2, int t) {
    int v_1 = mymin(v1, v2);
    int v_2 = mymax(v1, v2);
    if (t == 2) {
        assert(v_2 - v_1 <= d);
        return v_1 + v_2;
    } else {
        return v_1 + findMaxDistance(v_1 + d, v_2, t - 1);
    }
}
예제 #3
0
void Thread::minimize_energy()
{
	//Set up optimization parameters
  setStationaryOptParams();	


/*
  std::cout << "start: " << std::endl;

  std::cout << thread_curvature_error_penalty << std::endl;
  std::cout << thread_torsion_error_penalty  << std::endl;
  std::cout << thread_diff_curvature_error_penalty  << std::endl;
  std::cout << thread_diff_torsion_error_penalty << std::endl;
  std::cout << position_error_penalty  << std::endl;
  std::cout << rotation_error_penalty  << std::endl;
  std::cout << total_error_penalty  << std::endl;
  std::cout << gravity_penalty  << std::endl;
*/

	ThreadPiece* maxDistPiece;
	double maxDist = findMaxDistance(&maxDistPiece);
	while (maxDist > DISTANCE_THRESH)
	{
		//decide how many pieces each piece must be split into
		int numPiecesLeft, numPiecesRight;
		if (maxDistPiece->_length == maxDistPiece->_next_segment->_length)
		{
			numPiecesLeft = 2;
			numPiecesRight = 2;
		} else if (maxDistPiece->_length > maxDistPiece->_next_segment->_length) {
			numPiecesLeft = (int)(maxDistPiece->_length / maxDistPiece->_next_segment->_length);
			numPiecesRight = 1;
		} else if (maxDistPiece->_length < maxDistPiece->_next_segment->_length) {
			numPiecesLeft = 1;
			numPiecesRight = (int)(maxDistPiece->_next_segment->_length / maxDistPiece->_length);
		}
		opt_params.length_per_segment = (maxDistPiece->_length + maxDistPiece->_next_segment->_length)/((double)(numPiecesLeft+numPiecesRight));
		opt_params.num_segments = numPiecesLeft+numPiecesRight;
		//std::cout << "splitting into " << opt_params.num_segments << "   length per segment: " << opt_params.length_per_segment << std::endl;


//		opt_params.transform_back = Matrix4d::Identity();
		opt_params.transform_back = _transform_to_start;
    opt_params.length_back = 0.0;
		opt_params.transform_front = Matrix4d::Identity();
    opt_params.length_front = 0.0;
	
		//opt_params.twist_total_other_segments = 0.0;

		ThreadPiece* currPiece = threadList;
		while (currPiece != maxDistPiece)
		{
			opt_params.transform_back *= currPiece->_transform;
      opt_params.length_back += currPiece->_length;
			//opt_params.twist_total_other_segments += currPiece->_length* currPiece->_torsion;
      opt_params.curvature_back = currPiece->_curvature;
      opt_params.torsion_back = currPiece->_torsion;
			currPiece = currPiece->_next_segment;
		}
		currPiece = maxDistPiece->_next_segment->_next_segment;
    if (currPiece != NULL)
    {
      opt_params.curvature_front = currPiece->_curvature;
      opt_params.torsion_front = currPiece->_torsion;
    }
		while (currPiece != NULL)
		{
			opt_params.transform_front *= currPiece->_transform;
      opt_params.length_front += currPiece->_length;
			//opt_params.twist_total_other_segments += currPiece->_length* currPiece->_torsion;
			currPiece = currPiece->_next_segment;
		}
		
		//std::cout << "twist other seg: " << opt_params.twist_total_other_segments << std::endl;
		
		//std::cout << "transform start: " << opt_params.transform_back << std::endl;
		//std::cout << "transform end: " <<   opt_params.transform_front << std::endl;



		//set initial parameters
		if (opt_params.orig_params_each_piece->nrows() < 2*opt_params.num_segments+1)
		{
			delete(opt_params.orig_params_each_piece);
			opt_params.orig_params_each_piece = new NEWMAT::ColumnVector(2*opt_params.num_segments+1);
		}

		int ind = 0;
		for (; ind < numPiecesLeft; ind++)
		{
			opt_params.orig_params_each_piece->element(2*ind) = maxDistPiece->_curvature;
			opt_params.orig_params_each_piece->element(2*ind+1) = maxDistPiece->_torsion;
		}
		for (; ind < numPiecesLeft + numPiecesRight; ind++)
		{
			opt_params.orig_params_each_piece->element(2*ind) = maxDistPiece->_next_segment->_curvature;
			opt_params.orig_params_each_piece->element(2*ind+1) = maxDistPiece->_next_segment->_torsion;
		}
		opt_params.orig_params_each_piece->element(2*opt_params.num_segments) = _angle_first_rot;


		//setup OPT++ problem
    NEWMAT::ColumnVector x_sol;
		optimize_FDNLF(2*opt_params.num_segments+1, energyEvalFunction, energyEvalFunction_init, x_sol, 1.e-6);

	  //split into pieces with new parameters
		double curvature[numPiecesLeft+numPiecesRight];
		double torsion[numPiecesLeft+numPiecesRight];

		for (int ind=0; ind < opt_params.num_segments; ind++)
		{
			curvature[ind] = x_sol(2*ind +1);
			torsion[ind] = x_sol(2*ind+2);
		}
		_angle_first_rot = x_sol(opt_params.num_segments*2+1);
	//	std::cout << curvature[0] << " " << curvature[1] <<  " " << curvature[2] <<  " " << curvature[3] <<  " " << std::endl;

		maxDistPiece->_next_segment->splitIntoSegments(&curvature[numPiecesLeft], &torsion[numPiecesLeft], numPiecesRight);
		maxDistPiece->splitIntoSegments(curvature, torsion, numPiecesLeft);

    

		//get next piece to be split
		maxDist = findMaxDistance(&maxDistPiece);
		//std::cout << "maxDist: " << maxDist << std::endl;
	}
  //printThreadInfo();
	
}