1

我想要一个随机生成的正或负序列整数文件。现在,我要求文件包含大致相等数量的负数和正数(无需保证),但以后可以轻松更改比例。“串行”是指第 k 个随机负数等于 -k,第 k 个随机正数等于 +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,我将无法分析排序的行为或判断是否保持稳定性。

4

6 回答 6

6

如果我理解正确,您希望随机交错正整数和负整数。例如: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()函数返回一个闭包。这样,您甚至可以同时运行多个列表生成器。

于 2009-04-07T17:44:47.847 回答
4

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

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

编辑daotoad 的40 字符版本

seq 1 10|perl -ple'$_=rand>.5?++$a:--$b'
于 2009-04-07T18:44:42.430 回答
2

其中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
于 2009-04-07T19:03:54.427 回答
1
#!/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
于 2009-04-07T19:21:33.620 回答
0

这是受 lhunath 和 Brian 的回答启发的 Bash one-liner (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--);}'
于 2009-04-07T19:58:17.837 回答
-1

没有一组数字可以满足您的所有标准。你不能说你想要随机但同时说第 k 个负值 == -k 和第 k 个正值 == k。您可以随机使用,也可以不使用。

至于您要做什么,为什么不将这两个问题分开并在诸如长度为 n 的整数对数组之类的东西上测试排序。这对中的第一个可以是零或 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,而跟踪器整数乱序。

于 2009-04-07T17:29:39.240 回答