算法初步学习一 穷举法的学习
今天学习常见的算法之一”穷举法“,所谓穷举则为就是把有限集合的所有元素逐一进行比较,进行判断和处理,从而得出所需结果。
穷举的一个比较实用的示例百鸡问题:公鸡5元一只,母鸡3元一只,小鸡1元3只,求100元钱买一百只鸡,公鸡、母鸡、小鸡的数量各是多少。
用我们所学的数学可以得出以下方程式:
a+b+c=100;
a*5+b*3+c/3=100;
c%3=0;
问题分析,100元钱买100只鸡的问题,母鸡公鸡小鸡的数量都是不确定的有可能有多种组合答案,不管有多少种都要满足以上列出的方程式,进而我们可以猜测满足问题的答案可能为三个数组,对应索引的数量组成问题的答案,根据问题进一步联想100元钱买100只鸡,从而问题升华为n元钱买n只鸡的问题,进而问题转化为了程序
由于我所熟悉的语言为c#所以今后大部分使用c#实现算法思想,请大家见谅:
从分析中可以得知声明三个数组
ArrayList g = new ArrayList(),--公鸡
m = new ArrayList(),--母鸡
s = new ArrayList();--小鸡
因为母鸡、公鸡和小鸡的各自的数量应为0到n的任意整数,所以总结出我们可以使用最直接的方法使用三层循环的方式,找出我们所有的答案,这就使用了穷举法处理了数组中所有的元素了实现代码如下
1 public int chicken_question(int n, ArrayList g, ArrayList m, ArrayList s) 2 { 3 int a, b, c; int k = 0; 4 for (a = 0; a <= n; a++) 5 { 6 for (b = 0; b <= n; b++) 7 { 8 for (c = 0; c <= n; c++) 9 { 10 if ((a + b + c) == n && (5 * a + 3 * b + c / 3) == n && c % 3 == 0) 11 { 12 g.Add(a); 13 m.Add(b); 14 s.Add(c); 15 k++; 16 } 17 } 18 } 19 } 20 21 return k; 22 }
以上这个实现方式有三重循环,第一重循环执行次数为n+1次,第二重循环为(n+1)*(n+1)次,第三次循环为n+1的三次方,当n=100时最内层循环的执行就大于100万次之多,从而效率肯定不理想。
从数学方程式的解析思路,一共有三个未知数,应该可以减少一个未知数即减少一层循环,那么可不可以减少循环的次数呢?答案是肯定的,这就使用的算法的思想,使用极限的方式分析问题,假如n元钱全买公鸡最多能买多少呢,无疑是n/5,从而得知最多买母鸡数量为n/3,即最外层循环的最大次数为n/5+1,第二层循环次数最大为n/3+1,小鸡的数量为c=n-a-b从而内层循环去除,实现代码如下
1 public int chicken_questiontwo(int n, ArrayList g, ArrayList m, ArrayList s) 2 { 3 int a, b, c; int k = 0; 4 int i = n / 5, j = n / 3; 5 6 for (a = 0; a <= i; a++) 7 { 8 for (b = 0; b <= j; b++) 9 { 10 c = n - a - b; 11 if ((5 * a + 3 * b + c / 3) == n && c % 3 == 0) 12 { 13 g.Add(a); 14 m.Add(b); 15 s.Add(c); 16 k++; 17 } 18 } 19 } 20 21 return k; 22 }
分析以上代码,我们省略了穷举方法中没有必要的一些组合,从而提高了程序的运行效率,第一层循环执行的次数为n/5+1,第一层为(n/5+1)*(n/3+1),当n为100时内层循环执行次数为714次,从而大大提高了程序的执行效率,可见算法分析中极限分析十分重要。
以上是我学习穷举法的一些总结,没有创新的地方,单纯的学习和积累。如果错误请大家纠正谢谢。学习算法还要兼修数学、计算机相关理论知识,以后学习需要更加努力,加油吧大家~~啊哈哈
浙公网安备 33010602011771号