Minimum number of calls to be made? - algorithm

There are 'n' number of detectives..each one knows an information, how many minimum calls should they make so all the detectives know all the n number of information ?
My answer: I came up with 2n-3 (that is, n-1 + n-2) solution where a detective calls n-1 other detectives and shares information mutually (in this way the last detective and the first has all the information). Then the remaining n-2 detectives who doesn't have the whole data calls either the first detective or the last to gain the remaining information.
(This is a question asked by my friend).

2n-3 is not correct.
Consider the case of n=4, 2n-3 would predict that 2*4-3=5 calls are needed.
However, we can do it in 4 calls via:
A calls B
C calls D
A calls C
B calls D

Related

How to minimise sum of 4 different people's scores, each in distinct disciplines

In a swimming contest, there are 4 types of different strokes. Each contestant participates in all of them and their completion times are recorded. From all the contestants, four have to be chosen such that their combined time is minimum(one contestant can be chosen for only one stroke). More than one such team may be possible and all of such teams must be printed in output.
For example, say there are four contestants A, B, C and D. Their completion times are
A 50.5 52.9 51.8 52.7
B 50.7 52.7 51.4 52.7
C 50.7 52.7 51.4 52.8
D 50.8 52.9 51.6 52.6
Here, the minimum time would be (A - 50.5, C - 52.7, B - 51.4, D - 52.6) and (A - 50.5, B - 52.7, C - 51.4, D - 52.6).
I don't have any test cases for this. I can do it using brute force but that would take O(n^4). What would be a better approach?
There's no point in taking the fifth or worse best time in a stroke: one of the top four is available regardless of how we want to assign the other three strokes. Take the top four candidates in each stroke and then filter the 4*4*4*4 = 256 possibilities to make sure that the assignments are unique.
O(n) (assuming that the number of races is constant).
Since you need all of the solutions, there's no way to get an O(n)-time solutions, since there may be exponentially many of them. You can enumerate them efficiently using the algorithm above, however. In your brute-force algorithm, insert a test that uses the above logic to determine whether the partial assignment being considered can be extended to an optimal solution. The running time is O(n + s), where s is the number of optimal solutions.

Determining the number of steps in an algorithm

I was going through my Data Structures and Algorithms notes, and came across the following examples regarding Time Complexity and Big-O Notation: The columns on the left count the number of operations carried out in each line. I didn't understand why almost all the lines in the first example have a multiple of 2 in front of them, whereas the other two examples don't. Obviously this doesn't affect the resulting O(n), but I would still like to know where the 2 came form.
I can only find one explanation for this: the sloppiness of the author of the slides.
In a proper analysis one have to explain what kind of operations are performed at which time for what input (like for example this book on page 21). Without this you can not even be sure whether we count multiplication of 2 numbers as 1 operation or 2 or something else?
These slides are inconsistent. For example:
In slide1 currentMax = A[0] takes 2 operations. Kind of makes sense if you take finding 0-th element in array as 1 operation and assigning as another one. But in the slide3 n iterations of s = s + X[i] takes n operations. Which means that s = s + X[i] takes 1 operation. Also kind of makes sense we just increase one counter.
But it is totally inconsistent with each other, because it doesn't makes sense that a = X[0] is 2 operations, and a = a + X[0] where you do more takes only 1.

Algorithm determining the smallest coprime subset

Given a set A of n positive integers, determine a non-empty subset B
consisting of as few elements as possible such that their GCD is 1 and output its size.
For example: 5 6 10 12 15 18
yields an output of "3", while:
5 2 4 6 8 10
equals "NONE" since no subset can be determined.
So it seems really basic but I'm still stuck with it. My thoughts on it are as follows: we know that having the multiples of some number already present in the set are useless since their divisors are the same times some factor k and we're going for the smallest subsest. Hence, for every ni, we remove any kni where k is a positive int from further calculations.
That's where I get stuck, though. What should I do next? I can only think of a dumb, brute force approach of trying if there is already some 2-element subset, then 3-elem and so on. What should I check to determine it in some more clever way?
Suppose for each A,B (two elements) we calculate their greatest common
divisor D. And then we store these D values somewhere as a map of the form:
A,B -> D
Let's say we also store the reverse map
D -> A,B
If there's at least one D=1 then there we go - the answer is 2.
Suppose now, there's no such D that D=1.
What condition should be met for the answer to be 3?
I think this one:
there exist two D values say D1 and D2 such that GCD(D1, D2)=1.
Right?
So now instead of As and Bs, we've transformed our problem to the
same problem over the set of all Ds and we've transformed the option of
a the 2 answer to the option a 3 answer. Right?
I am not 100% sure just thinking out loud.
But this transformed problem is even worse as
we have to store much more values.
(combinations of N elements class 2).
Not sure, this problem you pose seems like a hard
problem to me. I would be surprised if there exists
a better approach than brute-force
and would be interested to know it.
What you need to think on (and look for) is this:
is there a way to express GCD(a1, a2, ... aN)
if you know their pair-wise GCDs. If there's some
sort of method or formula you can simplify a bit
your search (for the smallest subset matching
the desired criterion).
See also this link. Maybe it could help.
https://cs.stackexchange.com/questions/10249/finding-the-size-of-the-smallest-subset-with-gcd-1
The problem is definitely a tough one to solve. I can't see any computationally efficient algorithm that would guaranteed find the solution in reasonable time.
One approach is:
Form a list of ordered sets that would contain the prime factors of each element in the original set.
Now you need to find the minimum number of sets for which their intersection is zero.
To do that, first order these sets in your list so that the sets that have least number of intersections with other sets are towards the beginning. Now what are "least number of intersections"?
This is where heuristics come into play. It can be:
1. set having Less of MIN number of intersections with other elements.
2. set having Less of MAX number of intersections with other elements.
3. Any other more suitable definition.
Now you will need to expensively iterate through all the combinations maybe through recursion to determine the solution.

Algorithm for expressing reordering, as minimum number of object moves

This problem arises in synchronization of arrays (ordered sets) of objects.
Specifically, consider an array of items, synchronized to another computer. The user moves one or more objects, thus reordering the array, behind my back. When my program wakes up, I see the new order, and I know the old order. I must transmit the changes to the other computer, reproducing the new order there. Here's an example:
index 0 1 2
old order A B C
new order C A B
Define a move as moving a given object to a given new index. The problem is to express the reordering by transmitting a minimum number of moves across a communication link, such that the other end can infer the remaining moves by taking the unmoved objects in the old order and moving them into as-yet unused indexes in the new order, starting with the lowest index and going up. This method of transmission would be very efficient in cases where a small number of objects are moved within a large array, displacing a large number of objects.
Hang on. Let's continue the example. We have
CANDIDATE 1
Move A to index 1
Move B to index 2
Infer moving C to index 0 (the only place it can go)
Note that the first two moves are required to be transmitted. If we don't transmit Move B to index 2, B will be inferred to index 0, and we'll end up with B A C, which is wrong. We need to transmit two moves. Let's see if we can do better…
CANDIDATE 2
Move C to index 0
Infer moving A to index 1 (the first available index)
Infer moving B to index 2 (the next available index)
In this case, we get the correct answer, C A B, transmitting only one move, Move C to index 0. Candidate 2 is therefore better than Candidate 1. There are four more candidates, but since it's obvious that at least one move is needed to do anything, we can stop now and declare Candidate 2 to be the winner.
I think I can do this by brute forcibly trying all possible candidates, but for an array of N items there are N! (N factorial) possible candidates, and even if I am smart enough to truncate unnecessary searches as in the example, things might still get pretty costly in a typical array which may contain hundreds of objects.
The solution of just transmitting the whole order is not acceptable, because, for compatibility, I need to emulate the transmissions of another program.
If someone could just write down the answer that would be great, but advice to go read Chapter N of computer science textbook XXX would be quite acceptable. I don't know those books because, I'm, hey, only an electrical engineer.
Thanks!
Jerry Krinock
I think that the problem is reducible to Longest common subsequence problem, just find this common subsequence and transmit the moves that are not belonging to it. There is no prove of optimality, just my intuition, so I might be wrong. Even if I'm wrong, that may be a good starting point to some more fancy algorithm.
Information theory based approach
First, have a bit series such that 0 corresponds to 'regular order' and 11 corresponds to 'irregular entry'. Whenever there in irregular entry also add the original location of the entry that is next.
Eg. Assume original order of ABCDE for the following cases
ABDEC: 001 3 01 2
BCDEA: 1 1 0001 0
Now, if the probability of making a 'move' is p, this method requires roughly n + n*p*log(n) bits.
Note that if p is small the number of 0s is going to be high. You can further compress the result to:
n*(p*log(1/p) + (1-p)*log(1/(1-p))) + n*p*log(n) bits

Understanding the AStar Algorithm

From this link: Link
If an adjacent square is already on the open list, check to see if
this path to that square is a better one. In other words, check to see
if the G score for that square is lower if we use the current square
to get there. If not, don’t do anything.
Example:
parent (already traversed): O
branches: A, B, C
parent (working on): A
Branches: B, D
The open list contains, A, B, C and now D.
Now, the bold statements in the above quote are comparing which path with, path A to B?
i.e.
Comparison of A to B && O to B
OR
Comparison of A to B && A to D
Please clarify.
Basic A* is:
While we're not close enough to the / a destination
Take the point that we have now, with the lowest expected total cost (so known cost up to this point plus estimated remaining cost).
Calculate cost for all surrounding locations & add them back to the priority queue with their expected total cost.
return route that we followed to the closest point
In the official A* terminology, G-score is the cost to get there. H-score is the estimate to get from there to where you want to go.
Extremes are if your H-score always overestimates; the new score (estimate + new cost) will then always be lower than the previous square's estimate + cost, so you'll beeline to the target. If your H-score always underestimates (or is 0, or whatever) you'll always prefer squares closer to your point of departure, as they'll have a lower cost so far, so you'll basically floodfill from that position.
You can use A* from a theoretical point of view or from a practical point of view. Theoretically, you may never overestimate the cost of any link. That means that you will always find the most efficient route, but will take longer finding it as you'll expand a lot more nodes.
Using it from the practical point of view allows slightly-inadmissible heuristics (ones that can overestimate slightly). The route you find will most likely be slightly unoptimal but shouldn't be too bad for game use. The calculations get way faster though, since you don't expand everything anymore. One (slow) implementation I had made took 6 minutes across a 1k*1k map with a regular trig distance heuristic but only a few seconds with that augmented times 3. The routes weren't too different. Making the heuristic times 5 made the routes basically a beeline & much faster still, but unusably so.
WRT your direct question:
It's the second square you evaluate. You have the roads from O to A,B,C planned (with a given cost G for each of those routes). Now, suppose there's a highway from O through A to B, instead of a dirt road from O to B. That means that going through A is faster. When expanding A it looks at all surrounding squares and adds the cost + heuristic to the open list if it wasn't in there already. If it was in there, it sees if the new route is faster (lower G to get to that square) and only if so, does it replace it.
So in your example, it adds O->A->D to the list and then checks if O->A->B is faster than O->B.
-- addendum
Open list: 2 / A (through O), 5 / B (through O), 7 / C (through O)
Closed list: 0 / O (origin / through nothing)
Take A as it's the lowest cost so far. Then, for each neighbor of A calculate the cost to get there.
If there's an entry for it already and the cost is lower than we know so far, replace the entry.
If there's no current entry, add it.
Working on A, with roads of cost 2 to B and 3 to D. Going to B through A has a cost of 4, where the current entry is 5. So we replace it. D isn't in there, so we add it.
Open list: 4 / B (through A), 5 / D (through A), 7 / C (through O)
Closed list: 0 / O (origin / through nothing), 2 / A (through O)
So we compared A to B versus O to B.
Well, if we are working on the node A, we are considering its neighbours. Say we are considering the B node now (which is in the openList).
The definition given tells us to compare the G value of B (previously computed when it was first added to open list when the working node was O) and the sum of the cost of reaching A from the begining (O) and the cost of reaching B from A.

Resources