If you are not familiar with the standard weighted job scheduling problem, here it is (along with a description of a solution with an asymptotic runtime of n*logn).
I’m wondering though, if you instead provided the profit values per unit of time and allowed for taking partial shifts of jobs, if you could still find a solution to this problem with a runtime of O(nlogn).
For example, with the following structure for job details:
{start time, end time, profit/hour}
And the following jobs:
Job 1: {1, 5, 50} Job 2: {2, 4, 100} Job 3: {3, 4, 150}
The algorithm would decide to take Job 1 from 1-2, Job 2 from 2-3, Job 3 from 3-4, and Job 1 again from 4-5.
Any thoughts or approaches are appreciated!
Related
Assume you are given t1, t2, t3, ..., tn amount of tasks to finish every day. And once you start working, you can only finish c1, c2, c3, ..., cn tasks until spending 1 day resting. You can spend multiple days resting too. But you can only do the tasks which are given you that day. For example;
T[] = {10, 1, 4, 8} given tasks;
C[] = {8, 4, 2, 1} is the capacity of doing tasks for each day.
For this example, optimal solution is giving a break on the 3rd day. That way you can complete 17 tasks in 4 days:
1st day 8 (maximum 10 tasks, but c1=8)
2nd day 1 (maximum 1 task, c2=4)
3rd day 0 (rest to reset to c1)
4th day 8 (maximum 8 tasks, c1=8)
Any other schedule would result with fewer tasks getting done.
I'm trying to find the recurrence relation for this dynamic programming problem. Can anyone help me? I find this question but mine is different because of the decreasing work capacity and there are different number of jobs each day. Reference
If I got you right you have an amount of tasks to do, t(i) for every day i. Also you have some kind of a given internal restriction sequence c(j) for a current treak day j where j can be reseted to 0 if no task was done that day. Goal is to maximizie the solved tasks.
Naive approach is to store for each day i a list for every state j how many tasks were done. Fill the data for the first day. Then for every following day fill the values for the "no break" case - which is
value(i-1,j-1)+min(t(i),c(j)). Choose the maximum from the previous day to fill the "break" entry. Repeat until last day. Choose the highest value and trace back the path.
Example for above
Memory consumtption is pretty easy: O(number of days * number of states).
If you are only interested in the value and not the schedule the memory consumption would be the O(number of states).
Time consumption is a bit more complex, so lets write some pseudo code:
For each day i
For each possible state j
add and write values
choose maximum from previous day for break state
choose maximum
For each day
trace back path
The choose maximum-function would have a complexity of O(number of states).
This pseudo code results in time consumption O(number of days * number of states) as well.
I have a processing logic which has 11 parameters(let's say from parameter A to parameter K) and different combinations of theses parameters can results in different outcomes.
Processing Logic Example:
if x > A:
x = B
else:
x = C
y = math.sin(2x*x+1.1416)-D
# other logic involving parameter E,F,G,H,I,J,K
return outcome
Here are some examples of the possible values of the parameters(others are similar, discrete):
A ∈ [0.01, 0.02, 0.03, ..., 0.2]
E ∈ [1, 2, 3, 4, ..., 200]
I would like to find the combination of these parameters that results in the best outcome.
However, the problem I am facing is that there are in total
10^19 possible combinations while each combination takes 700ms processing time per CPU core. Obviously, the time to process the whole combinations is unacceptable even I have a large computing cluster.
Could anyone give some advice on what is the correct methodology to handle this problem?
Here is some of my thoughts:
Step 1. Minimize the step interval of each parameter that reduces the total processing time to an acceptable scope, for example:
A ∈ [0.01, 0.05, 0.09, ..., 0.2]
E ∈ [1, 5, 10, 15, ..., 200]
Step 2. Starting from the best combination resulted from step 1, doing a more meticulous research around that combination to find the best combination
But I am afraid that the best combination might hide somewhere that step 1 is not able to perceive, so step 2 is in vain
This is an optimization problem. However, you have two distinct problems in what you posed:
There are no restrictions or properties on the evaluation function;
You accept only the best solution of 10^19 possibilities.
The field of optimization serves up many possibilities, most of which are one variation or another of hill-climbing search and irruptive movement (to help break out of a local maximum that is not the global solution). All of these depend on some manner of continuity or predictability in the evaluation function's dependence on its inputs.
Without that continuity, there is no shorter path to the sole optimal solution.
If you do have some predictability, then you have some reading to do on various solution methods. Start with Newton-Raphson, move on to Gradient Descent, and continue to other topics, depending on the fabric of your function.
Have you thought about purely mathematical approach i.e. trying to find local/global extrema, or based on whether function is monotonic per operation?
There are quite decent numerical methods for derivatives/integrals, even to be used in a relatively-generic manner.
So in other words limit the scope, instead of computing every single option - depends on the general character of operations, that you have in mind.
So I have a job assignment problem that doesn't have the traditional cost the Hungarian method requires.
For example:
I have 3 workers - A, B and C
I have 5 jobs - 1, 2, 3, 4 and 5
Each worker has a list of jobs he can perform, like so:
worker A can work on job 1, 2, 5
worker B can work on job 1, 2
worker C can work on job 1
The end result (since there's no cost) is the maximum number of assignments I can achieve. In this example, I can achieve a maximum of 3 assignments:
worker A on job 5
worker B on job 2
worker C on job 1
Is the Hungarian method a good way to solve this? Should I just use "dummy" costs? I was thinking maybe using the index of the job preference as the cost; is this a good idea?
The Hungarian algorithm could be made to work here, but an algorithm for unweighted maximum bipartite matching like Hopcroft–Karp would be faster.
Assign the cost -1 to the job which they can, and the others is zero.
Then run the Hungarian algorithm and it will give you the answer(It will returns -answer,in fact).
Don't do it with some large numbers, it may cause overflow(unless you implement the Hungarian very carefully).
Indeed, it's Maximum matchings in bipartite graphs, and there are so many ways to solve this problem, see wiki pages:
http://en.wikipedia.org/wiki/Matching_(graph_theory)#Maximum_matchings_in_bipartite_graphs
PS:Hopcroft–Karp algorithm is faster than hungarian and is more simple also. It worth a try. Some compulicated method is faster than these two, but it's not recommanded to learn these algorithms at very first.
PSS: Your ID in stackoverflow is a method to solve this problem. It's a network flow way. It's called shortest argument path(sap). See:http://coral.ie.lehigh.edu/~ted/files/ie411/lectures/Lecture11.pdf
Dummy costs should do the trick. Assign a cost of 1 to any job they can do, and an infinite cost (if your system allows that) to jobs they can't. The Hungarian algorithm is designed to minimize the total cost across all tasks, so it'll figure things out naturally. There shouldn't be any need to account for what you think their job preferences are; that's the algorithm's job.
Hungarian algorithm will give you an answer, but do not use infinity costs, since you cannot compare (infinity + infinity) and infinity (unless you compare the costs yourself).
A: 1, 2, 3
B: 1
C: 1
The matrix form:
1 2 3
A 1 2 3
B 1 inf inf
C 1 inf inf
How can your computer compare 1, inf, inf and 2, 1, inf?
Instead, use some cost that is so large that it will guarantee to be not assigned (and yes, be careful with overflowing).
I'm coding a question on an online judge for practice . The question is regarding optimizing Bogosort and involves not shuffling the entire number range every time. If after the last shuffle several first elements end up in the right places we will fix them and don't shuffle those elements furthermore. We will do the same for the last elements if they are in the right places. For example, if the initial sequence is (3, 5, 1, 6, 4, 2) and after one shuffle Johnny gets (1, 2, 5, 4, 3, 6) he will fix 1, 2 and 6 and proceed with sorting (5, 4, 3) using the same algorithm.
For each test case output the expected amount of shuffles needed for the improved algorithm to sort the sequence of first n natural numbers in the form of irreducible fractions.
A sample input/output says that for n=6, the answer is 1826/189.
I don't quite understand how the answer was arrived at.
This looks similar to 2011 Google Code Jam, Preliminary Round, Problem 4, however the answer is n, I don't know how you get 1826/189.
let's say i have an array, size 40. and the element im looking for is in position 38.
having a simple loop, it will take 38 steps right?
but, having, 2 loops, running in parallel, and a variable, "found"
set to false, and changes to true when the element is found.
the first loop, will start from index 0
the second loop, will start from index 40.
so basically, it will take only, 4 steps right? to find the element. the worst case will be if the element is in the middle of the array. right?
It depends how much work it takes to synchronize the state between the two threads.
If it takes 0 work, then this will be, on average, 50% faster than a straight through algorithm.
On the other hand, if it takes more work than X, it will start to get slower (which is very likely the case).
From an algorithm standpoint, I don't think this is how you want to go. Even 2 threads is still going to be O(n) runtime. You would want to sort the data (n log n ), and then do a binary search to get the data. Especially you can sort it 1 time and use it for many searches...
If you're talking about algorithmic complexity, this is still a linear search. Just because you're searching two elements per iteration doesn't change the fact that the algorithm is O(n).
In terms of actual performance you would see, this algorithm is likely to be slower than a linear search with a single processor. Since very little work is done per-element in a search, the algorithm would be memory bound, so there would be no benefit to using multiple processors. Also, since you're searching in two locations, this algorithm would not be as cache efficient. And then, as bwawok points out, there would be a lot of time lost in synchronization.
When you are running in parallel you are dividing your CPU power into two + creating some overhead. If you mean you are running the search on a say, a multicore machine, with your proposed algorithm then the worse case is 20 steps. You are not making any change in the complexity class. So where those 4 steps, that you mentioned, are coming from?
On average there is no different in runtime.
Take for example if you are searching for an item out of 10.
The original algorithm will process in the following search order:
1, 2, 3, 4, 5, 6, 7, 8, 9, 10
The worse case is the last item (taking 10 steps).
While the second algorithm will process in the following search order:
1, 3, 5, 7, 9, 10, 8, 6, 4, 2
The worse case in this scenario is item 6 (taking 10 steps).
There are some cases where algorithm 1 is faster.
There are some cases where algorithm 2 is faster.
Both take the same time on average - O(n).
On a side note, it is interesting to compare this to a binary search order (on a sorted array).
4, 3, 2, 3, 1, 4, 3, 2, 4, 3
Taking at most 4 steps to complete.