最新公告
  • 欢迎您光临欧资源网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入我们
  • 5.5.4用数学方法解约瑟夫环环(1)_经济学网

    5.5.4 数学求解约瑟夫环(1)

    原文副本:

    5.5.4 用数学方法求解约瑟夫环(1)

    上面写的解决约瑟夫环的程序模拟了报号的整个过程,程序的运行时间可以接受,而且可以很快,但是当参与者总数N和出队值M是很大,运行速度会变慢。比如当N的值是百万,M的值是几万时,最后只剩下2个人,需要几万个循环(M的个数)确定2人中下一次出队的序号。显然,在这个程序的执行过程中,很多步骤都是重复无用的循环。

    那么,能不能设计一个更高效的程序呢?

    当然有办法。其中,在 Joseph 环中,只需要获取最后一个 dequeuer 的初始序号即可,无需模拟报号的全过程。因此,为了追求效率,我们可以考虑从数学的角度进行计算,找出规律,然后编写程序。

    为了讨论方便,先按原意用数学语言描述问题。

    问题:将编号为0~(N–1)的N个人排成一圈,从0开始顺时针计数,向M-1报告退出循环队列的人数,剩下的人继续从0开始计数,然后重复。在循环队列中找到最初离开队列的最后一个人的号码。

    下面先列出0~(N -1)这N个人的原始编号如下:

    根据前面的推导流程,第一个上榜的人数必须是(M–1)%n。例如41个人中,如果上榜3的人,则第一个被列出的人的编号必须是(M–1)%n)。列出的人的编号必须是(3–1)%41=2,注意这里的编号是从0,所以数字2其实对应1的起点的数字3。根据前面的描述,m(M–1)的前一个元素已经出队,那么出队1人后的列表就是如下:

    根据规则,当有人出队,下一个位置的人从0开始计数时,上面的列表可以调整为如下形式(即从位置M开始,后面跟着0、@ N–1) >1、2…, 形成一个环):

    按照上面的顺序重新编号,可以得到如下对应:

    即下架1人后的数据重新整理成一个0~(N–2)一共N-1人的列表,继续找n-1人,按数字到M – 1为出队,求解循环队列中最后一个出队的初始编号。

    有什么规定吗?顺便说一句,通过一次处理,减少了问题的规模。即对于报N个人数的问题可以分解为先解决(N-1)个人报数的子问题;而对于(N-1)个人报数,可以分解为先求[(N–1)-1]报人数的子问题,…

    题量最小的情况是什么?也就是只有一个人(N=1)时,报号给(M-1)的人出队,此时最后出队的是谁?当然只有数字为 0 的人。因此,可以设置以下功能:

    那么,当N=2时,向(M-1)报号的人出队,最后出队的人是谁?应该是最后出队时得到的序号只有一个人报号加Go to M,因为注册M-1的人已经被退市了,而且只有2个人,那么另一个退市就是最后一个,可以用下面的形式表示:

    按上式计算时,F(2)的结果可能会超过N值(总人数)。例如设N=2,M=3(即2人,当计数达到列表中的2个时),根据上式计算的值为:

    只有2人参与,3号人显然没有。怎么做?由于是循环报号,当两个人报完号后,0号开始报号。根据这个原理m环想细解法,可以对得到的值和总人数N进行取模运算,即:

    5.5.4 用数学方法求解约瑟夫环(2)

    即N=2,M=3(即有2人,报人数时3-1人出队时),最后出队人数队列的数量为 1(编号从 0 开始)。我们来计算一下m环想细解法,如下图,当号码为0、@>1时,两个人循环报号时,号码0分别报0和2。报到2时(M–1),号码0 出队,最后剩下数字 1,所以数字是 1 是最后被列出的。

    根据以上推导过程,很容易推导出N=3时的公式:

    同理,当参加人数为N时,也可以推导出最后列出人员编号的公式:

    其实这是一个递归公式,公式包含以下两个公式:

    有了这个递归公式,设计程序就很简单了。您可以使用递归方法来设计程序。具体代码如下:

    #包括

    intmain(void)

    m环想细解法_m幻想细解法_钢链连接焊死的乳环阴环女m

    {

    intn,m,i,s=0;

    printf(“输入参与人数N和出队位置的值M=”);

    scanf(“%d%d”,&n,&m);

    printf(“最后一个出队的人原来的位置是%dn”, josephus(n, m));

    get();

    return0;

    }

    intjosephus(intn,intm)

    {

    如果(n==1)

    return0;

    其他

    钢链连接焊死的乳环阴环女m_m幻想细解法_m环想细解法

    return(约瑟夫斯(n- 1,m)+m)%n;

    }

    在上面的代码中,定义了一个递归函数josephus(),然后在main函数中调用这个函数进行操作。

    编译执行上面的程序,输入N和M的值,可以快速得到最后列出的人的数量,输入N=8,M=3,结果如图5-19所示(注意编号从0开始)。

    使用递归函数会占用大量计算机内存。当递归级别太深时,程序可能无法执行。因此,程序也可以直接写成如下递归形式:

    #包括

    intmain(void)

    {

    intn,m,i,s=0;

    printf(“输入参与人数N和出队位置值M=”);

    scanf(“%d%d”,&n,&m);

    for(i=2;i

    站内大部分资源收集于网络,若侵犯了您的合法权益,请联系我们删除!
    欧资源网 » 5.5.4用数学方法解约瑟夫环环(1)_经济学网

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    欧资源网
    一个高级程序员模板开发平台

    发表评论