39 lines
1.2 KiB
Ada
39 lines
1.2 KiB
Ada
with Ada.Numerics.Float_Random, Ada.Numerics.Discrete_Random;
|
|
|
|
package body S_Of_N_Creator is
|
|
|
|
package F_Rnd renames Ada.Numerics.Float_Random;
|
|
F_Gen: F_Rnd.Generator;
|
|
|
|
package D_Rnd is new Ada.Numerics.Discrete_Random(Index_Type);
|
|
D_Gen: D_Rnd.Generator;
|
|
|
|
Item_Count: Natural := 0; -- this is a global counter
|
|
Sample: Item_Array; -- also used globally
|
|
|
|
procedure Update(New_Item: Item_Type) is
|
|
begin
|
|
Item_Count := Item_Count + 1;
|
|
if Item_Count <= Sample_Size then
|
|
-- select the first Sample_Size items as the sample
|
|
Sample(Item_Count) := New_Item;
|
|
else
|
|
-- for I-th item, I > Sample_Size: Sample_Size/I chance of keeping it
|
|
if (Float(Sample_Size)/Float(Item_Count)) > F_Rnd.Random(F_Gen) then
|
|
-- randomly (1/Sample_Size) replace one of the items of the sample
|
|
Sample(D_Rnd.Random(D_Gen)) := New_Item;
|
|
end if;
|
|
end if;
|
|
end Update;
|
|
|
|
function Result return Item_Array is
|
|
begin
|
|
Item_Count := 0; -- ready to start another run
|
|
return Sample;
|
|
end Result;
|
|
|
|
begin
|
|
D_Rnd.Reset(D_Gen); -- at package instantiation, initialize rnd-generators
|
|
F_Rnd.Reset(F_Gen);
|
|
end S_Of_N_Creator;
|