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