|
| 1 | +#include <stdbool.h> |
1 | 2 | #include <stdio.h>
|
2 | 3 | #include <stdlib.h>
|
3 |
| -#include <stdbool.h> |
| 4 | +#include <string.h> |
| 5 | +#include <time.h> |
| 6 | + |
| 7 | +struct person { |
| 8 | + int id; |
| 9 | + struct person *partner; |
| 10 | + size_t *prefers; |
| 11 | + size_t index; |
| 12 | +}; |
| 13 | + |
| 14 | +void shuffle(size_t *array, size_t size) { |
| 15 | + for (size_t i = size - 1; i > 0; --i) { |
| 16 | + size_t j = rand() % (i + 1); |
| 17 | + size_t tmp = array[i]; |
| 18 | + array[i] = array[j]; |
| 19 | + array[j] = tmp; |
| 20 | + } |
| 21 | +} |
| 22 | + |
| 23 | +void create_group(struct person *group, size_t size, bool are_men) { |
| 24 | + for (size_t i = 0; i < size; ++i) { |
| 25 | + group[i].id = i; |
| 26 | + group[i].partner = NULL; |
| 27 | + group[i].prefers = (size_t*)malloc(sizeof(size_t) * size); |
| 28 | + group[i].index = 0; |
4 | 29 |
|
5 |
| -typedef struct person { |
6 |
| - size_t id; |
7 |
| - size_t prtnr; |
8 |
| - size_t *prefs; |
9 |
| - size_t pref_ind; |
10 |
| -} person; |
11 |
| - |
12 |
| -void shuffle(size_t *x, size_t n) { |
13 |
| - if (n > 1) { |
14 |
| - for (size_t i = 0; i < n - 1; ++i) { |
15 |
| - size_t j = i + rand() / (RAND_MAX / (n - i) + 1); |
16 |
| - size_t t = x[j]; |
17 |
| - x[j] = x[i]; |
18 |
| - x[i] = t; |
| 30 | + for (size_t j = 0; j < size; ++j) { |
| 31 | + group[i].prefers[j] = j; |
19 | 32 | }
|
| 33 | + |
| 34 | + shuffle(group[i].prefers, size); |
20 | 35 | }
|
21 | 36 | }
|
22 | 37 |
|
23 |
| -bool prefers(size_t *prefs, size_t prtnr_id, size_t prop_id, size_t pref_size) { |
24 |
| - for (size_t i = 0; i < pref_size; ++i) { |
25 |
| - if (prefs[i] == prtnr_id) { |
26 |
| - return false; |
27 |
| - } else if(prefs[i] == prop_id) { |
| 38 | +bool prefers_partner(size_t *prefers, size_t partner, size_t id, size_t size) { |
| 39 | + for (size_t i = 0; i < size; ++i) { |
| 40 | + if (prefers[i] == partner) { |
28 | 41 | return true;
|
| 42 | + } else if(prefers[i] == id) { |
| 43 | + return false; |
29 | 44 | }
|
30 | 45 | }
|
31 | 46 | }
|
32 | 47 |
|
33 |
| -void create_ppl(person *grp, size_t grp_size) { |
34 |
| - for (size_t i = 0; i < grp_size; ++i) { |
35 |
| - person prn; |
36 |
| - prn.id = i; |
37 |
| - prn.prtnr = grp_size + 1; |
38 |
| - prn.pref_ind = 0; |
39 |
| - prn.prefs = (size_t *) malloc(sizeof(size_t) * grp_size); |
40 |
| - |
41 |
| - for (size_t j = 0; j < grp_size; ++j) { |
42 |
| - prn.prefs[j] = j; |
43 |
| - } |
| 48 | +void stable_marriage(struct person *men, struct person *women, size_t size) { |
| 49 | + struct person *bachelors[size]; |
| 50 | + size_t bachelors_size = size; |
44 | 51 |
|
45 |
| - shuffle(prn.prefs, grp_size); |
46 |
| - grp[i] = prn; |
| 52 | + for (size_t i = 0; i < size; ++i) { |
| 53 | + bachelors[i] = &men[i]; |
47 | 54 | }
|
48 |
| -} |
49 |
| - |
50 |
| -void stable_matching(person *men, person *women, size_t grp_size) { |
51 |
| - bool cont = true; |
52 |
| - while (cont) { |
53 |
| - for (size_t i = 0; i < grp_size; ++i) { |
54 |
| - if (men[i].prtnr == (grp_size + 1)) { |
55 |
| - size_t wmn_id = men[i].prefs[men[i].pref_ind]; |
56 |
| - |
57 |
| - if (women[wmn_id].prtnr == (grp_size + 1)) { |
58 |
| - men[i].prtnr = wmn_id; |
59 |
| - women[wmn_id].prtnr = i; |
60 |
| - } else if(prefers(women[wmn_id].prefs, women[wmn_id].prtnr, i, |
61 |
| - grp_size)) { |
62 |
| - men[women[wmn_id].prtnr].prtnr = grp_size + 1; |
63 |
| - women[wmn_id].prtnr = i; |
64 |
| - men[i].prtnr = wmn_id; |
65 |
| - } |
66 |
| - |
67 |
| - men[i].pref_ind++; |
68 |
| - } |
69 |
| - } |
70 | 55 |
|
71 |
| - cont = false; |
72 |
| - for (size_t i = 0; i < grp_size; ++i) { |
73 |
| - if (men[i].prtnr == (grp_size + 1)) { |
74 |
| - cont = true; |
75 |
| - break; |
76 |
| - } |
| 56 | + while (bachelors_size > 0) { |
| 57 | + struct person *man = bachelors[bachelors_size - 1]; |
| 58 | + struct person *woman = &women[man->prefers[man->index]]; |
| 59 | + |
| 60 | + if (!woman->partner) { |
| 61 | + woman->partner = man; |
| 62 | + man->partner = woman; |
| 63 | + bachelors[--bachelors_size] = NULL; |
| 64 | + } else if (!prefers_partner(woman->prefers, woman->partner->id, man->id, |
| 65 | + size)) { |
| 66 | + |
| 67 | + woman->partner->index++; |
| 68 | + bachelors[bachelors_size - 1] = woman->partner; |
| 69 | + woman->partner = man; |
| 70 | + man->partner = woman; |
| 71 | + } else { |
| 72 | + man->index++; |
77 | 73 | }
|
78 | 74 | }
|
79 | 75 | }
|
80 | 76 |
|
81 |
| -void kill(person *grp, size_t grp_size) { |
82 |
| - for (size_t i = 0; i < grp_size; ++i) { |
83 |
| - free(grp[i].prefs); |
| 77 | +void free_group(struct person *group, size_t size) { |
| 78 | + for (size_t i = 0; i < size; ++i) { |
| 79 | + free(group[i].prefers); |
84 | 80 | }
|
85 | 81 | }
|
86 | 82 |
|
87 | 83 | int main() {
|
88 |
| - int grp_size = 5; |
89 |
| - person men[grp_size], women[grp_size]; |
| 84 | + srand(time(NULL)); |
90 | 85 |
|
91 |
| - create_ppl(men, grp_size); |
92 |
| - create_ppl(women, grp_size); |
| 86 | + struct person men[5], women[5]; |
93 | 87 |
|
94 |
| - stable_matching(men, women, grp_size); |
| 88 | + create_group(men, 5, true); |
| 89 | + create_group(women, 5, false); |
95 | 90 |
|
96 |
| - for (size_t i = 0; i < grp_size; ++i) { |
97 |
| - printf("preferences of man %zu \n", i); |
98 |
| - for (size_t j = 0; j < grp_size; ++j) { |
99 |
| - printf("%zu \n", men[i].prefs[j]); |
| 91 | + for (size_t i = 0; i < 5; ++i) { |
| 92 | + printf("preferences of man %zu: ", i); |
| 93 | + for (size_t j = 0; j < 5; ++j) { |
| 94 | + printf("%zu ", men[i].prefers[j]); |
100 | 95 | }
|
| 96 | + |
| 97 | + printf("\n"); |
101 | 98 | }
|
102 | 99 |
|
103 |
| - for (size_t i = 0; i < grp_size; ++i) { |
104 |
| - printf("preferences of woman %zu \n", i); |
105 |
| - for (size_t j = 0; j < grp_size; ++j) { |
106 |
| - printf("%zu \n", women[i].prefs[j]); |
| 100 | + printf("\n"); |
| 101 | + |
| 102 | + for (size_t i = 0; i < 5; ++i) { |
| 103 | + printf("preferences of woman %zu: ", i); |
| 104 | + for (size_t j = 0; j < 5; ++j) { |
| 105 | + printf("%zu ", women[i].prefers[j]); |
107 | 106 | }
|
108 |
| - } |
109 | 107 |
|
110 |
| - for (size_t i = 0; i < grp_size; ++i) { |
111 |
| - printf("partners of man %zu is woman %zu\n", i, men[i].prtnr); |
| 108 | + printf("\n"); |
112 | 109 | }
|
113 | 110 |
|
114 |
| - kill(men, grp_size); |
115 |
| - kill(women, grp_size); |
| 111 | + stable_marriage(men, women, 5); |
| 112 | + |
| 113 | + printf("\n"); |
| 114 | + |
| 115 | + for (size_t i = 0; i < 5; ++i) { |
| 116 | + printf("the partner of man %zu is woman %d\n", i, men[i].partner->id); |
| 117 | + } |
116 | 118 |
|
117 |
| - return 0; |
| 119 | + free_group(men, 5); |
| 120 | + free_group(women, 5); |
118 | 121 | }
|
0 commit comments