给定文件和深度的随机目录/文件

时间:2009-10-12 07:06:48

标签: python algorithm

我想介绍一些VCS软件,为此我想在随机排列的目录中生成一组随机文件。我正在用Python编写脚本,但我的问题很简单:如何生成一个随机目录树,每个目录有一个平均子目录数,每个目录有一些广泛的文件分发? < / p>

澄清:我不是在比较不同的VCS回购格式(例如SVN与Git与Hg),而是分析处理SVN(以及最终其他)工作副本和回购的软件。

我想要的约束是指定文件总数(称为'N',可能约为10k-100k)和目录结构的最大深度('L',可能是2-10)。我不关心在每个级别生成多少目录,我不希望每个目录最终得到1个文件,或者在一个目录中得到100k。

分布是我不确定的,因为我不知道VCS'(特别是SVN)是否会在结构非常均匀或结构非常偏斜的情况下表现更好或更差。尽管如此,如果我能想出一个对于大数字没有“均衡”的算法,那将是很好的。

我的第一个想法是:使用某种方法生成目录树,然后用文件统一填充树(平等地处理每个目录,不考虑嵌套)。我的背后计算告诉我,如果有'L'级别,每个目录有'D'子目录,每个目录有大约sqrt(N)个文件,那么就会有大约D ^ L dirs,所以N = ~sqrt(N)*(D ^ L)=&gt; D = ~N ^(1 / 2L)。所以现在我有'D'的近似值,我该如何生成树?如何填充文件?

对于我可以使用的算法的一些指示,我将不胜感激。我的搜索只发现了漂亮的applets / flash。

3 个答案:

答案 0 :(得分:4)

为什么不下载一些真正的开源回购并使用它们?

您是否考虑过文件中的内容?是随机数据吗?

答案 1 :(得分:0)

你的问题相当漫长且涉及很多,但我认为这可以归结为要求具有某些统计属性的随机数生成器。

如果你不喜欢python的随机数生成器,你可能会看一下pypi上的其他一些统计软件包,或者你想要一些更重要的东西,也许是GNU Scientific Library的python绑定。

http://sourceforge.net/projects/pygsl/

http://www.gnu.org/software/gsl/

答案 2 :(得分:0)

我最近编写了一个小型python软件包randomfiletree,该软件包会生成随机的文件/目录结构。代码和手册在https://github.com/klieret/randomfiletree上。

该算法遍历现有文件树并基于具有一定宽度和期望值的高斯在每个子文件夹中创建许多文件和目录。然后重复此过程。

它基本上使用这样的东西:

def create_random_tree(basedir, nfiles=2, nfolders=1, repeat=1,
                       maxdepth=None, sigma_folders=1, sigma_files=1):
    """
    Create a random set of files and folders by repeatedly walking through the
    current tree and creating random files or subfolders (the number of files
    and folders created is chosen from a Gaussian distribution).

    Args:
        basedir: Directory to create files and folders in
        nfiles: Average number of files to create
        nfolders: Average number of folders to create
        repeat: Walk this often through the directory tree to create new
            subdirectories and files
        maxdepth: Maximum depth to descend into current file tree. If None,
            infinity.
        sigma_folders: Spread of number of folders
        sigma_files: Spread of number of files
    Returns:
       (List of dirs, List of files), all as pathlib.Path objects.
    """
    alldirs = []
    allfiles = []
    for i in range(repeat):
        for root, dirs, files in os.walk(str(basedir)):
            for _ in range(int(random.gauss(nfolders, sigma_folders))):
                p = Path(root) / random_string()
                p.mkdir(exist_ok=True)
                alldirs.append(p)
            for _ in range(int(random.gauss(nfiles, sigma_files))):
                p = Path(root) / random_string()
                p.touch(exist_ok=True)
                allfiles.append(p)
            depth = os.path.relpath(root, str(basedir)).count(os.sep)
            if maxdepth and depth >= maxdepth - 1:
                del dirs[:]
    alldirs = list(set(alldirs))
    allfiles = list(set(allfiles))
    return alldirs, allfiles

这是一种很简单的方法,但是如果有兴趣的话,也可以进一步开发此模块。

相关问题