一维搜索(暴力搜索、黄金分割、区间消去、菲波拉契)c++ 算法实现

  • main.cpp
#include <iostream>
#include <cmath>
#include "Search.h"


using namespace std;


double fun(double x){
	return 0.05 * (x*x + 10 * sin(x));
}



int main()
{


	double min_x, min_y;
	int k;
	int number;



	do
	{

	
	std::cout << "Please chose a search method : \n";
	std::cout << "1.Violent search" << endl;
	std::cout << "2.Interval elimination search" << endl;
	std::cout << "3.Golden section search" << endl;
	std::cout << "4.Fibonacci search" << endl;
	std::cout << "5.Exit" << endl;
	std::cin >> number; //输入number的数值
	std::cout << "You entered: " << number << std::endl;
	switch (number)
	{
	case 1:
			std::tie(min_x, min_y, k) = violent_search(fun, -5, 0, 0.1);
			std::cout << "Minimum x: " << min_x << std::endl;
			std::cout << "Minimum y: " << min_y << std::endl;
			std::cout << "Iterations: " << k << std::endl;
			break;
	case 2:
		
			std::tie(min_x, min_y, k) = interval_elimination_search(fun, -5, 0, 0.1);
			std::cout << "Minimum x: " << min_x << std::endl;
			std::cout << "Minimum y: " << min_y << std::endl;
			std::cout << "Iterations: " << k << std::endl;
			break;
	case 3:
			std::tie(min_x, min_y, k) = golden_section_search(fun, -5, 0, 0.1);
			std::cout << "Minimum x: " << min_x << std::endl;
			std::cout << "Minimum y: " << min_y << std::endl;
			std::cout << "Iterations: " << k << std::endl;
		break;
	case 4:
			std::tie(min_x, min_y, k) = fibonacci_search(fun, -5, 0, 0.1);
			std::cout << "Minimum x: " << min_x << std::endl;
			std::cout << "Minimum y: " << min_y << std::endl;
			std::cout << "Iterations: " << k << std::endl;
		break;
	
	}
	
	} while (number!=5);
	

	return 0;
}
  • Search.h
#ifndef SEARCH_H
#define SEARCH_H

#include <functional>
#include <tuple>
#include <chrono>
#include <iostream>
#include <vector>

std::tuple<double, double, int> violent_search(std::function<double(double)> fun_input, double x_min,double x_max,double epsilon);
std::tuple <double, double, int> interval_elimination_search(std::function<double(double)> fun_input, double x_min, double x_max, double epsilon);
std::tuple <double, double, int> golden_section_search(std::function<double(double)> fun_input, double x_min, double x_max, double epsilon);
std::tuple <double, double, int> fibonacci_search(std::function<double(double)> fun_input, double x_min, double x_max, double epsilon);
#endif // !SEARCH_H

 

  • violent_search.cpp(暴力搜索)
#include "Search.h"

std::tuple<double, double, int> violent_search(std::function<double(double)> fun_input, double x_min, double x_max, double epsilon) {
	
	
	auto start = std::chrono::high_resolution_clock::now();//获取当前时间,以获得该算法的耗时
	double num = std::ceil((x_max - x_min) / epsilon);//将区间分为num份
	double min_x = x_min;
	double min_y = 1.0e10;

	for (int i = 0; i <= num; ++i) {
		double x_temp = x_min + i * epsilon;//x的增量
		double y_temp = fun_input(x_temp);

		if (y_temp < min_y) {//更新min_x,与min_y。
			min_x = x_temp;
			min_y = y_temp;
		}
	}

	int k = num + 1;

	auto end = std::chrono::high_resolution_clock::now();
	auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
	std::cout << "Algorithm took: " << duration.count() << " microseconds" << std::endl;

	return std::make_tuple(min_x, min_y, k);//返回make_tuple类型的数
}
  • golden_section_search.cpp(黄金分割)
#include "Search.h"

std::tuple <double, double, int> golden_section_search (std::function<double(double)> fun_input, double x_min, double x_max, double epsilon) {
	auto start = std::chrono::high_resolution_clock::now();
	
	
	double ruo = (3 - std::sqrt(5)) * 0.5;//这个数是0.381966
	//和区间消去一样
	double x_left_side = x_min;
	double x_right_side = x_max;
	double x_left_center = x_left_side + ruo * (x_right_side - x_left_side);
	double x_right_center = x_right_side - ruo * (x_right_side - x_left_side);
	double y_left_center = fun_input(x_left_center);
	double y_right_center = fun_input(x_right_center);

	int num = 0;

	while (true) {
		num++;

		if (y_left_center >= y_right_center) {
			x_left_side = x_left_center;
			x_right_side = x_right_side;
			x_left_center = x_right_center;//这里是原来的右边界成为新的左边界
			//只更新右边界,提高算法效率
			x_right_center = x_right_side - ruo * (x_right_side - x_left_side);
			y_left_center = y_right_center;
			y_right_center = fun_input(x_right_center);
		}
		else {
			x_left_side = x_left_side;
			x_right_side = x_right_center;
			x_right_center = x_left_center;
			x_left_center = x_left_side + ruo * (x_right_side - x_left_side);
			y_right_center = y_left_center;//同理
			y_left_center = fun_input(x_left_center);
		}

		if (x_right_side - x_left_side <= epsilon) {
			break;
		}
	}
	auto end = std::chrono::high_resolution_clock::now();
	auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
	std::cout << "Algorithm took: " << duration.count() << " microseconds" << std::endl;
	double min_x = (x_left_side + x_right_side) * 0.5;
	double min_y = fun_input(min_x);
	int k = num;
 
	return std::make_tuple(min_x, min_y, num);
}
  •  fibonacci_search.cpp

#include "Search.h"

//std::tuple <double, double, int> fibonacci_search(std::function<double(double)> fun_input, double x_min, double x_max, double epsilon) {
//	
//	
//		double Fibonacci_up = (x_max - x_min) / epsilon;
//		std::vector<int> Fibonacci_set = { 1, 2 };
//		int Fibonacci_num = 1; // 初始斐波那契数列索引为 1
//		while (true) {
//			int next_fibonacci = Fibonacci_set[Fibonacci_num] + Fibonacci_set[Fibonacci_num - 1];
//			if (next_fibonacci >= Fibonacci_up) {
//				break;
//			}
//			Fibonacci_set.push_back(next_fibonacci);
//			Fibonacci_num++;
//		}
//		int N = Fibonacci_num - 1;
//		std::vector<double> ruo(N);
//		double x_left_side = x_min;
//		double x_right_side = x_max;
//		double x_left_center = x_left_side + ruo[0] * (x_right_side - x_left_side);
//		double x_right_center = x_right_side - ruo[0] * (x_right_side - x_left_side);
//		double y_left_center = fun_input(x_left_center);
//		double y_right_center = fun_input(x_right_center);
//		for (int i = 2; i <= N; ++i) {
//			if (N == i) {
//				ruo[i] = 0.5 - 0.1 * epsilon;
//			}
//			else {
//				ruo[i] = 1.0 - static_cast<double>(Fibonacci_set[N - i + 1]) / Fibonacci_set[N - i + 2];
//			}
//
//			if (y_left_center >= y_right_center) {
//				x_left_side = x_left_center;
//				x_right_side = x_right_side;
//				x_left_center = x_right_center;
//				x_right_center = x_right_side - ruo[i] * (x_right_side - x_left_side);
//				y_left_center = y_right_center;
//				y_right_center = fun_input(x_right_center);
//			}
//			else {
//				x_left_side = x_left_side;
//				x_right_side = x_right_center;
//				x_right_center = x_left_center;
//				x_left_center = x_left_side + ruo[i] * (x_right_side - x_left_side);
//				y_right_center = y_left_center;
//				y_left_center = fun_input(x_left_center);
//			}
//		}
//		double min_x = (x_left_side + x_right_side) * 0.5;
//		double min_y = fun_input(min_x);
//		int k = N - 1;
//
//		return std::make_tuple(min_x, min_y, k);
//}


std::tuple<double, double, int> fibonacci_search(std::function<double(double)> fun_input, double x_min, double x_max, double epsilon) {
	// 计算斐波那契数列
	auto start = std::chrono::high_resolution_clock::now();
	double Fibonacci_up = (x_max - x_min) / epsilon;
	int Fibonacci_set[100];
	Fibonacci_set[0] = 1;
	Fibonacci_set[1] = 2;
	int Fibonacci_num = 2;

	while (true) {
		Fibonacci_set[Fibonacci_num] = Fibonacci_set[Fibonacci_num - 1] + Fibonacci_set[Fibonacci_num - 2];
		if (Fibonacci_set[Fibonacci_num] >= Fibonacci_up)
			break;
		Fibonacci_num++;
	}

	int N = Fibonacci_num - 1;
	double ruo[100];
	ruo[0] = 1 - Fibonacci_set[N] / (double)Fibonacci_set[N + 1];

	// 初始化
	double x_left_side = x_min;
	double x_right_side = x_max;
	double x_left_center = x_left_side + ruo[0] * (x_right_side - x_left_side);
	double x_right_center = x_right_side - ruo[0] * (x_right_side - x_left_side);
	double y_left_center = fun_input(x_left_center);
	double y_right_center = fun_input(x_right_center);

	// 循环搜索
	for (int i = 1; i < N; ++i) {
		if (N == i + 1)
			ruo[i] = 1 / 2 - 0.1 * epsilon;
		else
			ruo[i] = 1 - Fibonacci_set[N - i] / (double)Fibonacci_set[N - i + 1];

		if (y_left_center >= y_right_center) {
			// 更新区间,继续计算
			x_left_side = x_left_center;
			x_left_center = x_right_center;
			x_right_center = x_right_side - ruo[i] * (x_right_side - x_left_side);
			y_left_center = y_right_center;
			y_right_center = fun_input(x_right_center);
		}
		else {
			// 更新区间,继续计算
			x_right_side = x_right_center;
			x_right_center = x_left_center;
			x_left_center = x_left_side + ruo[i] * (x_right_side - x_left_side);
			y_right_center = y_left_center;
			y_left_center = fun_input(x_left_center);
		}
	}

	// 输出最近点和迭代步长
	double min_x = (x_left_side + x_right_side) * 0.5;
	double min_y = fun_input(min_x);
	int k = N;
	auto end = std::chrono::high_resolution_clock::now();
	auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
	std::cout << "Algorithm took: " << duration.count() << " microseconds" << std::endl;

	return std::make_tuple(min_x, min_y, k);
}



 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值