代码之家  ›  专栏  ›  技术社区  ›  ashawley

如何在序列中生成随机的负整数和正整数文件?

  •  0
  • ashawley  · 技术社区  · 16 年前

    我想要一个随机生成的正或负序列整数的文件。现在,我要求该文件包含大致相等的负数和正数(不需要保证),但要方便以后更改比例。在“序列”中,我的意思是kth随机负等于-k,kth随机正等于+k。

    这个gnu-bash脚本一行程序可以满足文件格式,但不能满足 random .

    $ seq -1 -1 -5 && seq 1 5
    -1
    -2
    -3
    -4
    -5
    1
    2
    3
    4
    5
    

    这个例子显示了我正在寻找的更好的东西,但是仍然不是随机的,因为整数可以预测地在负整数和正整数之间交替。

    $ paste <(seq -1 -1 -5) <(seq 1 5) | tr '\t' '\n'
    -1
    1
    -2
    2
    -3
    3
    -4
    4
    -5
    5
    

    通过shuf命令发送其中一个命令会使它们随机地成为负的或正的,但是它们会失去连续性。

    $ paste <(seq -1 -1 -5) <(seq 1 5) | tr '\t' '\n' | shuf
    -5
    4
    3
    2
    -2
    1
    -1
    -4
    5
    -3
    

    注意:我正在尝试测试排序列表/位数组(0和1)的算法,但是如果我使用0和1,我将无法分析排序的行为或判断是否保留了稳定性。

    6 回复  |  直到 14 年前
        1
  •  3
  •   Community CDub    8 年前

    我们开始高尔夫比赛吧?(44)

    perl -le'print rand>.5?++$a:--$b for 1..10'
    

    编辑 : daotoad's 40个字符版本

    seq 1 10|perl -ple'$_=rand>.5?++$a:--$b'
    
        2
  •  6
  •   daotoad    16 年前

    如果我理解正确的话,您希望随机地交错正整数和负整数。例如: 1 2 -1 3 -2 4 5- 3 .

    my $count = 10;
    my $pos   =  1;
    my $neg   = -1;
    
    my @random = map { 
        int(rand 2) 
        ? $pos++ 
        : $neg--
    } 1..$count; 
    
    print "@random\n";
    

    更新:

    为了改变比例,我会这样做:

    use strict;
    use warnings;
    
    my $next = get_list_generator(.5);
    
    my @random = map $next->(), 1..10; 
    print "@random\n";
    
    my $again = get_list_generator(.25);
    
    my @another = map $again->(), 1..10; 
    print "@another\n";
    
    sub get_list_generator {
        my $prob_positive = shift;
    
        my $pos = 1;
        my $neg = -1;
    
        return sub {
            return rand() <= $prob_positive ? scalar $pos++ : scalar $neg--;
        }
    
    }
    

    这个 get_list_generator() 函数返回一个闭包。这样,您甚至可以同时运行多个列表生成器。

        3
  •  2
  •   lhunath    16 年前

    在哪里? 15 是生成的数字和 tp 是您想要的正数数量(有效地指示pos/neg的比率):

    tp=8
    unset p n
    for i in $(printf '%s\n' {1..15} | gsort -R); do
        (( i <= tp )) && \
            echo $((++p)) || \
            echo $((--n))
    done
    
        4
  •  1
  •   Brian Campbell Dennis Williamson    16 年前
    #!/bin/bash
    
    pos=0 neg=0
    for i in {1..10}
    do 
        if (( ($RANDOM > 16384 ? ++pos : --neg) > 0 ))
        then echo $pos
        else echo $neg
        fi
    done
    

    我不能把这个装进一个内衬里。还有其他人吗?

    编辑 :啊,一行,65个字符(如果在同一shell中重复调用此命令,则需要设置a和b):

    a=0 b=0;for i in {1..10}; do echo $(($RANDOM>16384?++a:--b));done
    
        5
  •  0
  •   ashawley    16 年前

    这里有一个bash一行(2?)灵感来源于卢纳思和布赖恩的回答。

    RANDOM=$$; pos=1; neg=-1; for i in {1..10}; do \
    echo $(( $(echo $RANDOM / 32767 \> 0.5 | bc -l) ? pos++ : neg-- )); done
    

    这是一个awk脚本,参加高尔夫比赛(44)。

    seq 1 10|awk '{print(rand()>0.5?++p:--n);}'
    

    这是更清晰的惯用方法:

    seq 1 10 | awk 'BEGIN{srand(); pos=1; neg=-1;}
                    {print (rand() > 0.5 ? pos++ : neg--);}'
    
        6
  •  -1
  •   Indeed is Trash    16 年前

    没有一组符合您所有标准的数字。你不能说你想要随机的,但同时说第k个负值=-k,第k个正值==k。你要么随机,要么不随机。

    至于你想做什么,为什么不把这两个问题分开,在一个长度为n的整数对数组上测试排序呢?第一对可以是0或1,第二对可以是你的稳定性追踪器(从0到n的计数)。

    生成所需的0和1的列表,并将它们随机移动,然后添加到跟踪器整数上。现在按它们的第一个元素对它们进行排序。

    您排序的输入将如下所示。

    0, 1
    1, 2
    0, 3
    1, 4
    1, 5
    0, 6
    0, 7
    1, 8
    1, 9
    1, 10
    0, 11
    0, 12
    0, 13
    

    稳定的种类会产生这个

    0, 1
    0, 3
    0, 6
    0, 7
    0, 11
    0, 12
    0, 13
    1, 2
    1, 4
    1, 5
    1, 8
    1, 9
    1, 10
    

    不稳定的整数会产生0和1,跟踪整数的顺序不对。