How to optimize assignment of tasks to agents with these constraints? - algorithm

I have an assignment problem as a part of my Master's Thesis, and I am looking for general direction in solving the same.
So, there is a list of agents, and a list of tasks, with number of tasks being greater than the number of agents.
The agents submit a prioritized ordered list of tasks they can/want to do. The length of the list is fixed to a number much smaller than the total number of tasks.
Every agent must be assigned a task. A task once assigned cannot be assigned to another agent.
The objective is to find an assignment such that the average priority/preference of the assigned tasks is the lowest. Additionally, if it is complete solution i.e. every agent is assigned a task, it is even better.
I have looked at the generalized assignment problems, and the Hungarian algorithm, but these do not cater to the specific situation where there is a cost to a task and also the possibility of the agent being unable to do some of the tasks.
Please help. Thank you.

If you want a general approach, you can model the problem as Mixed Integer Program, introducing binary variables for the assignment of tasks to agents and putting the priority costs and (very high) non-assignment costs into the objective function. Mixed Integer Programs can be solved using a variety of solver programs, including CPLEX or Gurobi which are free for academic purposes.

Related

Need an advice about algorithm to solve quite specific Job Shop Scheduling Problem

Job Shop Scheduling Problem (JSSP): I have jobs that consist of tasks and I have machines that can perform these tasks.
I should be able to add new jobs dynamically. E.g. I have a schedule for the first 5 jobs, and when the 6th arrive - I need to be able to fit it into the schedule in the best way. It is possible to adjust existing schedule within the given flexibility constrains.
Look at the picture below.
Jobs have tasks, each task is the same type of action. Think about painting of some objects with paint spray. All the machines are the same (paint sprays), and all of the tasks are the same.
Constraint 1. Jobs have a preferred deadline for completion, but the deadline is flexible to some extent.
Edit after #tucuxi answer: Flexible deadline mean that the time of completion can be extended by some delta if necessary.
Constraint 2. Between the jobs there is resting phase. Think about drying the paint. Resting phase has minimal required duration. Resting phase can be longer or shorter if necessary.
Edit after #tucuxi answer: So there is planned time of rest Tp which is desired, but flexible value that can be increased or decreased if this allows for better scheduling. And there is minimal time of rest Tm. So Tp-Tadjustmenet>=Tm.
The machine is occupied by the job from the start to the completion.
Here goes parts that make this problem very distinct from what I have read about.
Jobs arrive in batches of several jobs. For example a batch can contain 10 jobs of the type Job_1 and 5 of Job_2. Different batches can contain different types of jobs. All the jobs from the batches should be finished as close to each other as possible. Not necessary at the same time, but we need to minimize the delay between the completion of first and last jobs from the batch.
Constraint 3. Machines are grouped. In each group only M machines can work simultaneously. Think about paint sprays that are connected to the common pressurizer that has limited performance.
The goal.
Having given description of the problem, it should be possible to solve JSSP. It should be also possible to add new jobs to the existing schedule.
Edit after #tucuxi answer: This is not a task that should be solved immediately: it is not a time-critical system. But it shouldn't be too long to irritate a human who put new tasks into the algorithm.
Question
What kind of many JSSP algorithms can help me solve this? I can implement an algorithm by myself, if there is one. The closest I found is This - Resource Constrained Project Scheduling Problem. But I was not able to comprehend how can I glue it to the JSSP solving algorithm.
Edit after #tucuxianswer: No, I haven't tried it yet.
Is there any libraries that can be used to solve this problem? Python or C# are the preferred languages, but in the end it doesn't really matter.
I appreciate any help: keyword to search for, link, reference to a book, reference to a library.
Thank you.
I doubt that there is a pre-made algorithm that solves your exact problem.
If I had to solve it, I would first:
compile datasets of inputs that I can feed into candidate solvers.
think of a metric to rank outputs, so that I can compare the candidates to see which is better.
A baseline solver could be a brute-force search: test and rate all possible job schedulings for small sample problems. This is of course infeasible for large inputs, but for small inputs it allows you to compare the outputs of more efficient solvers to a known-best answer.
Your link is to localsolver.com, which appears to provide a library for specifying problem constraints to then solve them. It is not freely available, requiring a license to use; but it would seem that your problem can be readily modeled in it. Have you tried to do so? They appear to support both C++ and Python. Other free options exist, including optaplanner (2.8k stars in github) or python-constraint (I have not looked into other languages).
Note that a good metric is crucial to choosing a good algorithm: unless you have a clear cost function to minimize, choosing "a good algorithm" is impossible. In your description of the problem, I see several places where cost is unclear (marked in italics):
job deadlines are flexible
minimal required rest times... which may be shortened
jobs from a batch should be finished as close together as possible
(not from specification): how long can you wait for an optimal vs a less-optimal-but-faster solution?

Task assigning algorithm

I'm trying to figure out what the most efficient way of assigning tasks to people. Here is what I'm struggling with:
you have X number of people that are all eligible to do work
each person can do X number of tasks at once
you have X number of waiting tasks
each task takes a variable length of time
The goal of the challenge is to evenly distribute the tasks among the people as best as possible. Once a person finishes one of the given tasks, one of the 'queued' tasks will be fed to them. Here's an example scenario.
There's 500 tasks in the queue with 50 people available to 'take' them. Each person can take 2 tasks at once. Once a person finishes a given task they'll be fed another. The tasks that have been waiting the longest get the highest priority.
One way to possibly do it would be to have each of the 50 people that have the capacity to take a task be assigned one based on their task last given time. For example:
task 1 -> person 1
task 2 -> person 2
task 3 -> person 3
...
task 4 -> person 1
task 5 -> person 2
task 6 -> person 3
Based on the task last assigned to X person, the person with the oldest task last assigned and that's available to take on another task would get it fed to them. I'm unsure if this is the right solution for even task distribution, would love to hear suggestions! Is there a name for this type of algorithm?
Another method could possibly be to assign tasks based on the person currently serving the lowest number of tasks. Although if multiple people are tied to for the lowest number of tasks, the task is assigned to the person who's been available (last task assigned) for the longest period of time.
Please consider looking at this at a higher level.
The proposals so far have been greedy. They build one schedule and hope for the best.
The first thing you'll need to decide is whether that's what you want. Greedy assignment will produce spectacularly bad answers for some inputs, though if the inputs are "reasonable," and all you want is a reasonable answer, it may be fine.
On the other hand, finding the optimal assignment of tasks is NP hard. You'll need time exponential in the input size to be sure you have the best possible answer.
There are two intermediate approaches.
Randomized task scheduling algorithms. This is a huge topic. This paper is still a decent starting place, though it's now very out-of-date. Richard Karp is amazing. The nice thing about randomized algorithms is that they can provide very useful optimality guarantees.
Heuristic search. Define a single numeric metric of goodness of a schedule. Start with a reasonable one (greedily determined or random). Put that on the search queue sorted by metric v, pull the best metric off the queue, find all its "children", i.e. schedules that haven't been considered before resulting from all possible simple changes, add these to the queue, and repeat. Stop when you can't wait any longer. The current best is your answer. You can also structure this as a genetic algorithm, which is just a specialized heuristic search.
Keep 2 queues. one for tasks another for free people waiting for task. If there is a task to be taken first person from queue will take and go. You will not think about time for tasks and people in this solution as it is justice way of distribution. You might think about priority queues if you need some kind of prioritization in the future with little changes for both queues.
As zsiar, but use two priority queues. The top task in the top priority queue gets assigned to the top workers, assuming he is capable. If he's not, the task can't be done and must wait.
Workers in the worker priority queue get ordered by capacity or time idle or whatever seems fair. In fact it's not a real priority queue as when a worker finishes a task, we take him out and put him back in the queue, in a higher position.
(If workers can do two tasks at once they are probably computers rather than people, so time idle isn't a useful metric. Only human workers care if they are kept busy whilst other doss about).

Scheduling with variable Resources

(First of all, sorry for my english, it's not my first language)
I have a list of tasks/jobs, each task must start after a specific start time, needs to run for a certain time and has to be finished after a certain end time.
I can dynamically add and remove workers, so it is possible to execute 2 or more tasks at the same time if I have to. My Goal is to find a scheduling plan that executes each job successfully and uses the minimal amount of workers possible.
I'm currently using an EDF (http://en.wikipedia.org/wiki/Earliest_deadline_first_scheduling) Algorithm and recursively call the function with a higher Worker Limit if it can't schedule all jobs correctly, but I think this doesn't work right because I don't have a real way to measure when I can lower the ressource limit again.
Are there any Algorithms that work for my problem, or any other clever ideas?
Thanks for your help.
A scheduling problem can often be solved very effectively by formulating it either as mixed-integer program (MIP)
http://en.wikipedia.org/wiki/Mixed_integer_programming#Integer_unknowns
or expressing it using constraint programming (CP)
http://en.wikipedia.org/wiki/Constraint_programming
For either MIP or CP, you will find both free and commercial solvers that can address your problem.
In both of these approaches, you put your effort into stating the properties that the solution must have, and the hard work of applying an appropriate algorithm is left to a specialized solver.

Constrained graph transformation in scheduling applications

I'm working on an interactive job scheduling application. Given a set of resources with corresponding capacity/availabilty profiles, a set of jobs to be executed on these resources and a set of constraints that determine job sequence and earliest/latest start/end times for jobs I want to enable the user to manually move jobs around. Essentially I want the user to be able to "grab" a node of the job network and drag that forwards/backwards in time without violating any of the constraints.
The image shows a simple example configuration. The triangular job at the end denotes the latest finish time for all jobs, the connecting lines between jobs impose an order on the jobs and the gray/green bars denote resource availabilty and load.
You can drag any of the jobs to compress the schedule. Note that jobs will change in length due to different capacity profiles.
I have implemented an ad-hock algorithm that kinda works. However there are still cases where it'll fail and violate some constraints. However, since job-shop-scheduling is a well researched field with lots of algorithms and heuristics for finding an optimal (or rather good) solution to the general NP-hard problem - I'm thinking solutions ought to exist for my easier subset. I have looked into constraint programming topics and even physics based solutions (rigid bodies connected via static joints) but so far couldn't find anything suitable. Any pointers/hints/tips/search key words for me?
I highly recommend you take a look at Mozart Oz, if your problem
deals only with integers. Oz has excellent support for finite domain
constraint specification, inference, and optimization. In your case
typically you would do the following:
Specify your constraints in a declarative manner. In this, you would
specify all the variables and their domains (say V1: 1#100, means
V1 variable can take values in the range of 1--100). Some variables
might have values directly, say V1: 99. In addition you would specify
all the constraints on the variables.
Ask the system for a solution: either any solution which satisfies
the constraints or an optimal solution. Then you would display this
solution on the UI.
Lets say the user changes the value of a variable, may be the start
time of a task. Now you can go to step 1 to post the problem to the
Oz solver. This time, solving the problem most probably will not take
as much time as earlier, as all the variables are already instantiated.
It may be the case that the user chose a inconsistent value. In that
case, the solver returns null. Then, you can take the UI to the earlier
solution.
If Oz suits your need and you like the language, then you may want to
write a constraint solver as a server which listens on a socket. This way,
you can keep the constraint solver separate from the rest of your code,
including the UI.
Hope this helps.
I would vote in favor of constraint programming for several reasons:
1) CP will quickly tell you if there is no schedule that satifies your constraints
2) It would appear that you want to give you users a feasible solution to start with but
allow them to manipulate jobs in order to improve the solution. CP is good at this too.
3) An MILP approach is usually complex and hard to formulate and you have to artificially create an objective function.
4) CP is not that difficult to learn especially for experienced programmers - it really comes more from the computer science community than the operations researchers (like me).
Good luck.
You could probably alter the Waltz constraint propagation algorithm to deal with changing constraints to quickly find out if a given solution is valid. I don't have a reference to hand, but this might point you in the right direction:
http://www.sciencedirect.com/science?_ob=ArticleURL&_udi=B6TYF-41C30BN-5&_user=809099&_rdoc=1&_fmt=&_orig=search&_sort=d&_docanchor=&view=c&_searchStrId=1102030809&_rerunOrigin=google&_acct=C000043939&_version=1&_urlVersion=0&_userid=809099&md5=696143716f0d363581a1805b34ae32d9
Have you considered using an Integer Linear Programming engine (like lp_solve)? It's quite a good fit for scheduling applications.

What is this algorithm called?

I'm trying to look up this problem but I don't know what it's called. The premise is this:
Given m machines and j jobs, where each job can only be assigned to machines i through j, I need to assign the jobs to machines so that I maximize busy machines at one time. I am only concerned with how they are assigned at time 0. I am not concerned with how I would schedule remaining jobs after a job is completed.
Once a job and a machine are assigned to each other, no other job or machine can act on either member.
Scheduling algorithm
As others said, what you described is a problem, not an algorithm. There are many techniques you could use to solve your problem. Which one you should choose depends on your needs. If you need the optimal solution, you must use a technique called integer programming. If you want a very good solution, not necessarily the optimal one, there are many heuristics you could use.
Like they have said you are basically writing a 'scheduler'.
As your 'j' jobs seem to be having equal priority may be you are looking at 'Round robin - time sliced scheduling algorithm'.
The problem is a variant of the bin packing problem, which has a wider variety of literature than processor scheduling.
Typical real world OS multi-processor scheduling algorithms don't operate with knowledge of how the long jobs will take, and account for other issues such as memory affinity, and trading the scheduler's complexity with the benefit of scheduling.
I have encountered get this kind of problem in modular avionics systems where you are apportioning jobs to nodes, and there you do know the expected timing and memory requirements for their jobs prior to the jobs executing.
Sounds like a scheduler.
As other have said, it's a scheduler.
It's also a classic problem used to demonstrate OOPS development, and in particular it used to be used as a very common sample application for Smalltalk programming.

Resources