递归问题 跑道 汽车 绕圈问题 Python实现

这篇博客介绍了使用Python解决一个汽车在圆形跑道上移动的递归问题,探讨了递归层数对计算速度的影响,并展示了不同轮次下车辆位置的均值和标准差变化,通过去重统计提高了计算效率。
摘要由CSDN通过智能技术生成

在此用Python实现一个递归问题,感觉自己能简单写递归了。还记得从前看C语言书上的汉诺塔问题真的是。。有些费解,不过现在感觉守得云开见月明了。

问题描述:
一个圆形车道,一共n个位置,有m辆车,开始的位置分别是 0 1一直到m-1,每一轮只能有一个车往前开,但只有前面有空时车才能开,假设每一时刻所以可以移动的车它们移动的概率是相等的。

求 某一时刻所有车的位置的均值的 均值和标准差
求 某一时刻所有车的位置的标准差的 均值和标准差

递归层数很深的时候,计算很慢。但情况个数毕竟是有限的,所以尝试了每次将情况去重并统计次数,再计算下一轮结果,至少内存不超。


import pandas as pd
import numpy as np
import time
M=5
agg_fun={'Label':['count']}
f=lambda x: 1 if x is True else 0
def car_location(N,M,T):
    if T==1:
        temp_car=pd.DataFrame(columns=["car"+str(s) for s in np.arange(0,M,1)])
        temp_car=temp_car.append(pd.Series(np.arange(0,M,1),index=["car"+str(s) for s in np.arange(0,M,1)]),ignore_index=True)
        temp_car.loc[temp_car.shape[0]-1][M-1]+=1
        unique_car_loc=temp_car
        unique_car_loc["count"]=None
        unique_car_loc.loc[0]["count"]=1
        columns=["car"+str(s) for s in np.arange(0,M)]
        unique_car_loc.loc[0][columns]=unique_car_loc.loc[0][columns].sort_values()               
        return unique_car_loc
    else:
        last_location=car_location(N,M,T-1)  
        #last_location=unique_car_loc
        start = time.clock()
        temp_car=last_location[last_location.columns[0:M]] # only location without duplicates
        count_car=last_location[last_location.columns[M]] # only count
        new_car=pd.DataFrame(columns=last_location.columns)
        columns=["car"+str(s) for s in np.arange(0,M)]
        for row in temp_car.index:       # 遍历每一种不重复情况     
            loc_diff=np.diff(temp_car.loc[row]).tolist()            
            if loc_diff.count(1)==len(loc_diff):               
                new_car=new_car.append(pd.concat([temp_car.loc[row],pd.Series(count_car[row],index=["count"])]),ignore_index=True)
                new_car.loc[new_car.shape[0]-1,"car"+str(M-1)]+=1
                new_car.loc[new_car.shape[0]-1][columns]=new_car.loc[new_car.shape[0]-1][columns].sort_values()               
            
            elif loc_diff.count(1)!=len(loc_diff):
                if temp_car.loc[row]["car4"]-temp_car.loc[row]["car0"]!=N-1 and temp_car.loc[row]["car4"]-temp_car.loc[row]["car0"]!=-1:
                    new_car=new_car.append(pd.concat([temp_car.loc[row],pd.Series(count_car[row],index=["count"])]),ignore_index=True)
                    new_car.loc[new_car.shape[0]-1,"car"+str(M-1)]+=1 # 最后一辆车移动

                loc_diff=pd.DataFrame(loc_diff)
                for ins in loc_diff[loc_diff!=1].dropna().index:
                    new_car=new_car.append(pd.concat([temp_car.loc[row],pd.Series(count_car[row],index=["count"])]),ignore_index=True)
                    new_car.loc[new_car.shape[0]-1,"car"+str(ins)]+=1 # 最后一辆车移动

        new_car_loc=new_car[new_car.columns[0:M]]  
        new_car_loc=new_car_loc.astype(int)
        new_car_loc[new_car_loc>=N-1]=new_car_loc-(new_car_loc//N)*N
        
        for ind in new_car_loc.index:
            new_car_loc.loc[ind][columns]=new_car_loc.loc[ind][columns].sort_values()   
            
        unique_car_loc=new_car_loc.drop_duplicates().reset_index().drop(["index"],axis=1)
        last_count=new_car[new_car.columns[M]]   #之前的次数 与下一次的相乘
        case_car_loc=pd.DataFrame(columns=["cishu"])
        for ind in np.arange(0,unique_car_loc.shape[0]):
            comp=(new_car_loc==unique_car_loc.loc[ind]).applymap(f)
            comp_stat=pd.DataFrame(np.sum(comp,axis=1)==M,columns=["Label"])
            pre_stat=np.sum(last_count.loc[np.argwhere(comp_stat["Label"]==True)[:,0]])
            case_car_loc=case_car_loc.append(pd.Series(pre_stat,index=["cishu"]),ignore_index=True)  
        elapsed = (time.clock() - start)                        
        unique_car_loc["count"]=case_car_loc["cishu"]/10
        print("T
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1.问题描述 给定一个N*N 的方形网格,设其左上角为起点,坐标为(1,1),X 轴向右为正,Y 轴 向下为正,每个方格边长为1。一辆汽车从起点出发驶向右下角终点,其坐标为(N,N)。 在若干个网格交叉点处,设置了油库,可供汽车在行驶途中加油。汽车在行驶过程中应遵守 如下规则: (1)汽车只能沿网格边行驶,装满油后能行驶K 条网格边。出发时汽车已装满油,在 起点与终点处不设油库。 (2)当汽车行驶经过一条网格边时,若其X 坐标或Y 坐标减小,则应付费用B,否则 免付费用。 (3)汽车在行驶过程中遇油库则应加满油并付加油费用A。 (4)在需要时可在网格点处增设油库,并付增设油库费用C(不含加油费用A)。 (5)(1)~(4)中的各数N、K、A、B、C均为正整数。 算法设计: 求汽车从起点出发到达终点的一条所付费用最少的行驶路线。 数据输入: 输入数据。第一行是N,K,A,B,C的值,2 <= N <= 100, 2 <= K <= 10。第二行起是一个N*N 的0-1方阵,每行N 个值,至N+1行结束。方阵的第i 行第j 列处的值为1 表示在网格交叉点(i,j)处设置了一个油库,为0 时表示未设油库。 各行相邻的2 个数以空格分隔。 结果输出: 将找到的最优行驶路线所需的费用,即最小费用输出. Sample input 9 3 2 3 6 0 0 0 0 1 0 0 0 0 0 0 0 1 0 1 1 0 0 1 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 1 1 0 0 1 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1 1 0 0 1 0 0 0 1 0 0 1 0 0 0 0 0 0 0 Sample output 12
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值