-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgsalgorithm.cc
More file actions
169 lines (145 loc) · 3.69 KB
/
Copy pathgsalgorithm.cc
File metadata and controls
169 lines (145 loc) · 3.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
#include <stdio.h>
#include <stdlib.h>
#include <random>
#include <time.h>
#include <chrono>
#define N 5 /* 人数 */
//生成した2次元配列を表示
void showarray(int **num, int numline)
{
for (int i = 1; i < numline; i++)
{
for (int j = 1; j < N + 1; j++)
{
printf("%d ", num[i][j]);
}
printf("\n");
}
}
// 2次元配列の初期化
void resetarray(int **num, int numline)
{
for (int i = 0; i < N + 1; i++)
{
for (int j = 0; j < N + 1; j++)
{
num[i][j] = j; // 初期化
}
}
return;
}
// min_valからmax_val-1の範囲で整数の乱数を返す関数(STL)
uint64_t get_rand(uint64_t min_val, uint64_t max_val)
{
// 乱数生成器_メルセンヌツイスター(mt19937_64)にtime(NULL)を入れて毎回実行結果を変えたい
static std::mt19937_64 mt64(time(NULL));
// [min_val, max_val] の一様分布整数 (int) の分布生成器
std::uniform_int_distribution<uint64_t> get_rand_uni_int(min_val, max_val);
// 乱数を生成
return get_rand_uni_int(mt64);
}
// 2次元配列をシャッフルする関数
void shuffle(int **num, int numline)
{
for (int i = 0; i < N; i++)
{
for (int j = 1; j < N; j++)
{
int r = get_rand(j, N);
int tmp = num[i][j];
num[i][j] = num[i][r];
num[i][r] = tmp;
}
}
}
int *galeshapley(int **male, int **female)
{
int next[N + 1] = {0};
int n = N + 1;
int *fiancee;
fiancee = (int *)malloc(sizeof(int) * n);
// fiancee[n] = {0};
for (int m = 1; m < N + 1; m++)
{
for (int s = m; s != 0;)
{
next[s]++;
int w = male[s][next[s]];
if (female[w][s] < female[w][fiancee[w]])
{
int t = fiancee[w];
fiancee[w] = s;
s = t;
}
}
}
return (fiancee);
}
void showresults(int *fiancee)
{
printf("f -- m\n======\n");
for (int f = 1; f < N + 1; f++)
{
printf("%d -- %d(%c)\n", f, fiancee[f], 'A' - 1 + fiancee[f]);
}
return;
}
int main(void)
{
// male[1][1]=2の場合、男性Aは女性2を希望リストの1番に設定している。
// female[1][1]=2の場合、女性1は男性Aを希望リストの2番に設定している。
int **male;
int **female;
int n, m;
n = N + 1, m = N + 1;
// maleの分のメモリ確保
male = (int **)malloc(sizeof(int *) * n);
for (int i = 0; i < n; i++)
{
male[i] = (int *)malloc(sizeof(int) * m);
}
resetarray(male, N + 1);
// femaleの分のメモリ確保
female = (int **)malloc(sizeof(int *) * n);
for (int i = 0; i < n; i++)
{
female[i] = (int *)malloc(sizeof(int) * m);
}
resetarray(female, N + 1);
for (int i = 0; i < N + 1; i++)
{
female[i][0] = N + 1;
}
shuffle(male, N + 1);
shuffle(female, N + 1);
/*printf("male[N+1][N+1]:\n");
showarray(male, N + 1);
printf("female[N+1][N+1]:\n");
showarray(female, N + 1);
printf("\n");*/
//時間計測開始
using namespace std;
chrono::system_clock::time_point start, end;
start = chrono::system_clock::now();
// gale-shapley algorithmの実行
int *fiancee = galeshapley(male, female);
end = chrono::system_clock::now();
//結果表示
// showresults(fiancee);
double time = static_cast<double>(chrono::duration_cast<chrono::microseconds>(end - start).count() / 1000.0);
printf("N= %d time %lf[ms]\n", N, time);
//メモリ解放:fiancee
free(fiancee);
//メモリ解放:male
for (int i = 0; i < n; i++)
{
free(male[i]);
}
free(male);
//メモリ解放:female
for (int i = 0; i < n; i++)
{
free(female[i]);
}
free(female);
}