{"id":1469,"date":"2015-08-01T00:01:47","date_gmt":"2015-08-01T07:01:47","guid":{"rendered":"http:\/\/c-for-dummies.com\/blog\/?p=1469"},"modified":"2015-08-22T07:58:48","modified_gmt":"2015-08-22T14:58:48","slug":"weighted-random-numbers","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=1469","title":{"rendered":"Weighted Random Numbers"},"content":{"rendered":"<p>Random numbers are useful when simulating information and they add a degree of unpredictability to computer games. The problem programmers run into, especially with simulation, is that not everything is truly random. In many cases, some numbers need to be more random than others. The solution is to generate weighted random numbers.<br \/>\n<!--more--><br \/>\nA <em>weighted random number<\/em> has a bias. The numbers generated are random, but some values pop up more frequently than others.<\/p>\n<p>As an example, say a program recreates the three states of existence for a cat: Playing, Eating, and Sleeping.<\/p>\n<blockquote><p>Yeah, yeah: The cat also hunts and performs other activities. Classify them all as &#8220;play&#8221; for the sake of this Lesson.<\/p><\/blockquote>\n<p>Say you were to code a cat simulator using a standard random number generator. Over time, it would spit out values in an even distribution; the cat would play, eat, and sleep in equal quantities. That&#8217;s not really reflective of the reality you&#8217;re trying to recreate.<\/p>\n<p>After observing cats for most of my life, I&#8217;ve noted that kitty spends a majority of her time sleeping. Therefore, a <em>weighted<\/em> random number generator would produce more sleeping state results and fewer playing and eating state results.<\/p>\n<p>To gather data for your cat simulator program, you apply for a government grant to fund a study of cat activities during a 24 hour period. During each hour, it&#8217;s noted whether the cat was playing, eating, or sleeping. Figure 1 illustrates the results.<\/p>\n<div id=\"attachment_1476\" style=\"width: 338px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-1476\" src=\"http:\/\/c-for-dummies.com\/blog\/wp-content\/uploads\/2015\/08\/0801-fig1.png\" alt=\"Figure 1. Cat statistics, courtesy of a government grant.\" width=\"328\" height=\"388\" class=\"size-full wp-image-1476\" srcset=\"https:\/\/c-for-dummies.com\/blog\/wp-content\/uploads\/2015\/08\/0801-fig1.png 328w, https:\/\/c-for-dummies.com\/blog\/wp-content\/uploads\/2015\/08\/0801-fig1-254x300.png 254w\" sizes=\"auto, (max-width: 328px) 100vw, 328px\" \/><p id=\"caption-attachment-1476\" class=\"wp-caption-text\">Figure 1. Cat statistics, courtesy of a government grant.<\/p><\/div>\n<p>For your code to reflect the proper values, you need to weight the results shown in Figure 1: The cat spends 25% of its time playing, 12.5% of its time eating, and the rest of the time sleeping. The <em>rand()<\/em> function&#8217;s output cannot be changed, therefore you must represent the data in a way that makes the results of the <em>rand()<\/em> function useful.<\/p>\n<p>The solution I devised is based on the hours, not the activities. I created an array of 24 elements, each representing an hour in the day. Then I populate that array with the proper quantities of playing, eating, and sleeping activities. The random number generator fetches a value from the array in the range of 0 to 23, which it does nicely, but the value fetched is weighted based on the research.<\/p>\n<p>Here&#8217;s the code:<\/p>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n#include &lt;stdlib.h&gt;\r\n#include &lttime.h&gt;\r\n\r\nint main()\r\n{\r\n    enum { PLAY, EAT, SLEEP };\r\n    int hours[24] = {\r\n        PLAY, PLAY, PLAY, PLAY, PLAY, PLAY,\r\n        EAT, EAT, EAT,\r\n        SLEEP, SLEEP, SLEEP, SLEEP, SLEEP,\r\n        SLEEP, SLEEP, SLEEP, SLEEP, SLEEP,\r\n        SLEEP, SLEEP, SLEEP, SLEEP, SLEEP\r\n    };\r\n    int x,h;\r\n\r\n    srand((unsigned)time(NULL));\r\n    puts(\"Kitty activity generator\");\r\n    puts(\"Five hours:\");\r\n    for(x=0;x&lt;5;x++)\r\n    {\r\n        printf(\"Hour %d: Kitty is \",x+1);\r\n        h = rand() % 24;\r\n        switch(hours[h])\r\n        {\r\n            case PLAY:\r\n                printf(\"playing\\n\");\r\n                break;\r\n            case EAT:\r\n                printf(\"eating\\n\");\r\n                break;\r\n            case SLEEP:\r\n                printf(\"sleeping.\\n\");\r\n        }\r\n    }\r\n\r\n    return(0);\r\n}<\/pre>\n<p>In Line 7, I used the oddball <a href=\"http:\/\/c-for-dummies.com\/blog\/?p=1440\"><em>enum<\/em><\/a> keyword to generate three constants, <code>PLAY<\/code>, <code>EAT<\/code>, and <code>SLEEP<\/code>, assigned the values 0, 1, and 2, respectively.<\/p>\n<p>The <code>hours[]<\/code> array at Line 8 is populated with the constant values in direct proportion to the results observed in Figure 1: 6 <code>PLAY<\/code> values, 3 <code>EAT<\/code> values, and 15 <code>SLEEP<\/code> values. This distribution reflects the weighted random results needed.<\/p>\n<p>At Line 23, the <em>rand()<\/em> function returns a random value between 0 and 23, matching the number of elements in the array \/ hours in a day. The random value stored in variable <code>h<\/code> isn&#8217;t weighted, but the array is.<\/p>\n<p>The <em>switch-case<\/em> structure between Lines 24 and 34 spews out the weighted random results.<\/p>\n<p>Here&#8217;s sample output:<\/p>\n<pre><code>Hour 1: Kitty is sleeping.\r\nHour 2: Kitty is sleeping.\r\nHour 3: Kitty is eating\r\nHour 4: Kitty is sleeping.\r\nHour 5: Kitty is sleeping.<\/code><\/pre>\n<p>These results more realistically reflect the observable data than would otherwise be generated by a purely random selection.<\/p>\n<p>In <a href=\"http:\/\/c-for-dummies.com\/blog\/?p=1472\">next week&#8217;s Lesson<\/a>, I cover a better way to represent large quantities of weighted random numbers.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Sometimes your code needs more predictable random numbers. <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=1469\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-1469","post","type-post","status-publish","format-standard","hentry","category-main"],"_links":{"self":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1469","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1469"}],"version-history":[{"count":6,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1469\/revisions"}],"predecessor-version":[{"id":1530,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1469\/revisions\/1530"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1469"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1469"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1469"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}