Resource allocation- Matching - algorithm

I've got a problem which I'm not sure can be solved by Linear Programming. Essentially there are 2 groups of people who are list their preference for one another and will be subsequently matchd. I'm writing an algorithm for this. Group A has upto 4 choices from Group B and vice versa.
In formulating a solution, I am currently assigning a cost to each combination of pairs. For example if Person 1 from Group A ranks Person 3 from Group B as his/her number 1 choice and vice versa, then the cost is minimal (Pair 1-3 cost: 0.01). Similarly, I would allot a cost to other pairs, devising an objective function which seeks to have pairings which minimize overall cost.
However, I do not see this being feasible because I don't know how to define my constraints and overall objective function. Reading online and from textbooks, I find resource allocation problems to be different from what I am trying to do.
Can I seek your advise on how to proceed?

Your problem can be formulated as an "Assignment Problem." As a canonical case, assignment problems are for assigning "jobs" to "machines." They can just as easily be used for Matching two sets.
Here's the formulation:
Two sets of people A and B
Decision Variable Xij
Let Xij be 1 if person i (ith person in set A) is matched with jth person in set B; 0 otherwise
Parameters:
Let Cij be the cost of pairing person i with person j
Objective Function: Minimize (Sum over i) (sum over j) Cij * Xij
Constraints:
Every Person i gets paired exactly once
Sum over j Xij = 1 (for each i)
Every Person j gets paired exactly once
Sum over i Xij = 1 (for each j)
Xij are Binary variables
Xij = (0,1)
The neat thing about Assignment problems is that the optimal pairings can be found using the fairly easy to understand 'Hungarian Method.' You can also use an LP/IP solver you have at your disposal.
Hope that helps.

Related

Shortest time for everyone to get to the destination

I have to design an algorithm to solve a problem:
We have two groups of people (group A and group B, the number of people in group A is always less or equal to the number of people in group B), all standing in a one-dimensional line, each people have a corresponding number indicating its location. When the timer starts, each people in group A must find a partner in group B, but people in group B cannot move at all and each people in group B can only have at most 1 partner.
Suppose that people in group A move 1 unit/sec, how can I find the minimum time for everyone in group A to find a partner?
for example, if there are three people in group A with location {5,7,8}, and four people in group B with location {2,3,4,9}, the optimal solution would be 3 sec because max(5-3,7-4,9-8)=3
I could just use brute-force to solve it, but is there a better way of solving this problem?
This problem is a special case of the edit distance problem, and so a similar Dynamic Programming solution can be used to solve it. It's possible that a faster solution exists for this special case.
Let A = [a_0, a_1...,a_(m-1)] be the (sorted) positions of our m moving people, and B = [b_0, b_1...,b_(n-1)] be the n (sorted) destination spots, with m <= n. For the edit distance analogy, the allowed operations are:
Insert a number into A (free), or
Substitute an element a -> a' in A with cost |a-a'|.
We can solve this in O(n*m) time (plus sorting time of both A and B, if necessary).
We can define the dynamic programming via a cost function C(i, j) which is the minimum cost to move the first i people a_0, ... a_(i-1) using only the first j spots b_0, ... b_(j-1). You want C(m,n). Define C as follows:

Optimize event seat assignments with Corona restrictions

Problem:
Given a set of group registrations, each for a varying number of people (1-7),
and a set of seating groups (immutable, at least 2m apart) varying from 1-4 seats,
I'd like to find the optimal assignment of people groups to seating groups:
People groups may be split among several seating groups (though preferably not)
Seating groups may not be shared by different people groups
(optional) the assignment should minimize the number of 'wasted' seats, i.e. maximize the number of seats in empty seating groups
(ideally it should run from within a Google Apps script, so memory and computational complexity should be as small as possible)
First attempt:
I'm interested in the decision problem (is it feasible?) as well as the optimization problem (see optional optimization function). I've modeled it as a SAT problem, but this does not find an optimal solution.
For this reason, I've tried to model it as an optimization problem. I'm thinking along the lines of a (remote) variation of multiple-knapsack, but I haven't been able to name it yet:
items: seating groups (size -> weight)
knapsacks: people groups (size -> container size)
constraint: combined item weight >= container size
optimization: minimize the number of items
As you can see, the constraint and optimization are inverted compared to the standard problem. So my question is: Am I on the right track here or would you go about it another way? If it's correct, does this optimization problem have a name?
You could approach this as an Integer Linear Programming Problem, defined as follows:
let P = the set of people groups, people group i consists of p_i people;
let T = the set of tables, table j has t_j places;
let x_ij be 1 if people from people group i are placed at table j, 0 otherwise
let M be a large penalty factor for empty seats
let N be a large penalty factor for splitting groups
// # of free spaces = # unavailable - # occupied
// every time a group uses more than one table,
// a penalty of N * (#tables - 1) is incurred
min M * [SUM_j(SUM_i[x_ij] * t_j) - SUM_i(p_i)] + N * SUM_i[(SUM_j(x_ij) - 1)]
// at most one group per table
s.t. SUM_i(x_ij) <= 1 for all j
// every group has enough seats
SUM_j(x_ij * t_j) = p_i for all i
0 <= x_ij <= 1
Although this minimises the number of empty seats, it does not minimise the number of tables used or maximise the number of groups admitted. If you'd like to do that, you could expand the objective function by adding a penalty for every group turned away.
ILPs are NP-hard, so without the right solvers, it might not be possible to make this run with Google Apps. I have no experience with that, so I'm afraid I can't help you. But there are some methods to reduce your search space.
One would be through something called column generation. Here, the problem is split into two parts. The complex master problem is your main research question, but instead of the entire solution space, it tries to find the optimum from different candidate assignments (or columns).
The goal is then to define a subproblem that recommends these new potential solutions that are then incorporated in the master problem. The power of a good subproblem is that it should be reducable to a simpler model, like Knapsack or Dijkstra.

Assignment problem with multiple persons needed on each job

First, sorry if my English isn't so good, I'm not a native English speaker.
I'm facing an assignment problem.
I have a list of jobs, with a certain number of persons needed for each job. Each person will let me know on how many jobs they want to be and their preferences.
I tried to do that with the Hungarian Algorithm but it seems I'm unable to get it done. With a large number of jobs and spots, some persons got multiple time the same job, which isn't ok.
I think it's all due to the fact I considered each spot as an individual job and I listed each person as many times as they need to be placed.
Do you know a better algorithm or a way to do it?
(It's not a coding problem, I'm doing it in Octave/Matlab for now, but I think I'll switch to Python.)
Thanks for your help.
In addition to Henrik's suggestion to use Linear Programming, your specific problem can also be solved using Minimum cost maximum flow.
You make a bipartite graph between people and jobs (like in the Hungarian algorithm), where the cost on the middle edges are the preference scores, and the capacity is 1.
The capacity of the edges from the jobs to the sink is the number of people you need for that job.
Assignment problems can be solved with linear programming:
Let xij = 1 if person i is assigned to job j and 0 otherwise. Let aij be the rank for person i of job j : aij = 1 for the job he wants most, aij = 2 for the next and so on. If he only wants k jobs you put aij to a very high number for all jobs beyond those k.
If you need at least bj workers on job j you have the constraint
x1j + ... + xmj >= bj (j = 1,...,n)
You also have the constraints xij >= 0 and xij <= 1 .
The linear function to minimize is
sum( aij xij ) over all i,j

Efficient divide-and-conquer algorithm

At a political event, introducing 2 people determines if they represent the same party or not.
Suppose more than half of the n attendees represent the same party. I'm trying to find an efficient algorithm that will identify the representatives of this party using as few introductions as possible.
A brute force solution will be to maintain two pointers over the array of attendees, introducing n attendees to n-1 other attendees in O(n2) time. I can't figure out how to improve on this.
Edit: Formally,
You are given an integer n. There is a hidden array A of size n, such that more than half of the values in A are the same. This array represents the party affiliation of each person.
You are allowed queries of the form introduce(i, j), where i≠j, and 1 <= i, j <= n, and you will get a boolean value in return: You will get back 1, if A[i] = A[j], and 0 otherwise.
Output: B ⊆ [1, 2. ... n] where |B| > n/2 and the A-value of every element in B is the same.
Hopefully this explains the problem better.
This can be done in O(n) introductions using the Boyer–Moore majority vote algorithm.
Consider some arbitrary ordering of the attendees: A_1, A_2, ..., A_n. In the algorithm, you maintain a 'stored element', denoted by m. Whenever the algorithm wants to check if the current element (x) is same as the stored element or not, you introduce those two people and increment or decrement the counter accordingly. The stored element at the end will be a member of the majority party. Then, you can do another pass over all the other n - 1 people, and introduce each of them to this known person and hence find all the members of the majority party.
Thus, the total number of introductions is O(n).

Formulating a knapsack style solution for spoj "BEHAPPY"?

The problem is described at problem ,I have been trying to reach an iterative dp solution to the above problem.
What i can guess from my experience in coding is ,it should have three dimensions, each state uniquely identified by :-
M = Gifts not distributed yet.
N = first N girlfriends available (Similar to 0-1 Knapsack)
C = Maximum gifts allowable for current girlfriend.
Now initializing for M=0,N,C (i.e. When 0 gifts remain to be distributed)
1 2 3 4 (girlfriends)
0
1
2
3
(Capacity)
I seem to have a problem , with initialization at k=0 as there is a low and high gift limit both for girlfriends ,hence deviating from standard knapsack having only maximum limit(not considering that knapsack finds optimum solution,and here i consider all possible solution)
Of course i maybe completely on the wrong path here ,if you feel is the case, what is the recurrence and initialization for this 3 state variable dp?
Thanks in advance
First remove all the minimum requirements. M -= sum(A[i]) and B[i] -= A[i]. These are the minimum so there's nothing for us to move around, just assign them and take them out of the computation.
Now your solution matrix sol[g, m] is the number of ways you can solve the first g girlfriends while having m gifts left. sol[g,m] = sum(sol[g-1, m-j], j= [0..B[g-1]]. You initialize sol[0, M] with 1 and the rest is 0.
Your solution will be sol[N+1, 0].
You only need the last line if you do it iteratively.

Resources