Identifying when greedy method gives optimum solution - algorithm

I was looking at this problem on leetcode
https://leetcode.com/problems/minimum-number-of-operations-to-convert-time/description/
The hints tell us to follow a greedy approach where we convert the time difference to minutes and pick the largest possible values
For the given allowed values [1,5,15,60] greedy seems to work for all cases
But let us assume a case where the difference b/w time is 46 minutes and the allowed values are [1,23,40] then as per greedy, the operation would take 7 steps but the minimum possible is 2 ( 23 + 23 )
Why don't we have similar case for the values given the original problem ? how can it be proved that greedy is always the optimal solution in the case of the original problem ? and how can we know, for a given set of allowed values, do we get the optimal solution with greedy or not ?

This problem is very similar to the coin change problem. In general you are very much correct and the greedy solution is not optimal. However is this case the greedy solution is optimal since the "coins" are complete multiplications of each other :
1 * 5 = 5
5 * 3 = 15
15 * 4 = 60
Since this is the case each 60 step can be done by 4 15 steps or 12 5 steps. Therefore the greedy solutions is best in this case.
In the second example you shoed, the "coins" were not a multiplication of each other, making the greedy solution sub-optimal in some cases.

Related

Finding minimum number of days

I got this question as a part of the interview and I am still unable to solve it.
It goes like this
A person has to complete N units of work; the nature of work is the same.
In order to get the hang of the work, he completes only one unit of work in the first day.
He wishes to celebrate the completion of work, so he decides to complete one unit of work in the last day.
Given that he is only allowed to complete x, x+1 or x-1 units of work in a day, where x is the units of work
completed on the previous day.
How many minimum days will he take to complete N units of work?
Sample Input:
6
-1
0
2
3
9
13
Here, line 1 represents the number of input test cases.
Sample Output:
0
0
2
3
5
7
Each number represents the minimum days required for each input in the sample input.
I tried doing it using the coin change approach but was not able to do so.
In 2k days, it's possible to do at most 2T(k) work (where T(k) is the k'th triangular number). In 2k+1 days, it's possible to do at most T(k+1)+T(k) at most work. That's because if there's an even (2k) number of days, the most work is 1+2+3+...+k + k+(k-1)+...3+2+1. Similarly, if there's an odd (2k+1) number of days, the most work is 1+2+3+...+k+(k+1)+k+...+3+2+1.
Given this pattern, it's possible to reduce the amount of work to any value (greater than 1) -- simply reduce the work done on the day with the most work, never picking the start or end day. This never invalidates the rule that the amount of work on one day is never more than 1 difference from an adjacent day.
Call this function F. That is:
F(2k) = 2T(k)
F(2k+1) = T(k)+T(k+1)
Recall that T(k) = k(k+1)/2, so the equations simplify:
F(2k) = k(k+1)
F(2k+1) = k(k+1)/2 + (k+1)(k+2)/2 = (k+1)^2
Armed with these observations, you can solve the original problem by finding the smallest number of days where it's possible to do at least N units of work. That is, the smallest d such that F(d) >= N.
You can, for example, use binary search to find d, or an optimal approach is to solve the equations. The minimal even solution has d/2 * (d/2 + 1) >= N which you can solve as a quadratic equation, and the minimal odd solution has (d+1)^2/4 >= N, which has a solution d = ceil(2sqrt(N)-1). Once you've found the minimal even and odd solutions, then you can pick the smaller of the two.
AS you want to have the minimum amounts of days you can just say yeah x+1, since if you want the minimum amount of days, BUT you have to consider that his last day x should be 1 so you have to break at a given point and go x-1, so now we have to determine the Breakpoint.
The Breakpoint is located in the middle of the days, since you start at 1 and want to end at 1.
For example you have to do 16 units so you distribute your days like:
Work done:
1234321.
7 days worked.
When you can't make an even Breakpoint like above repeat some values
5 = 1211
Samples:
2: 11
3: 111
9: 12321
13: 1234321
If you need to do exactly N units, not more, then you could use dynamic programming on the matrix a[x][y] where x is the amount of work done in the last day, y is the total amount of work, and a[x][y] is the the minimum number of days needed. You could use Dijkstra's algorithm to minimize a[1][N]. Begin with a[1][1]=1.

Dividing set of integers

I've got a problem with a solution for algorithmic problem as described below.
We have a set (e.g. array) of integers. Our task is to divide them into the groups (they don't have to have same amount of elements) that sum is equal to each other. I case that primal set cannot be divide we have to give answer "impossible to divide".
For example:
Set A is given [-7 3 3 1 2 5 14]. The answer is [-7 14], [3 3 1], [2 5].
It seems that it's easy to say when for sure it would be impossible. When sum of primal set isn't divisible by 3: sum(A) % 3 != 0.
Do you have any idea how to solve that problem?
This is the 3-partition problem variant of the partition problem, the difference being that the classic partition problem splits the set into two sets (not three) whose sums are equal to each other. This problem is NP-complete, so you're almost certainly not going to find a polynomial time solution for it; the 2-partition problem has a pseudopolynomial time solution, but the 3-partition problem does not.
See this answer for an outline of how to adapt the 2-partition algorithm to a 3-partition algorithm. See also this paper for a parallel solution.

Minimum number of coins required to get a value [duplicate]

This question already has answers here:
Coin changing algorithm
(4 answers)
Closed 8 years ago.
Given a list of denomination of coins, I need to find the minimum number of coins required to get a given value.
My approach using greedy algorithm,
Divide value by max denomination, take remainder value and divide by second maximum denomination and so on till be get required value.
But this approach fails for some cases.
I want to know
Approach which works for all cases
Why greedy approach fails?
Example where approach fails.
Coins Denomination (1,3,4,5)
Value Required 7
Using Greedy Approach
(7/5)=1 and +2 because 3 and 4 can't be used so we need to use 2 1's value coins. So total of 3 coins.
However optimal value is 4+3 ( 2 coins).
There is classic solution for the problem you described - a kind of knapsack problem.
It can be solved using dynamic programming approach.
For the clear explanation you may follow this tutorial
Lets say, you want to get the value "2,10€" and have got a coins of value 2, 1, 0.50, 3 times 0.20.
Greedy will always take the biggest coin first, so it will choose the coin of value 2.
Now it is no longer possible to reach 2,10 as you do not have a coin of value 0.10 even though it would be possible if you would have choosen 1, 0.50 and the 3 0.20 Coins.
In this case (just as in most cases) I would recommend you to use Backtracking which would not fail in this case.

Second best solution to an assignmentproblem using the Hungarian Algorithm

For finding the best solution in the assignment problem it's easy to use the Hungarian Algorithm.
For example:
A | 3 4 2
B | 8 9 1
C | 7 9 5
When using the Hungarian Algorithm on this you become:
A | 0 0 1
B | 5 5 0
C | 0 1 0
Which means A gets assigned to 'job' 2, B to job 3 and C to job 1.
However, I want to find the second best solution, meaning I want the best solution with a cost strictly greater that the cost of the optimal solution. According to me I just need to find the assignment with the minimal sum in the last matrix without it being the same as the optimal. I could do this by just searching in a tree (with pruning) but I'm worried about the complexity (being O(n!)). Is there any efficient method for this I don't know about?
I was thinking about a search in which I sort the rows first and then greedily choose the lowest cost first assuming most of the lowest costs will make up for the minimal sum + pruning. But assuming the Hungarian Algorithm can produce a matrix with a lot of zero's, the complexity is terrible again...
What you describe is a special case of the K best assignments problem -- there was in fact a solution to this problem proposed by Katta G. Murty in the following 1968 paper "An Algorithm for Ranking all the Assignments in Order of Increasing Cost." Operations Research 16(3):682-687.
Looks like there are actually a reasonable number of implementations of this, at least in Java and Matlab, available on the web (see e.g. here.)
In r there is now an implementation of Murty's algorithm in the muRty package.
CRAN
GitHub
It covers:
Optimization in both minimum and maximum direction;
output by rank (similar to dense rank in SQL), and
the use of either Hungarian algorithm (as implemented in clue) or linear programming (as implemented in lpSolve) for solving the initial assignment(s).
Disclaimer: I'm the author of the package.

Tips for Project Euler Problem #78

This is the problem in question: Problem #78
This is driving me crazy. I've been working on this for a few hours now and I've been able to reduce the complexity of finding the number of ways to stack n coins to O(n/2), but even with those improvements and starting from an n for which p(n) is close to one-million, I still can't reach the answer in under a minute. Not at all, actually.
Are there any hints that could help me with this?
Keep in mind that I don't want a full solution and there shouldn't be any functional solutions posted here, so as not to spoil the problem for other people. This is why I haven't included any code either.
Wikipedia can help you here. I assume that the solution you already have is a recursion such as the one in the section "intermediate function". This can be used to find the solution to the Euler problem, but isn't fast.
A much better way is to use the recursion based on the pentagonal number theorem in the next section. The proof of this theorem isn't straight forward, so I don't think the authors of the problem expect that you come up with the theorem by yourself. Rather it is one of the problems, where they expect some literature search.
This problem is really asking to find the first term in the sequence of integer partitions that’s divisible by 1,000,000.
A partition of an integer, n, is one way of describing how many ways the sum of positive integers, ≤ n, can be added together to equal n, regardless of order. The function p(n) is used to denote the number of partitions for n. Below we show our 5 “coins” as addends to evaluate 7 partitions, that is p(5)=7.
5 = 5
= 4+1
= 3+2
= 3+1+1
= 2+2+1
= 2+1+1+1
= 1+1+1+1+1
We use a generating function to create the series until we find the required n.
The generating function requires at most 500 so-called generalized pentagonal numbers, given by n(3n – 1)/2 with 0, ± 1, ± 2, ± 3…, the first few of which are 0, 1, 2, 5, 7, 12, 15, 22, 26, 35, … (Sloane’s A001318).
We have the following generating function which uses our pentagonal numbers as exponents:
1 - q - q^2 + q^5 + q^7 - q^12 - q^15 + q^22 + q^26 + ...
my blog at blog.dreamshire.com has a perl program that solves this in under 10 sec.
Have you done problems 31 or 76 yet? They form a nice set that is an generalization of the same base problem each time. Doing the easier questions may give you insight into a solution for 78.
here some hints:
Divisibility by one million is not the same thing as just being larger than one million. 1 million = 1,000,000 = 10^6 = 2^6 * 5^6.
So the question is to find a lowest n so that the factors of p(n) contain six 2's and six 5's.

Resources