Resource with schedules allocation problem - algorithm

I have a similar to this task but with some differencies in bold. That is:
I have a set of J jobs that need to be completed. Jobs are organized into set of directed graphs. Each job can have one or more preceding(parent) jobs that have to be completed before it starts
All jobs take different times to complete, but the time is known
I have a set of R human resources. Important!!! Each resource has a schedule when this resource is available
Some jobs can be preempted once started. E.g. if a resource is not available at some specific hours then it can process the job after
A job may has a predefined amount of resource which can be changed. If algorithm can't find desired decision (all jobs couldn't be finished at some known date) then we can increase/decrease resources amount. The duration of a job changes proportionally with amount. E.g. J1 require 1 human resource initially and estimated duration 1 hour. If we set 2 human resource than duration decreases to 0.5 hour
Resources have parameters that match tasks. E.g. If J1 has constraints {A,B} then we can assign resource R1 with permissions {A,B} which satisfied these constraints. If there is no appropriate resources then we can assign any of available.
My Goal: Assign as much appropriate resources as possible so that the job would finish at the time.
Is there a way to solve this problem via simplex method? How equatinons would look like. What will be a complexity? Could you please help me to build a math model or share some links. Any help would be appreciate. I can't get close to resource schedules without brute permutation.
I've tried to implement something similar to greedy algorithm:
Firstly I sheduled tasks from job start date without resources calendars considering only relations between tasks (I calculated order for each task which is in chain. Where order 0 - the earliest predecessor)
E.g. In chain J1 -> J2 -> J3 J3 must be done after finishing J1 and J2. J1.Order = 0, J2.Order = 1, J3.Order = 3.
Then I sorted tasks by order and operations count in chain. First goes the task with higher count of children. Then I sorted by count of required resources. And finally by initial duration of a task
For each order I take a task and assign resources with satisfied skills and can do the task then earlier then better considering their calendars and buisiness into another job
This algorithm doesn't take into account predefined job finish date. I'm worried that it's far away from optimal solution and another approach is needed.
The greedy algorithm with a proof of correctness would also make the deal for me.

Related

Algorithm to find the correct combination in a fast manner

Assume I have 4 lists: jobs, workers, mechanisms and mechanism equipment.
Currently I am firstly looping through jobs, lets call this the
jobLoop.
Inside jobLoop I'm looping through workerLoop, checking if
worker is available and has required competences to do the job.
If worker is OK, I'm looping through mechanismLoop, checking if worker can use the mechanism and if the mechanism is available. If no mechanisms are available, I fall back to workerLoop, looking for another correct worker.
If mechanism is OK, I loop through mechEquipmentLoop, checking checking if worker can use the equipment and if the equipment is available. If no equipment is available, I fall back to mechanismLoop, looking for another correct mechanism.
If mechanism equipment is finally okay, the algorithm is done. If not, the algorithm says items cannot be matched.
This is a simplified version, on each step there are many checks like if worker is allowed on the object where the job is done and so on.
I'm trying to think of a more efficient way to do this. Currently the time complexity for this algorithm should be roughly O(n^4), right? I'm not looking for code, just guidance on how to perform this.
IMHO - this algorithm is O(jwm*e) instead of O(n^4). j = number of jobs, w = number of workers, m= number of mechanisms, e = number of mech equipment.
If these lists don't change & if the answer is needed only once this is the best algorithm to execute. You need to visit all the inputs once at least.
Suppose these lists change and the same algo needs to execute for a given job multiple times you can do this.
Store the list of workers in BST (or a self-balanced tree-like AVL) with job competency as key. Suppose if there are multiple competencies for a worker then his data will be in all the competencies. The creation of the tree is O(wlogw) here w is the number of unique competency & worker combinations, not workers number alone. Deletion, Addition & Search will be O(logw). Here are we are assuming that competency - worker distribution is decent. Suppose if all workers have only one competency this will become O(w) once again.
The same applies to mechanism and equipment. This will make the search at every level to O(logm) and O(loge).
So for every job best case scenario of allocation is O(logw * logm * loge), with a overhead of O(wlogw + mlogm + eloge). For all jobs it will be (j * logw * logm * loge).

How to order Tasks from a Pool of Tasks to minimize time costs?

I am trying to solve a problem where I am currently stuck an apreciate any help/hints/tips how to continue.
First I will explain you the problem and how I tried to tackle it.
Basic Problem:
There is a pool of tasks which need to be completed (about 50 Tasks are in the pool).
To change from one task to a new one there are costs (time).
There is a nxn-Matrix(ChangeCostMatrix) which shows the costs to shift every task.
The costs are asymmetric ( Costs from T1 to T5 = 5 and Costs from T5 to T1 = 2).
According to my understanding this is the (Asymmetrical) Traveling Salesman Problem which is well described in the literature.
Now I describe the Problem as Advanced Problem where I don't have any Idea how to solve it.
Advanced Problem:
Plan the next 50 hours (about 20 tasks can be settled) with tasks so that the costs are minimized.
That means take 20 tasks out of the 50 and minimize the costs and therefore solve as much tasks as possible. Each task takes some time to finish. This time is stored in a TaskDurationMatrix.
Each task in the pool has a date or time left until when it needs to be completed. In most cases this will result in lets say 10 tasks that need to be solved within the next 50 hours.
There will be a starting task given from where to start the optimal tour.
Summarized I try to solve the following task:
Plan the next 50 hours with tasks, starting from a start task, where all tasks that need to be solved are solved and additional task are taken so that the time costs are minimal.
Input:
TaskPool n = 50
StartingTask i.e. T4
TimePeriod i.e. 50 h
TaskDurationMatrix(1 x n): T4: 1h, T5: 1.5h ...
AsymmetricChangeCostMatrix(n x n): T1 - T3: 3h, T3 -T1 2h
Output:
Task Order for Time Period: StartikgTask -> T15 -> T11 -> T7 -> T23 -> T14 -> T18...
Obviously this is an optimization task.
Does anyone know how I can tackle that kind of task and just give me a basic where I can start or what area I need to get into?
You could implement a biased random-key genetic algorithm (BRKGA). BRKGA is a generic framework for constructing genetic optimization algorithms. The one non-generic bit is the decoder, which turns a chromosome consisting of several real numbers between 0 and 1 into a solution to the problem. In this particular case, you could specify that the chromosomes have one number per task, and interpret a chromosome as a sequence of tasks by selecting (1) the required tasks (2) the bottom k other tasks and sorting the tasks with a comparator that compares the corresponding alleles.

Is there an algorithm for the AssignmentProblem where not every task can be performed by every agent and some tasks are more important than others?

My problem is very similar to the Assignment problem (http://en.wikipedia.org/wiki/Assignment_problem), with three exceptions:
Not every task can be performed by every agent.
Some tasks are more important than other tasks.
There is definitely a possibility that not every task will be fulfilled.
The real world story behind this is a fire department running on volunteers. Throughout the day volunteers can say they are available or not and we have to re-evaluate if every task is sufficiently filled. If not someone needs to be notified that there is a problem. We already want to notify if we only have the minimum amount. Generally, a small fire department usually needs to have a leader, a driver, and 4 regular firemen available at all times.
Translating this to the assignment problem, we say that the leader, driver, fireman are tasks and every fireman is an agent. What we want to do is find out if there is a problem (i.e. we don't have 2 possible leaders, 2 possible drivers, and 5 regular firemen), how big the problem is (i.e. we have the minimum amount, or we are in trouble) and where the problem is (i.e. we need another fireman or we need another leader, where needing another leader is more important than needing another fireman).
So what we want to do is given a set of tasks and a set of agents that each can perform a variable set of tasks, divide the agents so that every task is fulfilled OR the most important tasks are fulfilled.
Where the algorithms that solve the assignment problem that I've checked out end up going wrong is in the situation where you don't have enough people to fulfill all tasks. They then seem to get assigned to the lower priority tasks, where it would have been 'better' to have them on higher priority task.
Does this sound familiar to anyone? Is there maybe a name for this problem that I have missed in all the different variations I've looked at? Or does someone maybe have a brilliant idea on how to solve this efficiently?
You can basically use a greedy algorithm that schedules the highest priority tasks first. I would do something like:
Take highest priority task
For each agent who can do this task, determine what other as-yet-unassigned tasks they can do ("capabilities")
If an agent has no other capabilities, assign them to this task
Otherwise [all agents have other capabilities] count how many other as-yet-unscheduled agents also have those other capabilities
Select the resource who has the most "duplicated" effort for their other capabilities
Repeat for next highest priority task
So for a specific example, suppose you have 5 agents as follows:
A - leader, fireman
B - leader, driver
C - driver, fireman
D - fireman
E - fireman
Your highest priority task is leader, so select agents A and B. A can also do "fireman" which is duplicated by 3 others, and B can also do "driver" which is duplicated by 1 other. So the agent with the most duplicated tasks is A, and A gets assigned to leader.
Next highest task is driver. B can only do "driver" because leader has already been assigned, so B gets driver.
Etc.
This is a bit brute force and I'm sure there are edge cases it doesn't catch, but at least it's an approach that is usable...

Assigning jobs to people using Maximum Flow, harder version

I am self studying max flow and there was this problem:
the original problem is
Suppose we have a list of jobs
{J1, J1,..., Jm}
and a list of people that have applied for them
{P1, P2, P3,...,Pn}
each person have different interests and some of them have applied for multiple jobs (each person has a list of jobs they can do)
nobody is allowed to do more than 3 jobs.
so, this problem can be solved by finding a maximum flow in the graph below
I understand this solution, but
the harder version of the problem
what if these conditions are added?
the first 3 conditions of the easy version (lists of jobs and persons and each person has a list of interests or abilities) are still the same
the compony is employing only Vi persons for job Ji
the compony wants to employ as many people as possible
there is no limitations for the number of jobs a person is allowed to do.
What difference should I make in the graph so that my solution can satisfy those conditions as well?or if I need a different approach please tell me.
before anyone say anything, this is not homework. It's just self study, but I am studying Maximum flow and the problem was in that area so the solution should use Maximum flow.
For multiple persons for a single job:
The edge from Ji to t will have the capacity equal to the number of people for that job. E.g. If job #1 can have three people, this translates to a capacity of three for the edge from J1 to t.
For the requirement of hiring as many people as possible:
I don't think this is possible with a single flow-graph. Here is an algorithm for how it could be done:
Run the flow-algorithm once.
For each person:
Try to decrease the incoming capacity to one below the current flow-rate.
Run the flow-algorithm again.
While this does not decrease the total flow, repeat from (2.1.).
Increase the capacity by one, to restore the maximum flow.
Until no further persons gets added, repeat from (2.).
For no limitation on number of jobs:
The edges from s to Pi will have a maximum flow equal the number of applicable jobs for that person.

A Greedy algorithm for k-limited resources

I am studying greedy algorithms and I am wondering the solution for a different case.
For interval selection problem we want to pick the maximum number of activities that do not clash with each other, so selecting the job with the earliest finishing time works.
Another example; we have n jobs given and we want to buy as smallest number of resources as possible. Here, we can sort all the jobs from left to right, and when we encounter a new startpoint, we increment a counter and when we encounter an endpoint, we decrement the counter. So the largest value we get from this counter will be number of resources we need to buy.
But for example, what if we have n tasks but k resources? What if we cannot afford more then k resource? How should be a greedy solution to remove as few tasks as possible to satisfy this?
Also if there is a specific name for the last problem I wrote, I would be happy to hear that.
This looks like a general case of the version where we have only one resource.
Intuitively, it makes sense to still sort the jobs by end time and take them one by one in that order. Now, instead of the ending time of the last job, we keep track of the ending times of the last k jobs accepted into our resources. For each job, we check if the current jobs starting time is greater that the last job in any one of our resources. If no such resource is found, we skip that job and move ahead. If one resource is found, we assign that job to that resource and update ending time. If there are more than one resource able to take on that job, it makes sense to assign it to the resource with the latest end time.
I don't really have a proof of this greedy strategy, so it may well be wrong. But I cannot think of a case where changing the choice might enable us to fit more jobs.

Resources