diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/AI-Project.iml b/.idea/AI-Project.iml new file mode 100644 index 0000000..d0876a7 --- /dev/null +++ b/.idea/AI-Project.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..75eb357 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,12 @@ + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..dc9ea49 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..d9de2ef --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Project/.idea/.name b/Project/.idea/.name new file mode 100644 index 0000000..11a5d8e --- /dev/null +++ b/Project/.idea/.name @@ -0,0 +1 @@ +main.py \ No newline at end of file diff --git a/Project/.idea/sonarlint/issuestore/7/2/7224b3c30ce37886fed765e0e8a4dd24c17dddcb b/Project/.idea/sonarlint/issuestore/7/2/7224b3c30ce37886fed765e0e8a4dd24c17dddcb new file mode 100644 index 0000000..e69de29 diff --git a/Project/.idea/sonarlint/issuestore/b/e/be7d121bab467f6cfe8bb830b59a501e45e1f171 b/Project/.idea/sonarlint/issuestore/b/e/be7d121bab467f6cfe8bb830b59a501e45e1f171 new file mode 100644 index 0000000..e69de29 diff --git a/Project/.idea/sonarlint/issuestore/f/1/f1bdda93d9a278e358509d498e17d97764c1fb29 b/Project/.idea/sonarlint/issuestore/f/1/f1bdda93d9a278e358509d498e17d97764c1fb29 new file mode 100644 index 0000000..771563f --- /dev/null +++ b/Project/.idea/sonarlint/issuestore/f/1/f1bdda93d9a278e358509d498e17d97764c1fb29 @@ -0,0 +1,10 @@ + +m python:S1192("NDefine a constant instead of duplicating this literal 'Montserrat 25' 3 times.(80 +f python:S2208"GImport only needed names or import the module and then use its members.(80 += python:S125>"Remove this commented out code.(80 +J python:S1172K"+Remove the unused function parameter "men".(ޡ80 +X python:S1172K"9Remove the unused function parameter "preferences_women".(ޡ80 +G python:S1481N"(Remove the unused local variable "man2".(Ĕ80 +G python:S1481L")Remove the unused local variable "wives".(80 +I python:S1481q"%Remove the unused local variable "x".(֠Ȗ80 +I python:S1481s"%Remove the unused local variable "x".(80 \ No newline at end of file diff --git a/Project/.idea/sonarlint/issuestore/index.pb b/Project/.idea/sonarlint/issuestore/index.pb new file mode 100644 index 0000000..fca9d9a --- /dev/null +++ b/Project/.idea/sonarlint/issuestore/index.pb @@ -0,0 +1,7 @@ + += + input_men.txt,b\e\be7d121bab467f6cfe8bb830b59a501e45e1f171 +? +input_women.txt,7\2\7224b3c30ce37886fed765e0e8a4dd24c17dddcb +7 +main.py,f\1\f1bdda93d9a278e358509d498e17d97764c1fb29 \ No newline at end of file diff --git a/Project/alg.png b/Project/alg.png new file mode 100644 index 0000000..fcf8086 Binary files /dev/null and b/Project/alg.png differ diff --git a/Project/back_arrow.png b/Project/back_arrow.png new file mode 100644 index 0000000..e1507aa Binary files /dev/null and b/Project/back_arrow.png differ diff --git a/Project/backtracking.py b/Project/backtracking.py new file mode 100644 index 0000000..12e2f54 --- /dev/null +++ b/Project/backtracking.py @@ -0,0 +1,97 @@ +from numpy import * +import time +import random + +N = 0 +states = list() +solutions_bkt = list() +output_solutions = list() +count = 0 +counter = 1 + + +def ok(q_dict: list, col: int, mp, wp): + for i in range(0, col): + if q_dict[col] == q_dict[i]: + return False + + for i in range(0, col): + if q_dict[col] == q_dict[i]: + return False + + for i in range(0, col): + if (mp[i][q_dict[col]] < mp[i][q_dict[i]]) and (wp[q_dict[col]][i] < wp[q_dict[col]][col]): + return False + if (mp[col][q_dict[i]] < mp[col][q_dict[col]]) and (wp[q_dict[i]][col] < wp[q_dict[i]][i]): + return False + return True + + +def show(q_dict): + global count + count += 1 + for i in range(0, N): + for j in range(0, N): + if q_dict[i] == j: + print("Man ", i, " is matched with woman ", j) + + +def get_state(q_dict, sol): + global count + state = dict() + count += 1 + for i in range(0, N): + for j in range(0, N): + if q_dict[i] == j: + state[i] = j + return state, sol + + +def append_state(q_dict, sol): + global states + states.append((get_state(q_dict, sol))) + + +def append_to_output_possible_solutions(q_dict): + global output_solutions + global counter + state = dict() + counter += 1 + for i in range(0, N): + for j in range(0, N): + if q_dict[i] == j: + state[str(i + 1)] = chr(ord('@') + j + 1) + # print(state) + output_solutions.append(state) + + +def move(q_dict, i, mp, wp): + # create state + if i == N: + append_state(q_dict, 1) + # print("q", q_dict) + solutions_bkt.append(get_state(q_dict, 1)) + append_to_output_possible_solutions(q_dict) + # show(q_dict) + return + append_state(q_dict, 0) + for j in range(0, N): + q_dict[i] = j + if ok(q_dict, i, mp, wp): + move(q_dict, i + 1, mp, wp) + + +def bkt_approach(couples, mp, wp): + global N + N = couples + q = [0] * N + + move(q, 0, mp, wp) + time.sleep(3) + return random.choice(output_solutions), 0 + + +if __name__ == "__main__": + mp = array([[0, 2, 1], [0, 2, 1], [1, 2, 0]]) + wp = array([[2, 1, 0], [0, 1, 2], [2, 0, 1]]) + print(bkt_approach(3, mp, wp)) diff --git a/Project/lines.png b/Project/lines.png new file mode 100644 index 0000000..d5d6d23 Binary files /dev/null and b/Project/lines.png differ diff --git a/Project/main.py b/Project/main.py index 07b5cf7..bd02fd2 100644 --- a/Project/main.py +++ b/Project/main.py @@ -1,4 +1,7 @@ from tkinter import * +from Project.backtracking import * +import random +from PIL import Image, ImageTk # FII - AI Project # Ciuta Andrei Calin @@ -7,9 +10,373 @@ # Volentir Alexandra root = Tk() -myLabel = Label(root, text="Welcome!") -myLabel.pack() -root.mainloop() +f1 = Frame(root) +f2 = Frame(root) +f3 = Frame(root) +f4 = Frame(root) +f5 = Frame(root) +f6 = Frame(root) + + +def raise_frame(frame): + frame.tkraise() + + +def show_solution(solution, number_of_couples, solving_method): + # print(solution) + for widgets in f6.winfo_children(): + widgets.destroy() + root.geometry("1024x768") + root.configure(bg='#FFBBBC') + f6.configure(bg='#FFBBBC') + + home_btn = Button(f6, text="Home", borderwidth=0, bg="#FFBBBC", fg='#000000', font='Montserrat 14 bold', + command=home) + home_btn.pack(padx=590, pady=50) + + faq_btn = Button(f6, text="FAQ", borderwidth=0, bg="#FFBBBC", fg='#000000', font='Montserrat 14 bold', + command=faq) + faq_btn.place(x=700, y=50) + match_img = PhotoImage(file="make_a_match_btn.png") + match_btn = Button(f6, image=match_img, borderwidth=0, bg="#FFBBBC", command=match) + match_btn.place(x=780, y=40) + title = "The solution using " + solving_method + " is:" + Label(f6, text=title, borderwidth=0, bg="#FFBBBC", fg='#F04755', font='Montserrat 25 bold').place(x=300, y=100) + y_man = 200 + y_woman = 200 + men_images = [] + women_images = [] + for key, value in solution.items(): + man_image = PhotoImage(file="man1.png") + Label(f6, text=key, borderwidth=0, bg="#FFBBBC", fg='#F04755', font='Montserrat 15 bold', image=man_image, + compound='center').place(x=350, y=y_man) + y_man = y_man + 50 + men_images.append(man_image) + Label(f6, text="is married to", borderwidth=0, bg="#FFBBBC", fg='#F04755', font='Montserrat 16 bold').place( + x=450, + y=y_woman + 5) + woman_image = PhotoImage(file="woman1.png") + Label(f6, text=value, borderwidth=0, bg="#FFBBBC", fg='#F04755', font='Montserrat 15 bold', + image=woman_image, compound='center').place(x=650, y=y_woman) + y_woman = y_woman + 50 + women_images.append(woman_image) + + Label(f6, text="Ⓒ UAIC team", borderwidth=0, bg="#FFBBBC", fg='#F04755', font='Montserrat 16 bold').place(x=450, + y=730) + + raise_frame(f6) + root.mainloop() + + +def input_from_user_is_correct(preferences_men, preferences_women, number_of_couples): + men_correct = [] + women_correct = [] + print(preferences_men) + print(preferences_women) + for index in range(1, int(number_of_couples) + 1): + men_correct.append(str(index)) + women_correct.append(str(chr(index + 64))) + men_correct.sort() + women_correct.sort() + print(men_correct) + print(women_correct) + for man, list_of_preferences in preferences_men.items(): + new_list=list_of_preferences.copy() + new_list.sort() + if new_list != women_correct: + return False + for woman, list_of_preferences in preferences_women.items(): + new_list = list_of_preferences.copy() + new_list.sort() + if new_list != men_correct: + return False + return True + + +def choose_preferences(number_of_couples, solving_method): + for widgets in f5.winfo_children(): + widgets.destroy() + root.geometry("1024x768") + root.configure(bg='#FFBBBC') + f5.configure(bg='#FFBBBC') + + home_btn = Button(f5, text="Home", borderwidth=0, bg="#FFBBBC", fg='#000000', font='Montserrat 14 bold', + command=home) + home_btn.pack(padx=600, pady=50) + Label(f5, text="Set the preferences using the format: for men and <1,2,3> for women.", borderwidth=0, bg="#FFBBBC", fg='#F04755', font='Montserrat 14 bold').place( + x=150, y=100) + + Label(f5, text="Men", borderwidth=0, bg="#FFBBBC", fg='#F04755', font='Montserrat 25 bold').place(x=200, y=150) + Label(f5, text="Women", borderwidth=0, bg="#FFBBBC", fg='#F04755', font='Montserrat 25 bold').place(x=700, y=150) + + faq_btn = Button(f5, text="FAQ", borderwidth=0, bg="#FFBBBC", fg='#000000', font='Montserrat 14 bold', + command=faq) + faq_btn.place(x=700, y=50) + match_img = PhotoImage(file="make_a_match_btn.png") + match_btn = Button(f5, image=match_img, borderwidth=0, bg="#FFBBBC", command=match) + match_btn.place(x=780, y=40) + entry_array_men = [] + entry_array_women = [] + + def create_preferences(): + preferences_men = {} + preferences_women = {} + + index = 1 + for entry in entry_array_men: + string_list = entry.get() + local_pref = string_list.split(',') + preferences_men[str(index)] = local_pref + index += 1 + index = 1 + for entry in entry_array_women: + string_list = entry.get() + local_pref = string_list.split(',') + preferences_women[chr(index + 64)] = local_pref + index += 1 + + if input_from_user_is_correct(preferences_men, preferences_women, number_of_couples) is True: + print("AICI") + print(input_from_user_is_correct(preferences_men, preferences_women, number_of_couples)) + print(preferences_men, + preferences_women) + men_list, women_list = solve_problem(preferences_men, preferences_women, solving_method) + show_solution(men_list, number_of_couples, solving_method) + else: + Label(f5, text="The input is incorrect!", borderwidth=0, bg="#FFBBBC", fg='#F04755', + font='Montserrat 16 bold').place(x=400, y=650) + + y = 200 + + for index in range(1, int(number_of_couples) + 1): + Label(f5, text=index, borderwidth=0, bg="#FFBBBC", fg='#F04755', font='Montserrat 16 bold').place(x=100, y=y) + entry_man = Entry(f5) + entry_man.place(x=130, y=y) + entry_man.config(borderwidth=0, highlightbackground='#F04755', highlightthickness=3, bg="#FFFFFF", fg='#F04755', + font='Montserrat 14 bold') + entry_array_men.append(entry_man) + + Label(f5, text=chr(index + 64), borderwidth=0, bg="#FFBBBC", fg='#F04755', font='Montserrat 16 bold').place( + x=650, y=y) + entry_woman = Entry(f5) + entry_woman.place(x=670, y=y) + entry_woman.config(borderwidth=0, highlightbackground='#F04755', highlightthickness=3, bg="#FFFFFF", + fg='#F04755', + font='Montserrat 14 bold') + entry_array_women.append(entry_woman) + y = y + 50 + + submit_img = PhotoImage(file="submit.png") + submit_btn = Button(f5, image=submit_img, borderwidth=0, bg="#FFBBBC", command=create_preferences) + submit_btn.place(x=450, y=670) + + Label(f5, text="Ⓒ UAIC team", borderwidth=0, bg="#FFBBBC", fg='#F04755', font='Montserrat 16 bold').place(x=450, + y=730) + + raise_frame(f5) + root.mainloop() + + +def random_preferences(number_of_couples, solving_method): + preferences_men = {} + preferences_women = {} + list_of_men = [] + list_of_women = [] + for index in range(1, int(number_of_couples) + 1): + list_of_men.append(str(index)) + list_of_women.append(chr(index + 64)) + for man in list_of_men: + random.shuffle(list_of_women) + preferences_men[man] = list(list_of_women) + for woman in list_of_women: + random.shuffle(list_of_men) + preferences_women[woman] = list(list_of_men) + men_list, women_list = solve_problem(preferences_men, preferences_women, solving_method) + show_solution(men_list, number_of_couples, solving_method) + + +def submit_preferences(number_of_couples, solving_method, preferences): + print(number_of_couples) + print(solving_method) + print(preferences) + if preferences == "Manual": + choose_preferences(number_of_couples, solving_method) + else: + random_preferences(number_of_couples, solving_method) + + +def match(): + print("pressed the match") + for widgets in f4.winfo_children(): + widgets.destroy() + root.geometry("1024x768") + root.configure(bg='#FFBBBC') + f4.configure(bg='#FFBBBC') + + Label(f4, text="Number of couples", borderwidth=0, bg="#FFBBBC", fg='#F04755', font='Montserrat 25 bold').pack( + side=TOP, anchor=W, padx=300, pady=250) + Label(f4, text="Solving method", borderwidth=0, bg="#FFBBBC", fg='#F04755', font='Montserrat 25 bold').place(x=300, + y=350) + Label(f4, text="Preferences", borderwidth=0, bg="#FFBBBC", fg='#F04755', font='Montserrat 25 bold').place(x=330, + y=450) + + couples_variable = StringVar(f4) + couples_variable.set("1") + couples = OptionMenu(f4, couples_variable, "1", "2", "3", "4", "5", "6", "7", "8", "9", "10") + couples.place(x=630, y=250) + couples.config(borderwidth=0, highlightbackground='#F04755', highlightthickness=3, bg="#FFFFFF", fg='#F04755', + font='Montserrat 14 bold') + + solving_method_variable = StringVar(f4) + solving_method_variable.set("Greedy") + method = OptionMenu(f4, solving_method_variable, "Greedy", "Backtracking") + method.place(x=580, y=355) + method.config(borderwidth=0, highlightbackground='#F04755', highlightthickness=3, bg="#FFFFFF", fg='#F04755', + font='Montserrat 14 bold') + + preferences_variable = StringVar(f4) + preferences_variable.set("Random") + preferences = OptionMenu(f4, preferences_variable, "Random", "Manual") + preferences.place(x=565, y=455) + preferences.config(borderwidth=0, highlightbackground='#F04755', highlightthickness=3, bg="#FFFFFF", fg='#F04755', + font='Montserrat 14 bold') + + submit_img = PhotoImage(file="submit.png") + submit_btn = Button(f4, image=submit_img, borderwidth=0, bg="#FFBBBC", + command=lambda: submit_preferences(couples_variable.get(), solving_method_variable.get(), + preferences_variable.get())) + submit_btn.place(x=450, y=550) + + Label(f4, text="Ⓒ UAIC team", borderwidth=0, bg="#FFBBBC", fg='#F04755', font='Montserrat 16 bold').place(x=450, + y=730) + + home_btn = Button(f4, text="Home", borderwidth=0, bg="#FFBBBC", fg='#000000', font='Montserrat 14 bold', + command=home) + home_btn.place(x=600, y=50) + faq_btn = Button(f4, text="FAQ", borderwidth=0, bg="#FFBBBC", fg='#000000', font='Montserrat 14 bold', + command=faq) + faq_btn.place(x=700, y=50) + + match_img = PhotoImage(file="make_a_match_btn.png") + match_btn = Button(f4, image=match_img, borderwidth=0, bg="#FFBBBC", command=match) + match_btn.place(x=780, y=40) + + raise_frame(f4) + root.mainloop() + + +def faq(): + for widgets in f3.winfo_children(): + widgets.destroy() + root.geometry("1024x768") + root.configure(bg='#FFBBBC') + f3.configure(bg='#FFBBBC') + + Label(f3, text="Questions and Answers", borderwidth=0, bg="#FFBBBC", fg='#F04755', font='Montserrat 25 bold').pack( + side=TOP, anchor=W, padx=100, pady=130) + Label(f3, + text=" Q: What is the stable marriage problem? \n A: Ahe stable marriage problem (also stable matching problem " + "or SMP) is the problem of finding \n a stable matching between two equally sized sets of elements given an" + " ordering of preferences \n for each element. \n\n Q: What is a Greedy Algorithm? \n A: A greedy algorithm" + " is any algorithm that follows the problem-solving heuristic of making \n the locally optimal choice at " + "each stage. In many problems, a greedy strategy does not \n produce an optimal solution, but a greedy " + "heuristic can yield locally optimal solutions that \n approximate a globally optimal solution in a reasonable " + "amount of time. \n\n Q: What is Backtracking? \n A: Backtracking is a class of algorithms for finding " + "solutions to some computational \n problems, notably constraint satisfaction problems, that incrementally " + "builds candidates to \n the solutions, and abandons a candidate (backtracks) as soon as it determines that" + " the \n candidate cannot possibly be completed to a valid solution", + borderwidth=0, bg="#FFBBBC", fg='#F04755', font=('Montserrat 16'), justify=LEFT).place(x=70, y=250) + + home_btn = Button(f3, text="Home", borderwidth=0, bg="#FFBBBC", fg='#000000', font='Montserrat 14 bold', + command=home) + home_btn.place(x=600, y=50) + faq_btn = Button(f3, text="FAQ", borderwidth=0, bg="#FFBBBC", fg='#000000', font='Montserrat 14 bold', + command=faq) + faq_btn.place(x=700, y=50) + match_img = PhotoImage(file="make_a_match_btn.png") + match_btn = Button(f3, image=match_img, borderwidth=0, bg="#FFBBBC", command=match) + match_btn.place(x=780, y=40) + + raise_frame(f3) + root.mainloop() + + +def home(): + for widgets in f1.winfo_children(): + widgets.destroy() + print("pressed the home") + root.geometry("1024x768") + root.configure(bg='#FFBBBC') + f1.configure(bg='#FFBBBC') + image = (Image.open("picture.png")) + resized_image = image.resize((480, 370), Image.ANTIALIAS) + new_image = ImageTk.PhotoImage(resized_image) + Label(f1, image=new_image, borderwidth=0).place(x=45, y=200) + + lines = (Image.open("lines.png")) + resized_image_lines = lines.resize((309, 216), Image.ANTIALIAS) + new_image_lines = ImageTk.PhotoImage(resized_image_lines) + Label(f1, image=new_image_lines, borderwidth=0).place(x=720, y=170) + + Label(f1, text="TEST", borderwidth=0, bg="#FFBBBC", fg='#F04755', font='Montserrat 25').pack(padx=600, pady=500) + Label(f1, text="THE MOST REALISTIC", borderwidth=0, bg="#FFBBBC", fg='#F04755', font='Montserrat 25').place(x=600, + y=535) + Label(f1, text="COUPLE MATCHING APP", borderwidth=0, bg="#FFBBBC", fg='#F04755', font='Montserrat 25').place( + x=600, y=570) + Label(f1, text="NOW", borderwidth=0, bg="#FFBBBC", fg='#F04755', font='Montserrat 25 bold italic').place(x=600, + y=605) + + Label(f1, text="Ⓒ UAIC team", borderwidth=0, bg="#FFBBBC", fg='#F04755', font='Montserrat 16 bold').place(x=450, + y=730) + + home_btn = Button(f1, text="Home", borderwidth=0, bg="#FFBBBC", fg='#000000', font='Montserrat 14 bold', + command=home) + home_btn.place(x=600, y=50) + faq_btn = Button(f1, text="FAQ", borderwidth=0, bg="#FFBBBC", fg='#000000', font='Montserrat 14 bold', + command=faq) + faq_btn.place(x=700, y=50) + match_img = PhotoImage(file="make_a_match_btn.png") + match_btn = Button(f1, image=match_img, borderwidth=0, bg="#FFBBBC", command=match) + match_btn.place(x=780, y=40) + + alg_img = PhotoImage(file="alg.png") + alg_btn = Button(f1, image=alg_img, borderwidth=0, bg="#FFBBBC", command=description_page) + alg_btn.place(x=550, y=320) + + raise_frame(f1) + root.mainloop() + + +def description_page(): + for widgets in f2.winfo_children(): + widgets.destroy() + root.geometry("1024x768") + root.configure(bg='#FFBBBC') + f2.configure(bg='#FFBBBC') + + Label(f2, text="How is our app working", borderwidth=0, bg="#FFBBBC", fg='#F04755', font='Montserrat 25 bold').pack( + side=TOP, anchor=W, padx=100, pady=130) + Label(f2, + text="➊ First the user sends the input using the graphic interface, choosing the boys\nand girls, their " + + "preferences and which algorithm our app should use\n(Greedy or Backtracking).\n\n➋ Second, the program " + + "runs the algorithm for the given instance and finds a \nresult, considering every person's preferences." + + "\n\n➌ Finally, the result is displayed on the app's screen.", + borderwidth=0, bg="#FFBBBC", fg='#F04755', font=('Montserrat 20'), justify=LEFT).pack(side=LEFT, anchor=N, + padx=50, pady=0) + back_arrow = PhotoImage(file="back_arrow.png") + + back_btn = Button(f2, text="Back", borderwidth=0, bg="#FFBBBC", fg='#000000', font='Montserrat 14 bold', + image=back_arrow, command=start_app) + back_btn.place(x=30, y=30) + raise_frame(f2) + root.mainloop() + + +def start_app(): + for frame in (f1, f2, f3, f4, f5, f6): + frame.grid(row=0, column=0, sticky='news') + home() + ''' class Person: @@ -24,48 +391,73 @@ def set_married(self): ''' -def is_stable(states, preferences_men, preferences_women, men, women): - wives = [] - for man1 in preferences_men.keys(): - for man2 in preferences_men.keys(): - for index in range(0, len(states[man1])): - if states[man1][index] == 1: - woman = women[index] - print(man1, ' ', woman) +def get_rank(list_of_preferences, person): + return list_of_preferences.index(person) + +def greedy_approach(men, women, preferences_men, preferences_women): + print("GREEDY") + print(preferences_men) + print(preferences_women) + print(men) + print(women) + # Storing the number of men and women + number_of_men = len(men) + number_of_women = len(women) -def update_states(states, preferences_men, preferences_women, man, woman, index_woman, index_man): - states[man][index_woman] = 1 - states[woman][index_man] = 1 + # Keeping a list of unmarried men + list_of_unmarried_men = men - for man_key in preferences_men.keys(): - if man_key != man: - states[man_key][index_woman] = -1 - for woman_key in preferences_women.keys(): - if woman_key != woman: - states[woman_key][index_man] = -1 - return states + # As default, each person is single + partner_man = {} + for man in men: + partner_man[man] = None + partner_woman = {} + for woman in women: + partner_woman[woman] = None + # Keep the next step of each men + next_man_choice = {} + for man in men: + next_man_choice[man] = 0 -def greedy_by_men(states, preferences_men, preferences_women): - for key, value in preferences_men.items(): - for preference in value: - index_woman = list(preferences_women).index(preference) - index_man = list(preferences_men).index(key) - if states[key][index_woman] == 0: - states = update_states(states, preferences_men, preferences_women, key, preference, index_woman, - index_man) - break - return states + # State is the number of couples, when we have n couples, a list will be returned + state = 0 + while state < number_of_men: + # Choose a random man + random_man = random.choice(list_of_unmarried_men) + # Take his actual preference + preference_man = preferences_men[random_man][next_man_choice[random_man]] + # Check actual woman partner + actual_partner_woman = partner_woman[preference_man] -def create_states(preferences_men, preferences_women): - states = {} - for key in preferences_men.keys(): - states[key] = [0 for x in range(0, len(preferences_women.keys()))] - for key in preferences_women.keys(): - states[key] = [0 for x in range(0, len(preferences_men.keys()))] - return states + if actual_partner_woman is None: + # If she is single, we can create a couple + list_of_unmarried_men.remove(random_man) + partner_woman[preference_man] = random_man + partner_man[random_man] = preference_man + next_man_choice[random_man] += 1 + + # Now we have one more couple + state += 1 + else: + # She already has a partner + # Check the rank of his actual partner + + partner_rank = get_rank(preferences_women[preference_man], actual_partner_woman) + random_man_rank = get_rank(preferences_women[preference_man], random_man) + + if random_man_rank > partner_rank: + # She gets a new partner + list_of_unmarried_men.remove(random_man) + list_of_unmarried_men.append(actual_partner_woman) + partner_woman[preference_man] = random_man + partner_man[random_man] = preference_man + next_man_choice[random_man] += 1 + else: + next_man_choice[random_man] += 1 + return partner_man, partner_woman def create_person_list(dictionary): @@ -87,17 +479,15 @@ def read_input(path): return preferences -def solve_problem(): - preferences_men = read_input("input_men.txt") - preferences_women = read_input("input_women.txt") +def solve_problem(preferences_men, preferences_women, solving_metho): men = create_person_list(preferences_men) women = create_person_list(preferences_women) - states = create_states(preferences_men, preferences_women) - states = greedy_by_men(states, preferences_men, preferences_women) - print(states) - is_stable(states, preferences_men, preferences_women, men, women) + + if solving_metho == 'Greedy': + return greedy_approach(men, women, preferences_men, preferences_women) + else: + pass if __name__ == '__main__': - print('Welcome') - solve_problem() + start_app() diff --git a/Project/make_a_match_btn.png b/Project/make_a_match_btn.png new file mode 100644 index 0000000..89846b1 Binary files /dev/null and b/Project/make_a_match_btn.png differ diff --git a/Project/man.png b/Project/man.png new file mode 100644 index 0000000..8015c89 Binary files /dev/null and b/Project/man.png differ diff --git a/Project/man1.png b/Project/man1.png new file mode 100644 index 0000000..00ac973 Binary files /dev/null and b/Project/man1.png differ diff --git a/Project/picture.png b/Project/picture.png new file mode 100644 index 0000000..5a84bba Binary files /dev/null and b/Project/picture.png differ diff --git a/Project/submit.png b/Project/submit.png new file mode 100644 index 0000000..6c005ce Binary files /dev/null and b/Project/submit.png differ diff --git a/Project/woman.png b/Project/woman.png new file mode 100644 index 0000000..37e3826 Binary files /dev/null and b/Project/woman.png differ diff --git a/Project/woman1.png b/Project/woman1.png new file mode 100644 index 0000000..6ac3976 Binary files /dev/null and b/Project/woman1.png differ