I've recently gotten back into learning about discrete math. I enrolled in a course at university and am having trouble getting the hang of things again, especially when it comes to deriving a recurrence relation from a word problem. I would love to have some tips on how to do so.
For example (I've changed numbers from the homework question so if this doesn't work out just let me know): if Jean divides an input of size n into three subsets each of size n/5 and combines them in theta(n) time, what is the runtime? I got 3T(n/5) + theta(n) as the recurrence relation and I have no idea what the runtime is, and I feel like those are both incorrect.
I found this site (https://users.cs.duke.edu/~ola/ap/recurrence.html) to be helpful for breaking down a recurrence relation into a solid runtime, but I still don't get how to get the recurrence relation from the word problem in the first place. Thanks!
Think of such problems as tree structure with nodes on each level.Each node will contain a number the size of problem that you are dealing at a particular time and at each level you will have some nodes. This number could be 1,2,.......upto maximum n nodes at each level.
Now start from top level. You will have 1 node and the value in it will be 'n'(because at starting point we will have 'n' elements to deal with).
Now coming down to second level. In the above question says divide the problem(elements) in three parts at any point of time, so number of nodes on level 2 will be 3. The value in each node will be 'n/5'(because question says size of each subset is number of elements which were present on parent node divide by 5).Tree will look like:-
(n)
| | |
(n/5)(n/5) (n/5)
Now going further down to 3rd level, tree will look like
(n) level(1)
| | |
(n/5) (n/5) (n/5) level(2)
| | | | | | | | |
(n/25)(n/25)(n/25) (n/25)(n/25)(n/25) (n/25)(n/25)(n/25) level(3)
you will go on till the last level which will contain only 1 element and total number of nodes will be 'n'.
So, if you need to write the recursion just see level 1 and level 2.
Time taken to solve problem with 'n1' element is written as T(n1).
Time taken to solve problem with 'n2' element is written as T(n2).
Now number of elements in level 1 is n1=n
(Time taken to solve problem on first level)=(Time taken to solve 1st
node of level 2)+(Time taken to solve 2nd node of level 2)+(Time taken
to solve last node of level 2) + (It also takes time to combine these
three nodes given in question i.e. theta(number of total elements(n))
T(n)=T(n/5)+T(n/5)+T(n/5)+theta(n)
=>T(n)=3T(n/5)+theta(n)
Related
I am attempting to create an algorithm that pairs mentees with a different group of 1-4 mentors in each "round" of mentoring.
The algorithm would accept 3 inputs:
The number of mentees - an integer between 1 and 35
The number of mentors - Always greater than or equal to the number of mentees, but never greater than 35
The number of rounds of mentoring to perform
Given these three inputs, the algorithm would match each mentee with 1-4 mentors, with the following restrictions:
If it is possible to do so with the given inputs, a mentee must never be paired with the same mentor more than once
If it is possible to do so with the given inputs, a mentor must never be in the same group of mentors as another mentor more than once
Note: The algorithm does NOT have to assign mentors to mentees randomly. The code can give the same output each time it is run with the same set of inputs.
Here is an example of the output of a successful algorithm with 2 rounds, 4 mentees, and 11 mentors:
| Round
| Mentee | 1 | 2 |
| 1 | 1, 2, 3| 4, 7, 10|
| 2 | 4, 5, 6| 1, 8, 11|
| 3 | 7, 8, 9| 2, 5 |
| 4 |10, 11 | 3, 6, 9 |
Please let me know if you have any questions, or if what I am asking for is in fact impossible. Thank you very much for your time and assistance, and have a great day.
Sincerely,
Tyrovar
Interesting problem!
It's unlikely that it has a fast solution, unfortunately, because it's related to some long-standing combinatorial problems that don't have efficient constructive solutions I'm aware of.
You can think of the problem in two parts: (1) deciding the groups of mentors for each round, and then (2) pairing these groups with mentees.
Call n the number of mentors and m <= n the number of mentees. And assume m evenly divides n. (If not, you could just add m - (n mod m) "fake" mentors, i.e. empty chairs.)
Then just the first part (1) to figure out the groups of mentors in each round, is equivalent (with sufficiently many rounds) to finding a S(2, n/m, n) Steiner Triple System. There has been a good deal of research on these combinatorial objects, and some algorithms published, but to my knowledge none of them will be fast or even polynomial-time.
However, for reasonable parameter sizes, you could hope to generate the groups of mentors with a greedy algorithm approach: For each mentor, keep track (in a set data structure) of which other mentors that mentor has been in groups with already. For each round, start making groups of mentors that haven't been in groups with each other yet, and then add those group members to each list. If this fails, however, you may have to resort to a brute-force approach to find the groups.
Once you have the groups of mentors, pairing them with the mentees in each round becomes an instance of the bipartite perfect matching problem, to which there are a few reasonably efficient solutions, including the Hopcroft-Karp algorithm. Again, you would want to keep track of which mentors each mentee has seen, and update these in each round.
So in general, the approach I would suggest is:
Create a set of mentors for every mentor and for every mentee, initially empty.
Greedily select m/n groups of n mentors each that have not been in the same group before. If you get "stuck", resort to a brute-force search over all possible groupings until you find a suitable one.
Create a bipartite graph, with one vertex for each mentee, one vertex for each group of mentors in the current round, and an edge between them if none of the mentors in the group has seen that mentee yet.
Find a maximum matching in that graph - this is the pairings of mentors to mentees for the current round.
Repeat Steps 2-4 for the remaining rounds.
You might also want to look at the Kirkman's Schoolgirl's Problem, which is closely related to what you are asking and a good, simple illustration of why it's difficult in general to solve.
I'm currently facing an algorithmic problem were I could need some hints from you.
Here the problems details:
Given are n numbers of FIFOs with a capacity of k. There are also sixteen different elements. Now we fill those FIFOs with a random amount of different
random elements. The task is to remove a given random amount of random elements from the FIFOs. It is possible that there is no optimal solution caused by other blocking elements (rotating the FIFO isn't allowed).
The best solution is the one which removes all or most elements (so there are more possible solutions).
Well here is an visualized example of three FIFOs (seperated by | ) and three elements (a, b and c):
1 | 2 | 3
---+---+---
. | b | c <- last elements
. | b | a
a | a | b <- first elements
I hope you now know what problem I'm facing. (please feel free to ask if there is anything unintelligible)
Here is my idea of an algorithm:
Treat each FIFO seperately and check on how much elements possibly could get removed. (This step is necessary to remove the problems size in the following step)
Try each possible combination to remove the elements.
Stop if there is a perfect combination which removes each element else remember the best combination (which is the one that removes the most elements).
So the worst case has a complexity of O(n^k) which is obviously horrible! I'd really appreciate any idea to reduce the complexity.
I am implementing Karger's algorithm. From what I understand, the number of edges between the final two nodes is not always the Min Cut. What I am having trouble understanding is how do I actually get the min cut from this algorithm. I keep finding a lot of stuff on probabilities, but it all looks like gibberish to me...
From what I have read, I think I need to run Karger's algorithm multiple times on a graph. This will give me a high probability of success of hitting the min cut. I think?...
Can someone please explain this in a simpler way? How do I find the number of times to run this algorithm? Is what I have said above even correct?
Each time you run Karger's algorithm, it will give you a (semi-random) cut. The probability that that cut is the minimum cut is P = 1 / (n^2/2 - n/2), which is much better than just picking a cut completely randomly.
If you run the algorithm once, your probability of getting the min cut is P, but your probability of not getting it is 1 - P. If you run the algorithm twice, then your chances of not getting the min cut is (1 - P) * (1 - P), since you would have to miss the min cut the first time, and the second time.
That's quite a bit better. Running the algorithm twice gives us a higher likelihood of finding the min cut.
If we run the algorithm T times, then the probability of not getting the min cut is (1 - P)^T, which means that the probability of getting the min cut is 1 - (1 - P)^T.
At this point, you ask yourself how badly you want the right solution. Make up some probability (1 in 1,000,000?), and solve for T. That's how many times you should run the algorithm.
It's common to set T = C * (n choose 2) * ln(n), since that gives you less than a (1 / n)^C chance of not finding the min cut, which is a much easier formula to reason about, especially if you set C to 1. Then, you have a lower chance of getting an incorrect cut than you do of randomly picking a single node of your graph. That's pretty good if your graph is big.
In summary, choose C based on how necessary it is to get the right answer. If you don't know how necessary it is, then C = 1 is a good guess, and just run your algorithm (n choose 2) * ln(n) times.
(Most of this math is taken from the wikipedia page. You can find more details there)
I am learning about algo complexity and calculating time complexity. the question is
What is the time complexity of the best case to insert a new node into a
minimum-level BST with n nodes? Explain. (Hint: You may draw a diagram as part of your
solution.)
Can you please explain in details how you would solve this question and similar questions?
my attempt:
for time complexity we have 2 questions, how many times and what does it cost.
How many times:
there will be one element to check so => O(1)
how much does it cost?
how many times?
now I am stuck here (pretty early), I am assuming that since its a tree, there will be n/2 elements after the first comparison and it keeps splitting into half.
Consider the following minimum-height BST (any binary tree with 8 nodes has at least 4 levels, thus it has the minimum height).
8
/
4
/ \
2 6
/ \ / \
1 3 5 7
Now let's say you insert the value 9, it will go straight to the right side of the root.
To generalize this example: a BST which has a right child or left child which are complete trees- is a minimum height BST. If the other side is empty, any value that you'll insert which will be greater\lesser to the node will be added directly to the root's right\left child. in this case the insert will take O(1) time.
I have encoutered an algorithm question:
Fully Connection
Given n cities which spreads along a line, let Xi be the position of city i and Pi be its population.
Now we begin to lay cables between every two of the cities based on their distance and population. Given two cities i and j, the cost to lay cable between them is |Xi-Xj|*max(Pi,Pj). How much does it cost to lay all the cables?
For example, given:
i Xi Pi
- -- --
1 1 4
2 2 5
3 3 6
Then the total cost can be calculated as:
i j |Xi-Xj| max(Pi, Pj) Segment Cost
- - ------ ----------- ------------
1 2 1 5 5
2 3 1 6 6
1 3 2 6 12
So that the total cost is 5+6+12 = 23.
While this can clearly be done in O(n2) time, can it be done in asymptotically less time?
I can think of faster solution. If I am not wrong it goes to O(n*logn). Now let's first sort all the cities according to Pi. This is O(n* log n). Then we start processing the cities in increasing order of Pi. the reason being - you always know you have max (Pi, Pj) = Pi in this case. We only want to add all the segments that come from relations with Pi. Those that will connect with larger indexes will be counted when they will be processed.
Now the thing I was able to think of was to use several index trees in order to reduce the complexity of the algorithm. First index tree is counting the number of nodes and can process queries of the kind: how many nodes are to the right of xi in logarithmic time. Lets call this number NR. The second index tree can process queries of the kind: what is the sum of distances from all the points to the right of a given x. The distances are counted towards a fixed point that is guaranteed to be to the right of the rightmost point, lets call its x XR.Lets call this number SUMD. Then the sum of the distances to all points to the right of our point can be found that way: NR * dist(Xi, XR) - SUMD. Then all these contribute (NR * dist(Xi, XR) - SUMD) *Pi to the result. The same for the left points and you get the answer. After you process the ith point you add it to the index trees and can go on.
Edit: Here is one article about Biary index trees: http://community.topcoder.com/tc?module=Static&d1=tutorials&d2=binaryIndexedTrees
This is the direct connections problem from codesprint 2.
They will be posting worked solutions to all problems within a week on their website.
(They have said "Now that the contest is over, we're totally cool with everyone discussing their solutions to the problems.")