understanding lotto program logic by skiena - algorithm

I am reading article from following location. Here is text snippet form document.
Link
The problem of finding a minimum set of tickets that will guarantee a
win is not a trivial one. Given that P out of R outcomes will be from
the fortune-teller set, it is not difficult to see that there are NCP
= (N/P!)/(N-P)! possible P-subsets from the fortune-teller set that can occur in the winning ticket. If we were to pick all P-subsets from
the fortune-teller set W times and fill in the remaining R-P slots
arbitrarily, the set of tickets obtained will have at least W
occurrences of each P-subset and guarantee us W wins. However, such a
set need not be a minimal one and in most cases is not.
We know from the fortune-teller’s promise that one of the P-subsets
will occur in the winning ticket. It is possible for two P-subsets to
differ by less than J numbers. When such a situation arises, the
subsets are said to overlap or cover one another with respect to the
shared J numbers and only one of the P-subsets must be in a purchased
ticket. This phenomenon is best illustrated using an example. Suppose
we are playing the PICK-4 Lotto and require one 2/4 win. Hence R=4,
J=2 and W=1. Furthermore let’s assume that the fortune-teller predicts
3 numbers from a set of 5 numbers ( i.e. P=3 and N=5 ). If all
P-subsets were taken from the fortune-teller set and arbitrarily
filled to complete the tickets, we would have a set of ten tickets
that guarantees one 2/4 win ( See Figure 1 ). However, it is also
possible to exclude some tickets from this set because of several
two-number overlaps. For instance the subset {3, 4, 5} is different
than {1, 3, 5} by only one number and it will be wasteful to use both
of these in purchased tickets. We might think that not including {3,
4, 5} will permit the possibility of losing, but that is not the case
since if {3, 4, 5}occurs we will have ‘3’ and ‘5’ in {1, 3, 5}that we
bought to claim the prize! Similarly there can be many more redundant
P-subsets. An optimal solution is shown in Figure 2. Our lottery
problem is that of finding the smallest set of P-subsets from the
fortune-teller set that guarantees the specified number of wins by
keeping the number of overlaps to a minimum. This set of P-subsets
defines the winning set regardless of what numbers are used to
complete the R slots on the ticket.
My question are followiong
As author metioned "If all P-subsets were taken from the fortune-teller set and arbitrarily filled to complete the tickets, we would have a set of ten tickets" As in article table is missing can any one help me here what are the 10 tickets?
In above example if 1 and 3 occurs and if we didn't select {1, 3, 5} how can we win here?
Can anyone come up with fig 2 which is missing in article?
thank!

Here is an inefficent list of 10 tickets
{1, 2, 3, 6}
{1, 2, 4, 6}
{1, 2, 5, 6}
{1, 3, 4, 6}
{1, 3, 5, 6}
{1, 4, 5, 6}
{2, 3, 4, 6}
{2, 3, 5, 6}
{2, 4, 5, 6}
{3, 4, 5, 6}
Mu. To win we need to match 2 out of 4. So it isn't the case that 1 and 3 occurs, it is the case that a specific set of 3 occurs and we only need to match 2 of them.
I think this is optimal.
{1, 2, 3, 4}
But I'm not entirely positive that I can pick 4. If I am only allowed to pick 3 per ticket then an optimal set would be:
{1, 2, 3}
{2, 3, 4}

The two tickets are:
{ 1, 3, 5, X }
{ 2, 4, 5, X }
where X is an arbitrarily chosen number which does not affect the solution.

Related

Scattered indices in MPI

I'm trying to divide up an array between processors such that each one takes points from different parts in the array. For example, if
A = {1, 2, 3, 4, 5, 6, 7, 8}
and I'm using 2 processors, I want P1 to handle {1, 3, 5, 7}, and P2 to handle {2, 4, 6, 8}.
When scaling up to very large numbers of points (millions) and processors (128), this is tricky. In previous versions of my function, I simply gave P1 the first chunk of points, P2 the next chunk, and so on (which is easy with MPI_gatherv).
Is there some way to use MPI_gatherv to make this work, or a way to use MPI_send and MPI_receive to achieve it? The trouble with MPI_gatherv is that while you can specify indices for processors to send to, it still puts all of P1 before P2 before P3 etc.

Finding a group of subsets that does not overlap

I am reviewing for an upcoming programming contest and was working on the following problem:
Given a list of integers, an integer t, an integer r, and an integer p, determine if the list contains t sets of 3, r runs of 3, and p pairs of numbers. For each of these subsets, the numbers must be adjacent and any given number can only exist in one subset, if any at all.
Currently, I am solving the problem by simply finding all sets of 3, runs of 3, and pairs and then checking all permutations until finding one which has no overlapping subsets. This seems inefficient, however, and I was wondering if there was a better solution to the problem.
Here are two examples of the problem:
{1, 1, 1, 2, 3, 4, 4, 4, 5, 5, 1, 0}, t = 1, r = 1, p = 2.
This works because we have the triple {4 4 4}, the run {1 2 3}, and the pairs {1 1} and {5 5}
{1, 1, 1, 2, 3, 3}, t = 1, r = 1, p = 1
This does not work because the only triple is {1 1 1} and the only run is {1 2 3} and the two overlap (They share a 1).
I am looking for a more efficient approach to this problem.
There is probably a faster way, but you can solve this with dynamic programming. Compute a recursive function F(t,r,p,n) which decides whether it is possible to have t triples, r runs, and p pairs in the sequence starting at position 1 and ending at n, and storing the last subset of the solution ending at position n if it is possible. If you can have a triple, run, or pair ending at position n then you have a recursive case, either. F(t-1,r,p,n-3) or F(t,r-1,p,n-3) or F(t,r,p-1,n-2), and you have the last subset stored, or otherwise you have a recursive case F(t,r,p,n-1). This looks like fourth power complexity but it really isn't, because the value of n is always decreasing so the complexity is actually O(n + TRP), where T is the total desired number of triples, R is the total desired number of runs, and P is the total desired number of pairs. So O(n^3) in the worst case.

Split set of numbers into as fewest subsets as possible of defined "interval length" algorithm

consider that I have some set of numbers. For example {1, 2, 3, 7, 8, 9, 11, 15, 16}. What I need is to split this set into as fewest subsets as possible and also difference between the lowest and highest number is less than 9.
From my example set it would be for example:
{1, 2, 3, 7, 8}, {9, 11, 15, 16}
I need this to optimize the number of "read multiple registers" requests through the Modbus.
I already tried to split set into subsets with consecutive numbers and than merged them, but it's not ideal, because it returns me this:
{1, 2, 3}, {7, 8, 9, 11}, {15, 16} or {1, 2, 3}, {7, 8, 9}, {11, 15, 16}
As you can see this approach gives me three subsets instead of two.
So is there any usable algorithm?
Thanks
What about the greedy approach, i.e. insert elements from the left into a set, when you go over the desired difference, create a new set.
So, for 1, 2, 3, 7, 8, 9, 11, 15, 16:
You'd start off with 1.
2-1 = 1 < 9, so add 2.
3-1 = 2 < 9, so add 3.
7-1 = 6 < 9, so add 7.
8-1 = 7 < 9, so add 8.
9-1 = 8 < 9, so add 9.
11-1 = 10 > 9, so create a new set.
15-11 = 4 < 9, so add 15.
16-11 = 5 < 9, so add 16.
Output: {1, 2, 3, 7, 8, 9}, {11, 15, 16}.
Note:
If the elements aren't necessarily ordered, we can simply sort them first.
If these subsets don't have to be continuous, it doesn't make a difference, as selecting continuous sets from the ordered input is always better than non-continuous sets.
If the elements aren't necessarily ordered and the subsets must be continuous, that will change the problem a bit.
Proof of optimality:
Let S be the set assignment produced by this algorithm for some arbitrary input.
Take any set assignment T.
Let Si be the i-th set of S.
Let Ti be the i-th set of T.
Let Si-size be the size of the i-th set of S.
Let Ti-size be the size of the i-th set of T.
Assume S and T are different, then for some Si and Ti, Si-size != Ti-size. Specifically choose the first set i where the two differ.
So either Si-size > Ti-size or Si-size < Ti-size.
j > i is impossible, since this algorithm takes as many elements as possible from the start.
If j < i, the first element of Si+1 will be greater than the first element of Ti+1, and since the algorithm is greedy, Si+1 will include at least all the elements of Ti+1 not already included by Si.
Now, because of the above, the first element of Si+2 will similarly be greater than the first element of Ti+2, thus Si+2 will include at least all the elements of Ti+2 not already included by previous sets of S. Similarly for the rest of the sets of S and T. Thus there are at least as many sets in T as there are in S.
Thus the set assignment produced by this algorithm can't be any worse than any other assignment. Thus it is optimal.

equal value = equal rank

I would like to rank the elements of a list such that elements that have the same value also get the same rank:
list = {1, 2, 3, 4, 4, 5}
desired output:
ranks = {5, 4, 3, 2, 2, 1}
Ordering[] does almost what I want but assigns different ranks to the two instances of 4 in the list.
I am not sure that I cover everything you have in mind, but the following code will give the desired output. It presupposes that the smallest value is the highest rank, and should work with numerical values or as long as you are ok with the standard sorting order of Mathematica. The local variable dv is a shortname for "distinct values".
FromListToRanks[k_List]:= Module[ {dv=Reverse[Union[k]]},
k /. Thread[dv -> Range[Length[dv]]] ]
FromListToRanks[list]
{5,4,3,2,2,1}

Mathematica, maximize element extraction from list

I think this is a simple question for mathematica experts.
How can I maximize the extracted value from a list given a index that has to respect some constrains?
For example:
S = {4,2,3,5}
Maximize[{Extract[S,x], x<= 3, x>=1},{x}]
I would like 4 is returned instead of this error:
Extract::psl: "Position specification x in Extract[{4,2,3,5},x] is not an integer or a list of integers."
Does someone know like solve this?
Thanks a lot.
Thanks a lot!! The last approach shown is what I was looking for but applied to my real problem does not work.
I have the following problem:
I have to maximize the satisfaction of an employee with respect to a certain shift in an certain day of a month.
I have the matrix satisfaction (Employees,shifts) and is something like this:
S= {{4,3,5,2},{3,4,5,1}}
Each element represents the satisfaction of an employee with respect to a certain shift so employee 1 has satisfaction 4 with respect shift 1.
My model has to choose the right shift for all month days in order to maximize the employee satisfaction by respecting certain constraints.
My greatest problem is relate satisfaction matrix with chosen shift.
I am not able to use in method NMaximize a function that takes the chosen shifts and employee and returns the satisfaction and so doing a summation over all month days.
I need to maximize something like this:
Summation(from j=1 to j=31) getSatisfaction[1,chosenShift for that day)
Do you know how can I write this in mathematica?
I am struggling to this problem for several days but I am not able to solve this problem.
I need the input to relate chosen shift with satisfaction matrix.
Thanks a lot!!
If you don't need to find the value of x then I suggest you merely extract the acceptable range of the list and then find the Max of that:
s = {4,2,3,5};
s[[1 ;; 3]] // Max
4
If you have particularly hairy constraints then you may need something like Pick:
list = {5, 7, 1, 9, 3, 6, 2, 8, 4};
Pick[list, Range#Length#list, x_ /; x <= 7 && x >= 3 && Mod[7, x] == 1]
{1, 6}
You can then use Max on the returned list.
For completeness, if you need the value of x or other details from the process, here is an approach:
list = {6, 5, 7, 3, 4, 2, 1, 8, 9};
pos = Cases[Range#Length#list, x_ /; x <= 7 && x >= 3 && Mod[7, x] == 1]
values = Part[list, pos]
maxpos = Part[pos, Ordering[values, -1]]
{3, 6}
{7, 2}
{3}
Answering your updated question:
If you have:
shifts = {{4, 3, 5, 2}, {3, 4, 5, 1}, {4, 3, 5, 2}}
Then
(Tally /# Transpose#shifts)[[All, 1, 1]]
gives you:
{4, 3, 5, 2}
Which i a list with the preferred shift for each employee.

Resources