【问题标题】:Elixir - Randomized numbers in AgentElixir - Agent 中的随机数
【发布时间】:2015-08-06 22:53:45
【问题描述】:

我正在尝试实现一个像骰子一样的代理:

defmodule Dice do
  @on_load :seed_generator

  def start_link(opts \\ []) do
    Agent.start_link(fn -> [] end, name: __MODULE__)
  end

  def roll(n, val) do
    Agent.cast(__MODULE__, fn(_) ->
      Stream.repeatedly(fn -> :random.uniform(val) end)
      |> Enum.take(n)
    end)
  end

  def seed_generator do
    :random.seed(:erlang.now)
    :ok
  end
end

但是,每次我重新启动 iex 时,生成的数字都是一样的。 我究竟做错了什么 ?种子是否因为 :random.uniform 调用在代理内部而不起作用?或者与Stream 相关的东西。

【问题讨论】:

    标签: random elixir agent


    【解决方案1】:

    seed_generator 函数在与您的Agent 将使用的进程不同的进程中调用。实际上,在加载此代码时甚至不存在该过程。启动 Agent 时尝试为生成器播种:

    defmodule Dice do
      def start_link(opts \\ []) do
        Agent.start_link(fn -> :random.seed(:erlang.now) end, name: __MODULE__)
      end
    
      def roll(n, val) do
        Agent.get(__MODULE__, fn(_) ->
          Stream.repeatedly(fn -> :random.uniform(val) end)
          |> Enum.take(n)
        end)
      end
    end
    

    【讨论】:

    • 似乎有效,这样做:Agent.start_link(fn -> :random.seed(:erlang.now); [] end, name: __MODULE__) 将空列表保留为默认状态。谢谢。
    • 您在roll 函数中无论如何都忽略了状态,所以我认为这并不重要。您的实际状态是保存随机生成器状态的进程字典。
    • 代替 erlang.now(),函数 os.timestamp() 可能也不错:erlang.org/doc/man/os.html#timestamp-0 因为 erlang.now() 可能会带来一些问题。
    猜你喜欢
    • 2016-12-11
    • 1970-01-01
    • 1970-01-01
    • 2018-07-29
    • 2019-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-11
    相关资源
    最近更新 更多