埃及分数式


埃及分数简介

金字塔的故乡埃及也是数学的发源地之一,古埃及数系中,记数常采用分子为1的分数,称为“埃及分数”;

人们研究较多且颇感兴趣的问题是:

  • 把一个给定的整数或分数转化为若干个不相同的埃及分数之和,常约定分解式中不得包含与待分解分数同分母的埃及分数,当然,转化的方法可能有很多种,常把分解式中的埃及分数的个数最少或在个数相同时埃及分数中最大分母为最小的分解式称为最优分解式;

把给定整数或分数分解为埃及分数之和,分解与优化往往是一个烦琐艰辛的过程;

例如对5/121,可以分解为:

  • 5/121=1/61+1/62+1/121+3/3782+1/7381+1/7382+1/54486542

为了尽可能减少分解项数,1969年数学家 布雷策 在《数学游览》中给出了以下优化的三项分解式:

  • 5/121=1/25+1/759+1/208725

同时布雷策证明了: 5/121不可能分解为两个埃及分数之和

从项数来说,上述三项分解式不可能再优化了,但对最大分母来说,布雷策的分解式并不是最优的,我国两位青年数学爱好者于1983年发现:

  • 5/121=1/27+1/297+1/1089

  • 5/121=1/33+1/99+1/1089

  • 5/121=1/33+1/121+1/363

  • 5/121=1/33+1/91+1/33033

这4个分解式都比布雷策的结论要优,按通常约定分解式中不得包含与待分解分数同分母的埃及分数,显然应把第3个分解式排除在外,因此,现在所知把5/121分解为3个埃及分数的最小分母为1089;

那么,分解5/121为3个埃及分数之和,其最大分母能否小于1089呢?我们可以通过程序设计来探索;


构建3个埃及分数的分数式

1.说明:

设指定的分数m/d的3个埃及分数的分母分别为a、b、c(a< b< c),最大分母不超过z,通过二重循环实施枚举;

确定a循环的起始值a1与终止值a2为:

  • 1/a1=m/d-2/z =》 a1=dz/(mz-2d)(即把b、c全放大为z);

  • a2=3d/m+1 (即把b、c全缩减为a);

b循环起始取a+1,终止取z-1;

对于a、b二重循环的每一组a、b,由1/c=m/d-(1/a+1/b)即可确定:

  • a=abd/(mab-d(a+b))

计算x=abd,y=mab-d(a+b);

如果y>0且y整除x,即得整数c,此时如果c>b且c!=d,即得分解为3个埃及分数的分数式,打印输出后退出内循环,继续寻找;

2.程序设计:

#include<stdio.h>
int main()
{
   int a1,a2,a,b,c,d,e,m,n,z;
   long x,y;
   printf("确定分数m/d,请输入m,d:");
   scanf("%d,%d",&m,&d);
   printf("请确定分母的上限:");
   scanf("%d",&z);
   printf("把分数%d/%d分解为三个埃及分数之和:\n",m,d);
   n=0;
   a1=d*z/(m*z-2*d);
   a2=d*3/m+1;
   for(a=a1;a<=a2;a++)       /*构建二重循环枚举*/
      for(b=a+1;b<=z-1;b++)
      {
         e=0;
         if(a==d || b==d)
            continue;
         x=a*b*d;            /*计算x、y值*/
         y=m*a*b-d*(a+b);
         if(y>0 && x%y==0)
         {
            c=x/y;
            e=1;             /*判断并计算整数c*/
         }
         if(e==1 && c<=z && c>b && c!=d)
         {
            n=n+1;
            printf("NO%d:%d/%d=1/%d+1/%d+1/%d \n",n,m,d,a,b,c);
            break;
         }
      }
   printf("共上述%d个分数式\n",n);
}

3.程序运行示例及其注意事项:

确定分数m/d,请输入m,d:5,121
请确定分母的上限:1100
把分数5/121分解为三个埃及分数之和:
NO1:5/121=1/27+1/297+1/1089
NO2:5/121=1/33+1/99+1/1089
NO3:5/121=1/45+1/55+1/1089
共上述3个分数式

这样,我们通过程序设计探索得到:

  • 把分数5/121分解为3个埃及分数式,最大分母至少为1089,即不可能有比上述3个分解式更优的分解;

结果中的最后一个分解式是程序设计探索到的一个新的最优分解式;


构建4个埃及分数分数式

有资料指出,如果把5/121分解为4个埃及分数之和,其分母能否小于1089呢?对于这一还没有定论的分解问题,我们继续应用程序设计进行探索;

1.说明:

设指定的分数m/d的4个埃及分数的分母分别为a、b、c、e(a< b< c< e),最大分母不超过z,通过三重循环实施枚举;

确定a循环的起始值a1与终止值a2为:

  • 1/a1=m/d-3/z =》 a1=dz/(mz-3d)(即把b、c、e全放大为z);

  • a2=d*4/m+1 (即把b、c、e全缩减为a);

b循环起始取a+1,终止取z-2;
c循环起始取b+1,终止取z-1;

对于a、b、c三重循环的每一组a、b、c,由1/e=m/d-(1/a+1/b+1/c)即可确定:

  • e=abcd/(mabc-d(ab+bc+ca));

计算x=abcd,y=mabc-d(ab+bc+ca)

如果y>0且y整除x,即得整数e,此时如果e>c且e!=d,即得分解为4个埃及分数的分数式,打印输出后退出内循环,继续寻求;

2.程序设计:

#include<stdio.h>
int main()
{
   int a1,a2,a,b,c,e,d,f,m,n,z;
   long x,y;
   printf("确定分数m/d,请输入m,d:");
   scanf("%d,%d",&m,&d);
   printf("请确定分母的上届:");
   scanf("%d",&z);
   printf("把分数%d/%d分解为4个埃及分数之和:\n",m,d);
   n=0;
   a1=d*z/(m*z-3*d);
   a2=d*4/m+1;
   for(a=a1;a<=a2;a++)        /*构建三重枚举循环*/
      for(b=a+1;b<=z-2;b++)
         for(c=b+1;c<=z-1;c++)
         {
            f=0;
            if(b==d || c==d || a==d)
               continue;
            x=a*b*c*d;        /*计算x、y值*/
            y=m*a*b*c-d*(a*b+b*c+c*a);
            if(y>0 && x%y==0) /*判断并计算整数e*/
            {
               e=x/y;
               f=1;
            }
            if(f==1 && e<=z && e>c && e!=d)
            {
               n=n+1;         /*输出埃及分数式*/
               printf("NO%d:%d/%d=1/%d",n,m,d,a);
               printf("+1/%d+1/%d+1/%d \n",b,c,e);
               break;
            }
      }
      printf("共上述%d个分数式\n",n);
   }

3.程序运行示例及其注意事项:

确定分数m/d,请输入m,d:5,121
请确定分母的上届:1000
把分数5/121分解为4个埃及分数之和:
NO1:5/121=1/28+1/462+1/484+1/726
NO2:5/121=1/30+1/220+1/484+1/726
NO3:5/121=1/33+1/120+1/605+1/968
NO4:5/121=1/33+1/132+1/484+1/726
NO5:5/121=1/36+1/99+1/484+1/726
NO6:5/121=1/44+1/66+1/484+1/726
共上述6个分数式

注意:从以上6个分解式可知,把5/121分解为4个埃及分数之和,最优分母为726

以上两个程序并不限于关于5/121的分解,其他分数或整数(输入时分母d=1)的埃及分数式,请运行程序搜索;

### C语言实现真分数的最优埃及分数分解 在C语言中,可以利用贪婪算法来实现真分数埃及分数的分解。这种算法的核心思想是从原始真分数中逐步提取最大的单位分数(即分子为1的分数),直到整个分数完全被分解为止。 以下是基于贪婪算法的一个具体实现: #### 实现代码 ```c #include <stdio.h> void egyptianFraction(long numerator, long denominator) { printf("将 %ld/%ld 分解为埃及分数:\n", numerator, denominator); while (numerator != 0 && denominator != 0) { // 计算当前最大可能的分母 long n = denominator / numerator + ((denominator % numerator == 0) ? 0 : 1); // 输出当前的埃及分数项 printf("1/%ld ", n); // 更新新的分子和分母 long nextNumerator = numerator * n - denominator; long nextDenominator = denominator * n; numerator = nextNumerator; denominator = nextDenominator; if (nextNumerator == 0 || nextDenominator == 0) { break; } } printf("\n"); } int main() { long a, b; printf("请输入一个真分数(b/a): "); scanf("%ld/%ld", &b, &a); if (b <= 0 || a <= 0 || b >= a) { printf("错误:输入的不是有效真分数。\n"); return 1; } egyptianFraction(b, a); return 0; } ``` #### 代码解析 上述代码实现了通过贪婪算法将任意真分数转换为埃及分数的功能。其主要逻辑如下: 1. **计算初始的最大分母**:对于给定的真分数 \( \frac{\text{numerator}}{\text{denominator}} \),找到满足条件 \( \frac{1}{\text{n}} \leq \frac{\text{numerator}}{\text{denominator}} \) 的最小正整数 \( n \)[^1]。 2. **更新剩余部分**:从原分数中减去已找到的单位分数 \( \frac{1}{\text{n}} \),并重新计算剩余部分的新分子和新分母[^3]。 3. **重复迭代**:继续对剩余部分应用相同的过程,直至剩余部分变为零[^2]。 此方法能够保证每次选取的是尽可能大的单位分数,从而减少最终分解结果中的项数。 --- ####
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值