Ada中间隔中的唯一随机数列表

时间:2011-03-19 11:24:01

标签: algorithm random ada

我很抱歉打扰你我知道this question被问了很多但是从未和Ada在一起......我想知道Ada标准库中是否有生成独特随机列表的方法O(n)中的数字(你永远不会选择相同数字的两倍) 在某种程度上,在Ada中有Knuth-Fisher-Yates算法的实现吗?

3 个答案:

答案 0 :(得分:5)

有关于实施Fisher–Yates shuffle here的讨论。基本上,您需要在每次迭代中使用不同范围的Discrete_Random,如图所示here;如Float_Random中所述,A.5.2(50), Note 16是另一种选择。如果偏差不重要,那么example就足够了。

在任何情况下, shuffling 都是 O(n),但选择可以是 O(1)

附录:创建集合的复杂性取决于implementation。例如,Containers.Hashed_Sets, A.18.8(88/2)Containers.Ordered_Sets, A.18.9(116/2)

答案 1 :(得分:2)

鉴于你想要: a)从0到1000的随机数 和 b)数字不得重复 根据你提供的链接,你可以很容易地做到这一点。

只需使用值范围填充数组,并在随机选择的元素上执行一些交换;这保证了两个要求得到维护。

答案 2 :(得分:1)

我冒昧地编写了它。 你需要使用Ada.Numerics.Discrete_Random。

   Generic
      Low, High : Integer;
   Package Initialization is
      SubType Element is Integer Range Low..High;
      Function Incrementor Return Element;
      Type Element_Array is Array(Element) of Element;

      Values : Element_Array;
      Procedure Print;
   End Initialization;

   Package Body Initialization is
      Count : Element := Element'Last;

      Function Incrementor Return Element is
      begin
         Return Result : Element:= Count do
            Null;
            Count:= Element'Pred( Result );
         Exception
               When Constraint_Error => Count:= Element'Last;
         End Return;
      end Incrementor;

      Procedure Swap( Index_1, Index_2 : In Integer ) is
         Temp : Constant Element:= Values( Integer(Index_1) );
      begin
         Values( Integer(Index_1) ):= Values( Integer(Index_2) );
         Values( Integer(Index_2) ):= Temp;
      end Swap;

      Procedure Print is
      begin
         Put_Line( "Length: " & Values'Length'Img );
         Put( "(" );
         For Index in Values'First..Integer'Pred(Values'Last) loop
            Put( Values(Index)'Img & ',' );
         end loop;
         Put( Values(Values'Last)'Img );
         Put_Line( ")" );
      end Print;


   Begin
      Shuffle:
      Declare
         Package Random_Element is New
        Ada.Numerics.Discrete_Random( Element );
         Number : Random_Element.Generator;
         Use Random_Element;
      Begin
         Values:= Element_Array'( Others => Incrementor );
         Reset( Number );
         For Index in Element'Range loop
            Swap( Integer(Index), Integer(Random(Number)) );
         end loop;
      End Shuffle;
   End Initialization;

你可以用以下方法测试它:

   Test:
   Declare
      Package Q is new 
    Initialization( Low => 0, High => 1000 );
   Begin
      Q.Print;
   End Test;