埃及分数——迭代加深搜索IDS

得到的并非最优解

 1 /*
 2 迭代加深搜索解埃及分数
 3 19/45=1/3 + 1/12 + 1/180  
 4 19/45=1/3 + 1/15 + 1/45  
 5 19/45=1/3 + 1/18 + 1/30
 6 19/45=1/4 + 1/6 + 1/180  
 7 19/45=1/5 + 1/6 + 1/18
 8 最后一种最好,因为1/18比1/180,1/45,1/30,1/180都大
 9 */
10 //按照分母递增的顺序来扩展,若扩展到d层时,
11 //前d个分数之和为 now ,而第d个分数为 1 / maxdion,则接下来
12 //至少还要( frac - now ) / (1 / maxdion)个分数和才能达到
13 //frac(假设后面每个分母都为maxdion,即分数最大)
14 
15 #include <iostream>
16 using namespace std;
17 
18 const double error = 1e-7;    //精度,满足此精度就算找到答案 
19 double frac;
20 int depth = 1;    //深度
21 
22 inline double abs(double num)
23 {
24     return num>0 ? num:-num;
25 }
26 
27 bool IDS(int d,double now,int dion)//递归深度,当前的和,分母 
28 {
29     if(d == depth)    //达到搜索深度 
30         {
31             //printf("%d:%lf,%lf\n",d,abs(frac-now),now);
32             if(abs(frac - now) < error)    //递归出来的分数和,和原始埃及分数比较是否达到精度 
33                 return true;
34             return false;
35         }
36     /*
37     frac-now是两分数的差,1/(1/差) + now = frac
38     所以(1/差)是所允许的最大的一个分母
39     (depth - d)是还有几层递归,>=1
40     两者的商就是(递归的层数) * (所允许的最大分母),
41     在当前这层递归中
42     */
43     int maxdion = (int)((depth - d) / (frac - now));
44     
45     for(;dion <= maxdion;dion++)
46         {
47             if(IDS(d+1, now + 1.0/dion, dion+1))    //层数+1,更新和,更新最小分母 
48                 {
49                     cout << "1/" << dion <<' ';
50                     return true;
51                 }
52         }
53     return false;
54 }
55 
56 int main()
57 {
58     int a, b;
59     cout << "a / b, enter a and b : ";
60    cin >> a >> b;
61     frac = (double)a/b;
62     //因为埃及分数的分子始终是1,所以把frac = a/b化成1/x形式,
63     //推出x = 1.0/frac,由于埃及分数的分母肯定比x大
64     //所以先给x+1然后取整数,再进入搜索
65     while(IDS(0,0.0,(int)(1.0/frac)+1) == false)
66         {
67             depth++;    //如果没找到就增加深度继续搜索 
68         }
69     return 0;
70 }

 

posted @ 2013-07-13 15:22  瓶哥  Views(343)  Comments(0Edit  收藏  举报