2

我有一个项目,它生成用于从测试库中选择项目的随机数字符串。我注意到某些项目的选择率过高,因此我决定检查 Math.Random 的“随机性”。以下代码生成随机排序的数字 0 到 n-1 列表。然后它计算第一项为 0、1、2、...、n-1 的次数。您可以使用水平滑块更改生成的样本数。我产生的结果似乎表明随机数根本不是随机的 例如,如果我选择 100 个六位数字符串的样本,我得到以下分布,表明 0 和 5 的表示率大大低于:11,23, 15,18,24,9 这种模式在我重新运行模拟时成立。我' 我检查了我的代码,但非常感谢其他人对此准确性的见解。我听说 AS3 不会产生真正的随机数,但它们真的会这么糟糕吗?

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" minWidth="955" minHeight="600" >
    <mx:Script>
        <![CDATA[
            import mx.events.ListEvent;
            private var startingArray:Array = [];
            private var questionsArray:Array;
            private var countArray:Array;
            private var randomNumbers:int = 3;
            private function calculate():void{
                countArray = [0,0,0,0,0,0,0,0,0,0];
                for( var i:int = 0; i < slider.value; i++){
                    questionsArray = [];//Reset the list of questions
                    createRandomListOfQuestions(randomNumbers);
                }
                result.text = String(countArray);
            }
            public function createRandomListOfQuestions(_numQuestions:int):void{
                //Create an array containing the sequence of test questions
                var numQuestions:int=_numQuestions;
                //Reset the array
                startingArray=[];//Contains a randomized question order
                for (var i:int=0;i<numQuestions; i++){//Create an array of question numbers starting at 1
                    var count:int = 0
                    startingArray.push(i);
                }
                    //splice() removes one or more elements from an array and returns the deleted elements, 
                    //here only one (as specified in the second argument)
                while (startingArray.length > 0) {//Create a randomized list (questionsArray) from startingArray 
                    var val:int =startingArray.splice(Math.round(Math.random() * (startingArray.length - 1)), 1)
                    questionsArray.push(val);
                    if(count == 0){
                        countArray[val] += 1
                        count++
                    }
                }
                questionsArrayText.text += String(questionsArray) + "\r";
            }

            private function changeEvt(event:Event):void {
                randomNumbers = event.currentTarget.selectedItem.data
            }

        ]]>
    </mx:Script>
    <mx:VBox horizontalCenter="0" verticalCenter="0">
        <mx:Text x="487" y="261" text="{}" width="500" id="result"/>
        <mx:ComboBox  change="changeEvt(event)" >
            <mx:ArrayCollection>
                <mx:Object label="Three" data="3"/>
                <mx:Object label="Four" data="4"/>
                <mx:Object label="Five" data="5"/>
                <mx:Object label="Six" data="6"/>
                <mx:Object label="Seven" data="7"/>
                <mx:Object label="Eight" data="8"/>
                <mx:Object label="Nine" data="9"/>
                <mx:Object label="Ten" data="10"/>
            </mx:ArrayCollection>
        </mx:ComboBox>
        <mx:Button label="New list"  click="calculate()"/>
        <mx:HSlider  id="slider" value="5"  minimum="5" maximum="100"  snapInterval="1" />
        <mx:Label text="Random Numbers: {Math.round(slider.value) }"/>
    </mx:VBox>
    <mx:Text  id="questionsArrayText"  horizontalCenter="0" verticalCenter="0"/>
</mx:Application>
4

2 回答 2

2

有许多自定义随机数生成的实现可用;但是,ActionScriptMath.random()会在给定大量样本的情况下产生预期的分布。

下面是通过Math.random()生成 0 到 100 之间的数字进行的分布。纵轴显示了生成该值的次数。

1,000,000 个样本

1000000 个样本

100,000 个样本

100000 个样本

10,000 个样本

10000 个样本

1,000 个样本

1000 个样本

100 个样品

100 个样本

生成和可视化示例的代码:

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
               xmlns:s="library://ns.adobe.com/flex/spark"
               xmlns:mx="library://ns.adobe.com/flex/mx"
               creationComplete="creationCompleteHandler(event)">

    <fx:Script>
        <![CDATA[
            import mx.collections.ArrayList;
            import mx.events.FlexEvent;

            [Bindable]
            protected var data:ArrayList = new ArrayList();

            protected function creationCompleteHandler(event:FlexEvent):void
            {
                var i:uint = 0;
                var set:Dictionary = new Dictionary();
                const ITERATIONS:uint = 100;

                for (i = 0; i < 100; i++)
                {
                    set[i] = {value: i, count: 0};
                }

                for (i = 0; i < ITERATIONS; i++)
                {
                    var n:uint = Math.random() * 100;
                    set[n].count++;
                }

                for (i = 0; i < 100; i++)
                {
                    data.addItem({value: set[i].value, count: set[i].count});
                }
            }
        ]]>
    </fx:Script>

    <fx:Declarations>
        <mx:SolidColor id="areaFill"
                       color="0x123456"
                       alpha=".3" />
        <mx:SolidColorStroke id="areaStroke"
                             color="0x123456" />
    </fx:Declarations>

    <mx:AreaChart height="100%"
                  width="100%"
                  paddingLeft="5"
                  paddingRight="5"
                  showDataTips="true"
                  dataProvider="{data}">

        <mx:verticalAxis>
            <mx:LinearAxis title="count" />
        </mx:verticalAxis>

        <mx:horizontalAxis>
            <mx:CategoryAxis categoryField="value"
                             title="value" />
        </mx:horizontalAxis>

        <mx:series>
            <mx:AreaSeries yField="count"
                           areaStroke="{areaStroke}"
                           areaFill="{areaFill}">
            </mx:AreaSeries>
        </mx:series>

    </mx:AreaChart>

</s:Application>
于 2013-06-11T05:01:40.270 回答
0

您可以调用 random.org,但您必须等到网站使用事件侦听器返回。

function getRandomNum(min, max) {
    var randTextURLRequest:URLRequest = new URLRequest("http://www.random.org/integers/?num=1&min=" + min + "&max=" + max + "&col=1&base=10&format=plain&rnd=new");
    var randTextLoader:URLLoader = new URLLoader();
    randTextLoader.addEventListener(Event.COMPLETE, randCompleteHandler);
    randTextLoader.load(randTextURLRequest);
}

function randCompleteHandler(e:Event)
{
    var randVal = Number(randTextLoader.data);
    trace("Number " + randVal + " selected");
}

// You may then type in your code getRandomNum(1, 100)
于 2013-07-20T04:04:38.850 回答