Kevin
2013-02-01 11:25:29
The idea of a weighted random number is to be able to have a random number in some range, but have the chances of the result actually center around any desired section of the range, with likelihood of that centering also variable. This seems a little hard to explain in simple words, so I'll give an example.
IE: A random number between 150 and 350, with a likelihood of being 10 times more likely to be near 300 than 150.
This is valuable in cases where you want to click a range of area (some button), and want the clicking to possibly click anywhere, while still more likely to be around the center than the edges (although you could weight an edge instead of the center in some other desireable cases as well).
I have no idea if anyone else cares to use this, but here it is. I personally use it mostly as a method of staying within a dedicated SPS area with my center as the most likely area.
IE: A random number between 150 and 350, with a likelihood of being 10 times more likely to be near 300 than 150.
This is valuable in cases where you want to click a range of area (some button), and want the clicking to possibly click anywhere, while still more likely to be around the center than the edges (although you could weight an edge instead of the center in some other desireable cases as well).
I have no idea if anyone else cares to use this, but here it is. I personally use it mostly as a method of staying within a dedicated SPS area with my center as the most likely area.
//returns -1 as an error, sorry if that's in your desired range.
function WeightedRandom(min, max, weight, weightedNumber: integer): integer;
var
total, currentWeight, differencePer: extended;
i, arrayOffset, rand: integer;
Range: TExtendedArray;
begin
if((min > max) or (weightedNumber > max) or (weightedNumber < min))then
begin
result:= -1;
end else if (min = max)then
begin
result:= min;
end else
begin
SetLength(Range, (max - min+1));
total:= 0;
differencePer:= (weight - 1);//Forces it to an extended number for calculation at the next line
if((max - weightedNumber) > (weightedNumber - min)) then
begin
differencePer:= differencePer / (max - weightedNumber);
currentWeight:= weight - ((weightedNumber - min) * differencePer);
end else
begin
differencePer:= differencePer / (weightedNumber - min);
currentWeight:= 1;
end;
for i:= min to max do
begin
arrayOffset:= i - min;
Range[arrayOffset]:= currentWeight;//((arrayOffset) * currentWeight);
if(i=weightedNumber)then
begin
differencePer:= -1 * differencePer;
end;
total:= total + currentWeight;//Range[arrayOffset];
currentWeight:= currentWeight + differencePer;
end;
i:= round(total);
rand:= randomrange(0, i+1);
total:= 0;
i:= 0;
while(total < rand)do
begin
total:= total + Range[i];
Inc(i);
end;
if(i=0)then
begin
result:= min;
end else
result:= i-1+min;
end;
end;