Skip to content

Commit

Permalink
create delegation algorithm
Browse files Browse the repository at this point in the history
  • Loading branch information
mat-ng committed Mar 20, 2024
1 parent b0e1b09 commit 5499269
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 0 deletions.
49 changes: 49 additions & 0 deletions backend/typescript/utilities/delegation-algorithm/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { sequelize } from "../../models";

import Application from '../../models/application.model';
import ApplicationDashboardModel from '../../models/applicationDashboard.model';
import User from '../../models/user.model';

import { roundRobinPairs, assignApplicationsToPairs } from './roundRobinPairs';


async function delegationAlgorithm() {
sequelize.authenticate();

const applications = await loadApplications();
const reviewers = await loadReviewers();

const uniquePairs = roundRobinPairs(reviewers);
const totalPairs = assignApplicationsToPairs(uniquePairs, applications);

await Promise.all(applications.map(async function (application, i) {
return Promise.all(totalPairs[i].map(async function (reviewer) {
await ApplicationDashboardModel.create({
applicationId: application.id,
reviewerId: reviewer.id,
reviewerEmail: reviewer.email,
passionFSG: 0,
teamPlayer: 0,
desireToLearn: 0,
skill: 0,
skillCategory: 'junior',
reviewerComments: '',
recommendedSecondChoice: 'N/A'
});
}))
}))
}

async function loadReviewers(): Promise<User[]> {
return await User.findAll({
attributes: ['id', 'email'],
});
}

async function loadApplications(): Promise<Application[]> {
return await Application.findAll({
attributes: ['id']
});
}

delegationAlgorithm();
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { isEqual } from 'lodash';

import Application from '../../models/application.model';
import User from '../../models/user.model';


// Generate a list of all unique pairs of users — from a given list of users
// Uses Round Robin algorithm for optimized time complexity
export function roundRobinPairs(developers: (User | {})[]): [User, User][] {
if (developers.length % 2 !== 0) {
developers.push({});
}

const fixedDeveloper = developers[0];
let rotatingDevelopers = developers.slice(1);
const pairs: [(User | {}), (User | {})][] = [];

for (let i = 0; i < developers.length - 1; i++) {
for (let j = 0; j < developers.length / 2 - 1; j++) {
if (!isEqual(rotatingDevelopers[j], {}) && !isEqual(rotatingDevelopers[developers.length - j - 2], {})) {
pairs.push([rotatingDevelopers[j], rotatingDevelopers[developers.length - j - 2]]);
}
}
if (!isEqual(fixedDeveloper, {}) && !isEqual(rotatingDevelopers[Math.floor(developers.length / 2) - 1], {})) {
pairs.push([fixedDeveloper, rotatingDevelopers[Math.floor(developers.length / 2) - 1]]);
}
rotatingDevelopers = rotatingDevelopers.slice(1).concat(rotatingDevelopers.slice(0, 1)); //rotate list
}

shuffleArray(pairs);
return pairs as [User, User][];
}

// Multiply pairs to equal the number of applications
export function assignApplicationsToPairs(pairs: [User, User][], applications: Application[]): [User, User][] {
const totalPairsNeeded = applications.length;
while (pairs.length < totalPairsNeeded) {
pairs.push(...pairs.slice(0, totalPairsNeeded - pairs.length));
}

shuffleArray(pairs);
return pairs;
}

// Shuffle a list of items
function shuffleArray<T>(array: T[]): void {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
}

0 comments on commit 5499269

Please sign in to comment.