Automated Lottery Logic : How to choose winners for 3 possible prizes in known quantities - logic

So I have been tasked with designing the methodology for an automated lottery. I'm having trouble conceptualizing it and I'm hoping you fine folks can point me in the right direction.
There are 3 possible prizes (A, B, C) of known quantities available (N[A], N[B], N[C]). We know the duration the contest will run, but we do not know how many people will participate in the lottery. This contest logic will be used several times and the prize quantities and duration of the contest may change. Winners should be distributed at random-ish intervals throughout the duration of the contest.
Participants visit a webpage and they are shown if they have won a prize or not and, if so, which prize they have won. How do we choose which participants are winners and which prize the winner has won ?

Since you have no idea how many people will participate, and at what time they will do so, I would suggest you do not allocate prizes to contestants but to moments in time.
Then, whenever such a moment in time occurs, give the prize to the first participant to visit/participate/answer/whatever.
To distribute the prizes over the allotted time, you can start by distributing each prize evenly over the total time (depending on N[x]).
Then offset each timestamp with a random timespan between -T and T, where T is half the time between the prize moments.
If you want to avoid times falling in the night time (meaning in the morning people have a higher chance of winning by logging in early), simply adjust your formula's to skip the "night hours" as possible outcomes.

Related

Which algorithm combines knapsack optimization with the efficiency of job scheduling (to create a points optimizing fantasy basketball lineup)

I'm a fantasy basketball player and there is a recurring problem that I have not been able to figure out, and I can't find a similar enough example online that I can adapt for my own usage. For those who don't know, streaming (in fantasy basketball) is when you have an open spot on your individual team that you cycle available / free agent players through, in an attempt to maximize points, based on when they play during the week.
For example, Player 1 has games on Monday, Tuesday and Wednesday, and P2 plays on Thursday, Friday and Sunday. You keep P1 rostered through Wednesday, then drop them and pick up P2 for the rest of the week. Both players' points are added to your total; this allows you to essentially benefit from having two players' scoring for the week while only using one roster spot.
M
T
W
Th
F
S
S
Avg Pts / Game
P1
x
x
x
20
P2
x
x
x
25
The optimal strategy yields 135 points, vs 60 or 75 from just playing one player for the whole week.
The complexity comes from three places.
Players you want to play sometimes overlap on the same day, and their schedules often overlap in a way such that it might be worth it to start a worse player early in the week if it means you get access to a slate of their games later in the week. A player may have a lower points per game than another player, but by virtue of playing more games it’s worth it to start the player with a lower average.
Players can’t be re-added for the rest of the week once dropped, due to the nature of the fantasy sports platform. So you can’t toggle back and forth between two good players if they have complementary schedules. Related to this, there are a set number of “adds” you can use per week. Without this you could just add 7 different players, one each day, and figure out who was going to be the best for each day of the week. For the purposes of this league, the number of adds is 4 per week.
There are lots of available players. Figuring this out manually sometimes means starting players who are ranked far outside the top 130 (the total number of players across all of the leagues rosters) in Points Per Game, but due to their scheduling quirks, offer the best value for the remainder of the week. Trying each combination of players against each other involves a huge number of potential options.
I am a CS hobbyist, but the things I build do not require these sorts of optimizations, and I haven’t been able to find an example that would solve all parts of this problem.
Take the below schedule, for example. An “x” indicates the player is playing that day:
M
T
W
Th
F
S
S
Avg Pts / Game
P1
x
x
x
x
20
P2
x
x
x
21
P3
x
x
x
22
The points maximizing solution is to start Player 1 Monday, drop them and switch to Player 2 for the next three days, start no one on Thursday (as P1 would not be available after dropping them), and then switch to Player 3 for the last two days.
Start P1: 20 + 63 + 44 = 127
Constraints:
There are a set number of available days (7)
Only one player can be played per day
Each player can only be added one time (but can play consecutive games after being added with no penalty).
You can only add new players a set number of times: “n”
There are “p” possible players, each of whom has days of the week they can be played and an average points per game (same across all days)
The objective is to return the schedule of players in the proper combination that optimizes the total points in a given week.
My (somewhat brief) look through the existing algorithms led me to considering the knapsack problem, optimal scheduling, and greedy. Greedy doesn’t seem to work because it would immediately decide to start Player 3, which would not ultimately lead to the optimal solution, ending up with 125 total points
The scheduling algorithm would seem to require considering the start and end of a “task” as the first and last day a player plays, which creates problems here; Player 1’s “block” or whole week between first and last day would show that Player 1 offers the best total value at 80 points, and that the optimal strategy would be to just play them, but it doesn’t consider prematurely ending the task if something else was available.
Likewise I can’t figure out how to introduce the “switching” element into solutions to the knapsack problem.
There is a related question here but it doesn't include the scheduling aspect: Algorithm to select Player with max points but with a given cost
I feel like there’s a method that I’m not quite grasping, or a simplification that would allow me to use one of the aforementioned solutions. Any help in solving this completely inconsequential problem is greatly appreciated!

Algorithm development and optimization

I have this problem:
You need to develop a meal regime based on the data entered by the user. We have a database with the meals and their prices (meals also have a mark whether they are breakfast, cause on breakfast we eat smth different from lunch and dinner most often). The input receives the amount of money (Currency is not important) and the number of days. At the output, we must get a meal regime for a given number of days. Conditions:
Final price does not differ from the given one by more than 3%.
meals mustn't repeat more than once every 5 days.
I found this not effective solution: We are looking for an average price per day = amount of money / number of days. Then, until we reach the given number of days, we iterate throught each breakfast, then lunch and dinner (3 for loops, 2 are nested) and if price is not too different, then we end the search and add this day to the result list. So the design now looks like this:
while(daysCounter < days){
for(){
for(){
for(){
}
}
It looks scary, although there is not a lot of data (number of meals is about 150). There are thoughts that it is possible to find a more effective solution. Also i think about dynamic programming, but so far there are no ideas how to implement it.
Dynamic programming won't work because a necessary part of your state is the meals from the last 5 days. And the number of possibilities for that are astronomical.
However it is likely that there are many solutions, not just a few. And that it is easy to find a working solution by being greedy. Also that an existing solution can be improved fairly easily.
So I'd solve it like this. Replace days with an array of meals. Take the total you want to spend. Divide it up among your meals, in proportion to the median price of the options for that meal. (Breakfast is generally cheaper than dinner.) And now add up that per meal cost to get running totals.
And now for each meal choose the meal you have not had in the last 5 days that brings the running total of what has been spent as close as possible to the ideal total. Choose all of your meals, one at a time.
This is the greedy approach. Normally, but not always, it will come fairly close to the target.
And now, to a maximum of n tries or until you have the target within 3%, pick a random meal, consider all options that are not eaten within the last or next 5 days, and randomly pick one (if any such options exist) that brings the overall amount spent closer to the target.
(For a meal plan that is likely to vary more over a long period, I'd suggest trying simulated annealing. That will produce more interesting results, but it will also take longer.)

How to Schedule Tasks

There is a carwash that can only service 1 customer at a time. The goal of the car wash is to have as many happy customers as possible by making them wait the least amount of time in the queue. If the customers can be serviced under 15 minutes they are joyful, under an hour they are happy, between 1 hour to 3 hours neutral and 3 hours to 8 hours angry. (The goal is to minimize angry people and maximize happy people). The only caveat to this problem is that each car takes a different amount of time to wash and service so we cannot always serve on first come first serve basis given the goal we have to maximize customer utility. So it may look like this:
Customer Line :
Customer1) Task:6 Minutes (1st arrival)
Customer2) Task:3 Minutes (2nd arrival)
Customer3) Task:9 Minutes (3rd)
Customer4) Task:4 Minutes (4th)
Service Line:
Serve Customer 2, Serve Customer 1, Serve Customer 4, Serve Customer 3.
In this way, no one waited in line for more than 15 minutes before being served. I know I should use some form of priority queue to implement this but I honestly know how should I give priority to different customers. I cannot give priority to customers with the least amount of work needed since they may be the last customer to have arrived for example (others would be very angry) and I cannot just compare based on time since the first guy might have a task that takes the whole day.So how would I compare these customers to each other with the goal of maximizing happiness?
Cheers
This is similar to ordering calls to a call center. It becomes more interesting when you have gold and silver customers. Anyway:
Every car has readyTime (the earliest time it can be washed, so it's arrival time - which might be different for each car) and a dueTime (the moment the customer becomes angry, so 3 hours after readyTime).
Then use a constraint solver (like OptaPlanner) to determine the order of the cars (*). The order of the cars (which is a genuine planning variable) implies the startWashingTime of each car (which is a shadow variable), because in your example, if customer 1 is ordered after customer 2 and if we start at 08:00, we can deduce that customer 1's startWashingTime is 08:03.
Then the endWashingTime is startWashingTime + washingDuration.
Then it's just a matter of adding 2 constraints and let the solver solve() it:
endWashingTime must be lower than dueTime, this is a hard constraint. This is to have no angry customers.
endWashingTime must be lower than startTime plus 15 minutes, this is a soft constraint. This is to maximize happy customers.
(*) This problem is NP-complete or NP-hard because you can relax it to a knapsack problem. In practice this means: you can't write an algorithm for it that scales out and finds the optimal solution in reasonable time. But a constraint solver can get you close.

Even prize distribution

I'm currently facing interesting algorithm problem and I am looking for ideas or possible solutions. Topic seems to be common so maybe it's known and solved but I'm unable to find it.
So lets assume that I'm running shop and
I'm making lottery for buying customers. Each time they buy something they can win prize.
Prizes are given to customers instantly after buying.
I have X prizes and
I will be running lottery for Y days
Paying customer (act of buying, transaction) should have equal chance to win prize
Prizes should be distributed till last day (at last day there should be left some prizes to distribute)
There can not be left prizes at the end
I do not have historical data of transactions per day (no data from before lottery) to estimate average number of transactions (yet lottery could change number of transactions)
I can gather data while lottery is running
It this is not-solvable, what is closest solution?
Instant prize distribution have to stay.
Possible Solution #1
Based on #m69 comment
Lets says there are 6 prizes (total prizes) and 2 days of lottery.
Lets define Prizes By Day as PBD (to satisfy requirement have prizes till last day).
PBD = total prizes / days
We randomly choose as many as PBD events every day. Every transaction after this event is winning transaction.
Can be optimized to no to use last hour of last day of lottery to guarantee giving away all of prizes.
Pluses
Random. Simple, elegant solution.
Minuses
Seems that users have no equal chance to win.
Possible Solution #2
Based on #Sorin answer
We start to analyze first time frame (example 1 hour). And we calculate chance to win as:
where:
Δprizes = left prizes,
Δframes = left frames
What you're trying to do is impossible. Once you've gave away the last prize you can't prove any guarantee for the number of customers left, so not all customers will have equal chance to win a prize.
You can do something that approximates it fairly well. You can try to estimate the number of customers you will have, assume that they are evenly distributed and then spread the prizes over the period while the contest is running. This will give you a ratio that you can use to say if a given customer is a winner. Then as the contest progresses, change the estimates to match what you see, and what prizes are left. Run this update every x (hours/ minutes or even customer transaction) to make sure the rate isn't too low and every q prizes to make sure the rate isn't too high. Don't run the update too often if the prizes are given away or the algorithm might react too strongly if there's a period with low traffic (say overnight).
Let me give you an example. Say you figure out that you're going to see 100 customers per hour and you should give prizes every 200 customers. So roughly 1 every 2 hours. After 3 hours you come back and you see you saw 300 customers per hour and you've given out 4 prizes already. So you can now adjust the expectation to 300 customers per hour and adjust the distribution rate to match what is left.
This will work even if your initial is too low or too high.
This will break badly if your estimate is too far AND you updates are far in between (say you only check after a day but you've already given away all the prizes).
This can leave prizes on the table. If you don't want that you can reduce the amount of time the program considers the contest as running so that it should finish the prizes before the end of the contest. You can limit the number of prizes awarded in a given day to make the distribution more uniform (don't set it to X/Y, but something like X/Y * .25 so that there's some variation), and update the limit at the end of the day to account for variation in awards given.

Best Fit Scheduling Algorithm for Accommodation / Day Pass Problem?

I have a scheduling problem I'm trying to figure out a best fit algorithm to use.
A hotel owns a theme park and is a highlight for visitors staying at the hotel. However, the hotel has more rooms than day passes for visitors wanting to go to the theme park. So during the peak months, there is a possibility that some will not get to go to the theme park.
We want to have every visitor given at least 1 chance to visit the theme park.
If there is contention, we would want to favour giving the day pass to visitors who stay longer at the hotel.
Can anyone point me in the right direction on which algorithm will fit the problem best?
No this is not homework. :)
Thanks in advance.
You can use Priority Queue (PQ). Every day you put customers in your (PQ) computing the priority as p = 1/r where r is the number of remaining days for that guest in your hotel. In this way, every day you give away your n passes to the n customers who have fewer days to stay at your hotel (if a customer has just 1 more day to stay, she/he must have the highest priority in getting the pass, because there just one possibility). If you have several customers with equal p then you choose among them by looking at the total number of days that they stay at your hotel, and you favour those customers staying longer.
You can assign each guest a weight, or priority, according to length of stay (and maybe the number of days the guy's been a guest already without a pass) and then sort the guests by priority. Then it should be easy to give out passes just starting at the top of the sorted list.
You can use a priority queue for this. The priority queue has to be arranged based on the number of chances and number of days the visitors are staying.

Resources