Skip to content

Commit

Permalink
new changes
Browse files Browse the repository at this point in the history
  • Loading branch information
valde148 committed Sep 25, 2024
1 parent 01f8248 commit 35e2bb6
Show file tree
Hide file tree
Showing 2 changed files with 176 additions and 128 deletions.
117 changes: 115 additions & 2 deletions README.me
Original file line number Diff line number Diff line change
@@ -1,3 +1,116 @@
Todo:
- Armando - values to test on
- Armando- Questions
- Armando/El - values to test on
- Armando/El- Questions
The conclusion

Test Case 1: Programmers & Companies
Programmer Preferences:
Programmer 1: [0, 1, 2]
Programmer 2: [1, 0, 2]
Programmer 3: [2, 0, 1]

Company Preferences:
Company A: [1, 0, 2]
Company B: [0, 1, 2]
Company C: [2, 1, 0]
Algorithm Execution:
Step 1:
Programmer 1 picks Company A their top choice.
Company A accepts , they are free.
Step 2:
Programmer 2 picks Company B their top choice.
Company B accepts, since they are free.
Step 3:
Programmer 3 picks Company C their top choice.
Company C accepts, since they are free.
Final Matching:
Programmer 1 is matched with Company A
Programmer 2 is matched with Company B
Programmer 3 is matched with Company C


Test Case 2 : Programmers & Companies
Programmer Preferences:
Programmer 1: [0, 1, 2]
Programmer 2: [2, 1, 0]
Programmer 3: [1, 2, 0]

Company Preferences:
Company A: [1, 2, 0]
Company B: [0, 1, 2]
Company C: [2, 0, 1]
Steps:
Programmer 1 asks Company A, and Company A accepts.
Programmer 2 asks Company C, and Company C accepts.
Programmer 3 asks Company B, and Company B acce pts.
Final Matching:
Programmer 1 matched with Company A
Programmer 2 matched with Company C
Programmer 3 matched with Company B


Test Case 3: Larger Dataset (5 Programmers, 5 Companies)
Programmer Preferences:
Programmer 1: [1, 0, 2, 3, 4]
Programmer 2: [0, 1, 3, 4, 2]
Programmer 3: [2, 0, 1, 4, 3]
Programmer 4: [4, 3, 2, 1, 0]
Programmer 5: [0, 2, 3, 1, 4]

Company Preferences:
Company A: [1, 2, 3, 4, 0]
Company B: [0, 3, 1, 2, 4]
Company C: [2, 4, 1, 0, 3]
Company D: [4, 2, 1, 0, 3]
Company E: [0, 1, 2, 4, 3]

Fianl mathcing:
Programmer 1 matched with Company B
Programmer 2 matched with Company A
Programmer 3 matched with Company C
Programmer 4 matched with Company E
Programmer 5 matched with Company D


Why the Algorithm is Correct?
The Algorithm Always Stops,
The algorithm will always come to an end because each programmer only gets to ask each company
one time whether they can work there. There are a fixed number of programmers and companies,
and each programmer can only ask each company once. If a programmer gets rejected, they move on
to the next company in their list. Eventually, all programmers will either get a job at a company,
or they will have asked all the companies and the process will end. The worst case is that every
programmer asks every company, but the process won’t go on forever.The pairing we get at the end
is "satisfactory" because we don’t have any situations where:

A programmer is unhappy with their job and prefers a different company.
The company also prefers that programmer over the person they currently hired.

Programmers apply to the companies they like best first.
Companies don’t immediately accept all applications. They hold out for the best option based on who
has applied. If they find someone they like more than their current hire, they drop the old one and
take the new person. This way, companies always end up with the best programmer they could get, and
programmers end up with the best company that accepted them. This guarantees that no programmer or
company would rather switch to another option after the process is done. This approach is based on
a famous method called the Gale Shapley algorithm. It’s been mathematically proven to always find a
solution where no one is unhappy enough to want to switch to a stable solution. The way it works is
by having programmers "apply" to companies and companies only saying "yes" if it’s a good option for
them. Because of the way this back and forth works, the final result will always be a stable match.
Since the programmers are the ones doing the asking, the final result tends to be better for them.
Each programmer gets the best company that they could possibly get based on how companies respond.
The algorithm will always stop because each programmer has a limited number of companies they can
apply to. It will always give a result where no one would want to swap with someone else after the
matching is done. This approach is based on a well-proven theory (Gale Shapley) that ensures the
matching will be stable. The programmers get the best possible deal for themselves. So, the algorithm
works because it’s designed to reach a fair solution for everyone and it can’t go on forever.

the worst case, the number of steps it takes grows with the square of
the number of participants (programmers and companies). This happens
because each programmer might have to go through all the companies before
finding a match, and each company may have to consider multiple proposals
before choosing the best one. So, if there are 10 programmers and 10 companies,
the algorithm could take up to 100 steps. The space complexity is also O(N²)
because the program needs to store all the preferences for both the programmers
and companies, which adds up quickly as more participants are added. This means
the program will take more memory and time as the number of participants increases


187 changes: 61 additions & 126 deletions main.java
Original file line number Diff line number Diff line change
@@ -1,171 +1,106 @@
// Armando and El
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

class main{
public static void main(String[] args){
char[] alphabet = {'a','b','c','d','e','f','g','h','i','j'};

//test 3x3
//user entries:
//int[][] companyPreferences1 = {{2, 3, 1}, {1, 2, 3}, {3, 2, 1}}; //this is what is entered on the user side
//char[][] programerPreferences1 = {{'a','b','c'}, {'c','b','a'}, {'b','c','a'}}; //this is what is entered on the user side
//what the program receives:
//index equivalents of intended matches
int[][] companyPreferencesTranslated1 = {{1, 2, 0}, {0, 1 , 2}, {2, 1, 0}};
int[][] programerPreferencesTranslated1 = {{0,1,2},{2,1,0},{1,2,0}};
int[] expected = {1, 0, 0, 1, 2, 2};
int[] returned = match(companyPreferencesTranslated1, programerPreferencesTranslated1);
System.out.println("test one status:" + (Arrays.equals(expected, returned)));

//test 2x2
//int[][] companyPreferences2 = {{1,2},{1,2}};
//char[][] programerPreferences2 = {{'a','b'},{'b','a'}};
int[][] companyPreferencesTranslated2 = {{0,1},{0,1}};
int[][] programerPreferencesTranslated2 = {{0,1},{1,0}};
int[] expected2 = {0, 0, 1, 1};
int[] returned2 = match(companyPreferencesTranslated2, programerPreferencesTranslated2);
System.out.println("test two status:" + (Arrays.equals(expected2, returned2)));

class Main {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
System.out.println("Enter amount of Programers: ");
System.out.println("Enter number of Programmers & Companies: ");
int pro = s.nextInt();

//array constructors
char[][] programerPreferencesScanner = new char[pro][pro];
int[][] companyPreferencesScanner = new int[pro][pro];
int[][] companyPreferencesTranslatedScanner = new int[pro][pro];
int[][] programerPreferences = new int[pro][pro];
int[][] companyPreferences = new int[pro][pro];
char[] alphabet = {'a', 'b', 'c', 'd', 'e', 'f', 'g'}; //these are the lables of the companies

// processes first input for programer preferences
String inputString1 = s.nextLine().toLowerCase();
char[] input1 = inputString1.toCharArray();
for (int j = 0; j < input1.length; j++) {
programerPreferencesScanner[1][j] = input1[j];
}
//processes rest of inputs
for (int i = 0; i < pro; i++) {
System.out.println("insert programer " + (i+1) + "'s preferences \nplease enter on one line with no spaces or commas");
String inputString = s.nextLine().toLowerCase();
char[] input = inputString.toCharArray();
for (int j = 0; j < input.length; j++) {
programerPreferencesScanner[i][j] = input[j];
// the input preferences for programmer
for(int i = 0; i < pro; i++){
System.out.println("put pref for programmer " + (i+1) + " (enter " + pro + " values):");
for(int j = 0; j < pro; j++){
programerPreferences[i][j] = s.nextInt();
}
}

//processes inputs for company preferences
for (int i = 0; i < pro; i++) {
System.out.println("insert preferences for company " + alphabet[i] + "\nplease enter each programer id number on a new line");
for (int j = 0; j < pro; j++) {
companyPreferencesScanner[i][j] = s.nextInt();
companyPreferencesTranslatedScanner[i][j] = companyPreferencesScanner[i][j] -1;

// the input preferences for companies
for(int x = 0; x < pro; x++){
System.out.println("put pref for company " + alphabet[x] + " (enter " + pro + " values, where a=0, b=1, c=2, etc.):");
for(int y = 0; y < pro; y++){
companyPreferences[x][y] = s.nextInt();
}
}
//ends scanner
s.close();
//translates user imputed programer preferences to something our method understands
int[][] programerPreferencesTranslated = translator(programerPreferencesScanner);
//calls match method
int[] matches = match(companyPreferencesTranslatedScanner, programerPreferencesTranslated);

//print statements
System.out.println("Preferences in Array form \nprogramers: companies:");
int[] matches = match(programerPreferences, companyPreferences);

// displaying the prefrences
for (int i = 0; i < pro; i++) {
int programerId = i + 1;
// String c = Integer.toString(i + 1);
System.out.println(programerId + Arrays.toString(programerPreferencesScanner[i]) + " " + alphabet[i] + Arrays.toString(companyPreferencesScanner[i]));
}
for (int i = 0; i < matches.length; i++) {
if(i % 2 == 0) {
System.out.println("Match #"+ (i/2 + 1));
System.out.println(matches[i] +1);
} else {
System.out.println(alphabet[matches[i]]);
}
System.out.println((i+1) + Arrays.toString(programerPreferences[i]) + " " + alphabet[i] + Arrays.toString(companyPreferences[i]));
}
}

public static int[][] translator(char[][] companyPreferences){
//takes character array and converts it to integers where a = 0, b = 1, c = 2, etc...
// logic to make everything lowercase is handled in scanner
int[][] companyPreferencesTranslated = new int[companyPreferences.length][companyPreferences[0].length];
for (int i = 0; i < companyPreferences.length; i++) {
for (int j = 0; j < companyPreferences[0].length; j++) {
char c = companyPreferences[i][j];
int n = c - 97;
companyPreferencesTranslated[i][j] = n;
}
// thiw is the matching results
System.out.println("\nMatching results:");
for (int i = 0; i < matches.length; i++) {
System.out.println("Programmer " + (matches[i] + 1) + " matched with Company " + alphabet[i]);
}
return companyPreferencesTranslated;
}

// the matching algorithm
static int[] match(int[][] programerPreferences, int[][] companyPreferences) {
// array construction
// temp tracks current pairs
// programersFree and companiesFree track who is not paired
// stillFree tracks who is still free
Map<Integer, Integer> temp = new HashMap<>();
int size = programerPreferences.length;
Map<Integer, Integer> matches = new HashMap<>();
boolean[] programersFree = new boolean[size];
boolean[] companiesFree = new boolean[size];
Arrays.fill(programersFree, true);
Arrays.fill(companiesFree, true);
ArrayList<Integer> stillFree = new ArrayList<>();

while(stillFree.size() + temp.size() < size){ //while there is still unpaired people
for (int i = 0; i < companiesFree.length; i++) { // go through free companies
if (programersFree[i]) { //if the a programer is free
for(int j = 0; j < size; j++){ //for each of the companies they are interested in
if (companiesFree[programerPreferences[i][j]]) { //if the company is free
temp.put(programerPreferences[i][j], i); // log pair
programersFree[i] = false; //mark taken
companiesFree[programerPreferences[i][j]] = false; // mark taken
while (matches.size() < size) {
for (int i = 0; i < size; i++) {
if (programersFree[i]) {
//the programmer i ask to their next preferred company
for (int j = 0; j < size; j++) {
int company = programerPreferences[i][j];
if (companiesFree[company]) {
// the company if avalible, they accept the proposal
matches.put(company, i);
programersFree[i] = false;
companiesFree[company] = false;
break;
} else {
int possibleProgramer = programerPreferences[i][j]; //else record index of programer
boolean match = checkMatch(possibleProgramer, i , programerPreferences[i][j], companyPreferences); //check if possibleProgram has higher interest from company than current hire
if(!match){
// replace current match with new programer
temp.put(programerPreferences[i][j], i);
// the company already has a programmer, they will see if they prefer the new one
int currentProgrammer = matches.get(company);
boolean preferNew = checkMatch(currentProgrammer, i, company, companyPreferences);
if (preferNew) {
//the company switches to the new programmer if it is a better choice
matches.put(company, i);
programersFree[i] = false;
programersFree[possibleProgramer] = true;
programersFree[currentProgrammer] = true;
break;
}
}
}
if (programersFree[i]) {
//log that programer needs to go through the process again
stillFree.add(i);
}
}
}
}
// puts matched pairs from the hashMap to an array to be returned
int[] matchedPairs = new int[2*temp.size()];
int i = 0;
for(Map.Entry<Integer, Integer> entry : temp.entrySet()) {
matchedPairs[i] = entry.getValue();
i++;
matchedPairs[i] = entry.getKey();
i++;
}
}

int[] matchedPairs = new int[size];
for (Map.Entry<Integer, Integer> entry : matches.entrySet()) {
matchedPairs[entry.getKey()] = entry.getValue();
}
return matchedPairs;
}

static boolean checkMatch(int possibleProgramer, int currentProgramer, int company, int[][] companyPreferences) {
int p = 0; //index of possible possibleProgramer
int c = 0; //index of currentProgramer
for (int i = 0; i < companyPreferences.length; i++) {
//for each of the programers the company is interested in, record if the possibleProgramer or current hire is higher
if(companyPreferences[company][i] == possibleProgramer) {
p = i;
} else if (companyPreferences[company][i] == currentProgramer){
c = i;
// it will check if the company wants the new programmer over the last pick
static boolean checkMatch(int currentProgrammer, int newProgrammer, int company, int[][] companyPreferences) {
for (int i = 0; i < companyPreferences[company].length; i++) {
if (companyPreferences[company][i] == newProgrammer) {
return true; // new programmer is picked over the last one
}
if (companyPreferences[company][i] == currentProgrammer) {
return false; // if the current programmer is picked
}
}
return p < c; // respond if the possible programer is of higher interest
return false;
}
}
}

0 comments on commit 35e2bb6

Please sign in to comment.