【问题标题】:Problem with if condition on a "random walk" script“随机游走”脚本上的 if 条件问题
【发布时间】:2020-01-02 08:00:49
【问题描述】:

我试图让坐标“x”在区间 [-1,1] 内随机移动。但是,我的代码有时有效,有时无效。我试过 ShellCheck 但它说“没有检测到问题!”。我是条件语句的新手,我用错了吗?

我在 linux 的 windows 子系统上运行它。我在 nano 上编辑它。由于我有一个脚本可以绘制 200 条这些“随机游走”,因此代码应该能够始终如一地工作,但我真的不明白为什么它不能。

这是我的代码:

x=0
for num in {1..15}
do
  r=$RANDOM
  if [[ $r -lt 16383 ]]
  then
    p=1
  else
    p=-1
  fi
  if [[ $x -eq $p ]]
  then
    x=$(echo "$x-$p" | bc )
  else
    x=$(echo "$x+$p" | bc )
  fi
  echo "$num $x"
done

我希望是这样的:

1 -1
2 0
3 1
4 0
5 1
6 0
7 1
8 0
9 1
10 0
11 -1
12 0
13 1
14 0
15 1

但通常的输出是这样的:

1 1
2 0
3 -1
4 0
5 -1
6 0
7 -1
(standard_in) 1: syntax error
8
(standard_in) 1: syntax error
9
(standard_in) 1: syntax error
10
(standard_in) 1: syntax error
11
(standard_in) 1: syntax error
12
(standard_in) 1: syntax error
13
(standard_in) 1: syntax error
14
(standard_in) 1: syntax error
15

总是在 -1 之后停止。

【问题讨论】:

标签: bash if-statement conditional-statements


【解决方案1】:

OP 的 18 行随机游走脚本的单行等效项,使用 bash算术评估

  1. x=0; printf '%-5s\n' {1..15}\ $(( x=(RANDOM%2 ? 1 : -1) * (x==0) ))
  2. x=0; printf '%-5s\n' {1..15}\ $(( x=( x ? 0 : (RANDOM%2 ? 1 : -1) ) ))

任何一个的示例输出,(第 2 列在运行之间会有所不同):

1 -1 
2 0  
3 -1 
4 0  
5 1  
6 0  
7 1  
8 0  
9 -1 
10 0 
11 1 
12 0 
13 -1
14 0 
15 -1

它是如何工作的:

  • echo {1..15}\ $(( ...some code... )) 打印数字 115 后跟 $(( ... )) 代码返回的任何结果的 15 个实例。这种方法的一个缺陷是生成的 15 对数字(eg 1 -12 0),每个在bash 看来都是一个字符串,而不是 30 个单独的数字。
  • (RANDOM%2)%modulo operator,这里返回除以 2 的余数,即 01
  • (x==0): $x 可以是三个数字之一,但是如果 $x 的前一个值是 -11 唯一合法的随机步骤是 0,所以我们只需要一个随机数,如果$x 的先前值为 0
  • if 逻辑被替换为 (expr?expr:expr) 形式的快捷方式;这些使用与 OP 脚本相同的逻辑。

【讨论】:

  • 这实际上并没有做随机游走。您制作了一个很好的简短版本,介绍了如何使用模数以另一种方式计算 p(在 OP 的问题中)。您实际上并没有使用x 进行求和。
  • @kvantour,Egad,你是对的,谢谢。明显的输出错误是我当前的代码可以从1 步进到-1 之间没有0。修复待处理。
  • @kvantour,查看修改后的答案。
【解决方案2】:

您可以使用bash

 x=$(( x - p ))

 (( x -= p ))

你不需要bc

【讨论】:

    【解决方案3】:

    x=$(echo "$x-$p" | bc ) 替换为x=$(echo "$x-($p)" | bc ) 以避免echo "-1--1" | bc

    【讨论】:

    • 这是真正的错误修复!
    • 实际上在两者之间放置一个空格就足够了:x = $(echo "$x - $p" | bc ),使用 HERESTRING 甚至更好,x=$(bc <<< "$x - $p")
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-29
    • 2014-03-26
    • 1970-01-01
    相关资源
    最近更新 更多