分治算法——基本思想是将一个计算复杂的问题分为规模较小,计算简单的小问题求解,然后综合所有的小问题,得到最终的答案,程序中可以使用递归算法来进行求解。
分治算法问题实例:假币问题——一个袋子里有30个硬币,其中一个是假币,并且假币和真币一模一样,肉眼难辨,目前只知道真币比假币重一点,请问怎么区分出假币。
分析:将问题分为小问题求解
- 将30个硬币分为相等两份,称重比较
- 将重量较小的那一份再次分为两份,称重比较
- 当硬币的个数为奇数的时候,将多出来的一个硬币提取出来后再判断另外两份的重量,如果不等,取出重量小的那份,重复步骤一二,如果相等,表明多出来的那一个硬币即是假币。
- 若上面未找出假币,则一直递归分治,直到硬币数只有两个时。重量小的即假币。
代码实现:
// 分治算法——银币重量问题
int fenZhi(int[] data, int start, int end) {
//输入参数data代表每个硬币的重量,start即data中第一个数据的地址,end即最后一个数据的地址
int sum1 = 0;//前半段的和
int sum2 = 0;//后半段的和
int mid;//中间值
//判断是否只有两个数据
if ((end - start + 1) == 2) {
if (data[start] > data[end]) {
return end + 1;
} else {
return start + 1;
}
}
//若不止两个数据、取得中间值
mid =start+(end - start) / 2;
//根据硬币个数的奇偶求前后两段的重量和
if ((end - start + 1) % 2 == 0) {// 偶数
for (int i = start; i <=mid; i++) {
sum1 += data[i];
}
for (int j =mid + 1; j <= end; j++) {
sum2 += data[j];
}
} else if ((end - start + 1) % 2 != 0) {// 奇数
for (int i = start; i <mid; i++) {
sum1 += data[i];
}
for (int j =mid + 1; j <= end; j++) {
sum2 += data[j];
}
}
//递归
if (sum1 < sum2) {
return fenZhi(data, start, mid);
} else if (sum1 > sum2) {
return fenZhi(data, mid+1, end);
} else {
return mid+1;
}
}
概率算法——以概率统计的思路来求解问题,往往不能得到问题的精确解。
概率算法大致分为四种形式:
- 数值概率算法;
- 蒙特卡罗算法;
- 拉斯维加斯算法;
- 舍伍德算法;
概率算法实例:蒙特卡罗概率算法(计算圆周率PI)
代码实现:
//概率算法——蒙特卡罗算法求解PI
double montePi(int n){
//传入的参数n表示随机点的个数
int sum=0;//统计点落在圆内的次数
double PI;
for(int i=0;i<n;i++){
double x=Math.random();//0~1之间的随机数
double y=Math.random();//0~1之间的随机数
if((x*x+y*y)<=1){
sum++;//计数
}
}
PI=4.0*sum/n;//计算圆周率
return PI;
}