埃及分数——迭代加深搜索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 }
——现在的努力是为了小时候吹过的牛B!!