the number of chances in real scenario could be huge
struct CustomerChance
{
string customer_id;
int chances;
int first_chance_index;
};
int number_chances = 0;
foreach (customer in customers)
{
if (customer.credit >= 1000)
{
int current_chances = (int)(customer.credit/1000.);
CustomerChance cc = { customer.id, current_chances, number_chances };
array_chances.push_back(cc);
number_chances += current_chances;
}
}
int lucky_draw = random(number) modulo number_chances;
int begin = 0;
int end = array_chances.number_of_elements();
int middle = (begin + end)/2;
string winner;
while (begin < end)
{
CustomerChance cc = chance_array[middle];
if (cc.first_chance_index > lucky_draw)
{
// the lucky draw is below the current customer range of chances
end = cc.first_chance_index - 1;
}
else if (cc.first_chance_index + cc.chances) <= lucky_draw)
{
// the lucky draw is after the current customer range of chances
begin = cc.first_chance_index + cc.chances;
}
else
{
// we found the winner
winner = cc.customer_id;
break;
}
middle = (begin + end)/2;
}
You say it could be huge, but how huge?Yup, it could be in few millions.
int number_chances = 0;
foreach (customer in customers)
{
if (customer.credit >= 1000)
{
int current_chances = (int)(customer.credit/1000.);
CustomerChance cc = { customer.id, current_chances, number_chances };
array_chances.push_back(cc);
number_chances += current_chances;
}
}
Will I get number_chances = 0 for first customer?How do you declare the chance_array?
std::vector<CustomerChance> array_chances;
List<CustomerChance> array_chances = new List<CustomerChance>();
If there's a customer A credited $10000, he got 10 chances in this month.
If there's a customer B credited $2000, he got 2 chances in this month.
If there's a customer C credited $100, he got 0 chances in this month.
If there's a customer D credited $3500, he got 3 chances in this month.
array_chances[0] = { "A", 10, 0 };
array_chances[1] = { "B", 2, 10 };
array_chances[2] = { "D", 3, 12 };
Kinda difficult to get your idea in your last comment.if you would say what part is difficult to understand, i probably could help.
Does the algorithm suggested above work?which comments or points are you referring to?
In terms of an algorithm, I would be inclined to model 'raffle tickets':
Customer A gets tickets 1 to 10 inclusive
Customer B gets tickets 1 to 12 inclusive
Customer C gets no tickets
Customer D gets tickets 13 to 15 inclusive
I would then generate a random integer from 1 to 15 inclusive, and determine the winner from that.
Generating the table of tickets would be done throughout the month (or whatever period each 'draw' is over), so no noticeable load as you go, and the output is nothing more than a table of numbers and the name of the 'holder' of that ticket, which is appended to after each transaction is processed so very small.
After you have the winning number, you lookup that number in the table, and get the winner - no significant load there either.
Alan.