{"data":{"markdownRemark":{"html":"<h2 id=\"repeatability-in-models\"><a href=\"#repeatability-in-models\" aria-hidden=\"true\" class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Repeatability in Models</h2>\n<p>An important part of building models is that their results should be repeatable if the same inputs are given to them. The Simudyne SDK creates models that rely on numerical seeds that are randomly generated. A number of tools are provided for random number generation, but if a model is built properly, it should still be deterministic with respect to its seed.</p>\n<p>It is easy to unintentionally introduce other sources of randomness into the model besides its numerical seed. The output of a properly built model should only change under two conditions: if its input parameters change or if its numerical seed is purposely changed. For the same model running with the same seed, the only source of change should be the input parameters.</p>\n<h2 id=\"enforcing-determinism\"><a href=\"#enforcing-determinism\" aria-hidden=\"true\" class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Enforcing Determinism</h2>\n<p>The easiest way to enforce determinism is to use the random number generator provided from the model context. The seed will be the same for all instances of this model for the entire run.</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">public</span> <span class=\"token keyword\">class</span> <span class=\"token class-name\">myModel</span> <span class=\"token keyword\">extends</span> <span class=\"token class-name\">AgentBasedModel</span><span class=\"token generics function\"><span class=\"token punctuation\">&lt;</span>GlobalState<span class=\"token punctuation\">></span></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">public</span> <span class=\"token keyword\">void</span> <span class=\"token function\">setup</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        SeededRandom pnrg <span class=\"token operator\">=</span> <span class=\"token function\">getContext</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">getPRNG</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        pnrg<span class=\"token punctuation\">.</span>generator<span class=\"token punctuation\">.</span><span class=\"token function\">nextDouble</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n    <span class=\"token punctuation\">.</span><span class=\"token punctuation\">.</span><span class=\"token punctuation\">.</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<h2 id=\"randomness-health-checks\"><a href=\"#randomness-health-checks\" aria-hidden=\"true\" class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Randomness Health Checks</h2>\n<p>Health checks are implemented in the SDK to warn modellers if an unanticipated source of randomness may be present. This is achieved by internally running and testing the output of a registered model when starting the server.</p>\n<p>Health checks can be disabled by setting the value of the config field <code class=\"language-text\">nexus-server.health-check</code> in the <code class=\"language-text\">SimudyneSDK.properties</code> file. This value is a boolean, true by default, so setting it to false will disable health checks. To learn more about model configurations related to health checks, click <a href=\":version/reference/models/model-configuration\">here</a>.</p>\n<h2 id=\"unintentional-ways-to-introduce-randomness\"><a href=\"#unintentional-ways-to-introduce-randomness\" aria-hidden=\"true\" class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Unintentional Ways to Introduce Randomness</h2>\n<h3 id=\"user-defined-random-generator\"><a href=\"#user-defined-random-generator\" aria-hidden=\"true\" class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>User-Defined Random Generator</h3>\n<p>A random number generator defined by the user will not use the seed defined in a model's configuration. This generator's seed is not controlled, so determinism is not enforced.</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\">Random r <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Random</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\nr<span class=\"token punctuation\">.</span><span class=\"token function\">nextBoolean</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<h3 id=\"variable-source-for-seed\"><a href=\"#variable-source-for-seed\" aria-hidden=\"true\" class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Variable Source for Seed</h3>\n<p>A model cannot create repeatable results if its numeric seed varies between simulation runs.\nIn this example, a different time would be computed each time the model is called, so the seed would change every time.</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">long</span> seed <span class=\"token operator\">=</span> System<span class=\"token punctuation\">.</span><span class=\"token function\">currentTimeMillis</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\nSeededRandom prng <span class=\"token operator\">=</span> SeededRandom<span class=\"token punctuation\">.</span><span class=\"token function\">create</span><span class=\"token punctuation\">(</span>seed<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\nprng<span class=\"token punctuation\">.</span>generator<span class=\"token punctuation\">.</span><span class=\"token function\">nextDouble</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<h3 id=\"modifying-global-state-from-agents\"><a href=\"#modifying-global-state-from-agents\" aria-hidden=\"true\" class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Modifying Global State from Agents</h3>\n<p>Although the global state can be accessed and updated by any agent using the <code class=\"language-text\">getGlobals</code> function, doing so may result in non-deterministic behavior. Modifying global variables can have unforeseen effects on other parts of a model.\nIn this example, the agent updates the global state with its own value. Later in the code, the agent accesses this variable again to send a message to its neighbor. However, in the meantime, this variable could have been updated again. There is no certainty about its state.\nThis example is trivial, but updating the GlobalState from an agent is usually considered bad practice.</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">boolean</span> isTrueLocal <span class=\"token operator\">=</span> <span class=\"token boolean\">true</span><span class=\"token punctuation\">;</span>\n<span class=\"token function\">getGlobals</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>isTrueGlobal <span class=\"token operator\">=</span> isTrueLocal<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">.</span><span class=\"token punctuation\">.</span><span class=\"token punctuation\">.</span>\n<span class=\"token comment\">// Later in the agent, undefined behavior!</span>\n<span class=\"token function\">getLinks</span><span class=\"token punctuation\">(</span>BooleanLinks<span class=\"token punctuation\">.</span><span class=\"token keyword\">class</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">send</span><span class=\"token punctuation\">(</span>BooleanMessage<span class=\"token punctuation\">.</span><span class=\"token keyword\">class</span><span class=\"token punctuation\">,</span> <span class=\"token function\">getGlobals</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>isTrueGlobal<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<div class=\"ui segment info message\" ><h4>Setting Globals During Setup</h4>\n<p>Globals allows you to define variables that can be accessed and modified by both the model and agents within the system. However, during the setup process when you are creating agents via an injector, you should not by modifying globals. This is due to Java 8 lambda's. If you wish to properly modify Globals, make sure it is part of the message passing action of an agent, or make usage of an accumulator.</p></div>\n<h3 id=\"relying-on-message-ordering\"><a href=\"#relying-on-message-ordering\" aria-hidden=\"true\" class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Relying on Message Ordering</h3>\n<p>Agents and messages are not processed in a specific order, so relying on message order will create randomness.\nIn this example, the loan request fulfillment depends on the ordering of messages. If some agents send a request, there is no certainty about which request will be accepted. This dependency on apparent ordering can be found in other places. Links, IDs of agents, and updates of the global state do not possess a proper order.</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">int</span> liquidity <span class=\"token operator\">=</span> <span class=\"token number\">1000</span><span class=\"token punctuation\">;</span>\nList<span class=\"token generics function\"><span class=\"token punctuation\">&lt;</span>LoanRequest<span class=\"token punctuation\">></span></span> allLoanRequest <span class=\"token operator\">=</span> <span class=\"token function\">getMessagesOfType</span><span class=\"token punctuation\">(</span>LoanRequest<span class=\"token punctuation\">.</span><span class=\"token keyword\">class</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">for</span><span class=\"token punctuation\">(</span>LoanRequest m<span class=\"token operator\">:</span> messages<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span>m<span class=\"token punctuation\">.</span><span class=\"token function\">getBody</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;</span> liquidity<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        liquidity <span class=\"token operator\">=</span> liquidity <span class=\"token operator\">-</span> m<span class=\"token punctuation\">.</span><span class=\"token function\">getBody</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token function\">getLinksTo</span><span class=\"token punctuation\">(</span>m<span class=\"token punctuation\">.</span><span class=\"token function\">getSender</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">send</span><span class=\"token punctuation\">(</span>LoanResponse<span class=\"token punctuation\">.</span><span class=\"token keyword\">class</span><span class=\"token punctuation\">,</span> <span class=\"token boolean\">true</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span> <span class=\"token keyword\">else</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token function\">getLinksTo</span><span class=\"token punctuation\">(</span>m<span class=\"token punctuation\">.</span><span class=\"token function\">getSender</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">send</span><span class=\"token punctuation\">(</span>LoanResponse<span class=\"token punctuation\">.</span><span class=\"token keyword\">class</span><span class=\"token punctuation\">,</span> <span class=\"token boolean\">false</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>","headings":[{"value":"Repeatability in Models","depth":2},{"value":"Enforcing Determinism","depth":2},{"value":"Randomness Health Checks","depth":2},{"value":"Unintentional Ways to Introduce Randomness","depth":2},{"value":"User-Defined Random Generator","depth":3},{"value":"Variable Source for Seed","depth":3},{"value":"Modifying Global State from Agents","depth":3},{"value":"Relying on Message Ordering","depth":3}],"frontmatter":{"title":"Repeatable Models","toc":true,"experimental":null}},"site":{"siteMetadata":{"title":"Simudyne Docs","latestVersion":"2.6"}}},"pageContext":{"absolutePath":"/home/vsts/work/1/s/content/2.4/docs/practices/repeatable-models.md","versioned":true,"version":"2.4","kind":"docs","pagePath":"/practices/repeatable-models","chronology":{"prev":{"name":"Coordinator Pattern","path":"/practices/coordinator-pattern"},"next":{"name":"Randomness & Distributions","path":"/practices/randomness"}},"lastUpdated":"2026-04-21T13:56:54.847Z"}}