/
banker.h
256 lines (187 loc) · 5.56 KB
/
banker.h
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
/**
* You can play around with the following values.
*
* RES_TYPE represents the number of type of ressources.
*
* NB_MAX_OF_SIMULATIONS is self explainatory.
*
* MIN_NB_CUST - MAX_NB_CUST are the minimum and maximum
* number of customers to create for the simulation.
*
* MIN_RES_LIM - MAX_RES_LIM are the minimum and maximum
* number of ressources that a customer can ask to be available
* at the bank initially.
*
* The requests made by the customers will be chosen between
* MIN_REQUEST and MAX_REQUEST.
*/
#define RES_TYPE 4
#define NB_MAX_OF_SIMULATIONS 202
#define MAX_NB_CUST 12
#define MIN_NB_CUST 5
#define MAX_RES_LIM 12
#define MIN_RES_LIM 5
#define MAX_REQUEST 5
#define MIN_REQUEST 0
int id;
int res;
int res_id;
int rdm_nbr_between(const int min, const int max) {
return min + ( rand() % (max-min+1) );
}
typedef struct {
int total_res[RES_TYPE];
int stock[RES_TYPE];
int safe_state[RES_TYPE];
int deny_count[RES_TYPE];
} banker;
typedef struct {
int max_res[RES_TYPE];
int stock[RES_TYPE];
int request[RES_TYPE];
} customer;
/**
* Prints what the customers holds and needs
*/
void report_customer(const customer cust) {
for (res = 0; res < RES_TYPE; res++) {
printf("\t%d?%d/%d", cust.request[res], cust.stock[res], cust.max_res[res]);
}
printf("\n");
}
/**
* Prints what the customers holds and needs
*/
void report_customers(const customer * custs, const int nb_custs) {
printf("Customers");
for (res_id = 0; res_id < RES_TYPE; res_id++) {
printf("\tres%d", res_id);
}
printf("\n");
for (id = 0; id < nb_custs; id++) {
printf("#%d\t", id);
report_customer(custs[id]);
}
}
/**
* Gives random values to the number of ressources
* for every customers and sets their stocks,
* and requests to zero.
*/
void rdm_customer_res(customer * custs, const int nb_custs) {
for (id = 0; id < nb_custs; id++) {
for (res_id = 0; res_id < RES_TYPE; res_id++) {
custs[id].max_res[res_id] = rdm_nbr_between(MIN_NB_CUST,MAX_NB_CUST);
custs[id].stock[res_id] = 0;
custs[id].request[res_id] = 0;
}
}
}
/**
* Gives random values to the next request of
* every customers.
*/
void rdm_customer_req(customer * cust) {
for (res_id = 0; res_id < RES_TYPE; res_id++) {
cust->request[res_id] = rdm_nbr_between(MIN_REQUEST,MAX_REQUEST);
}
}
/**
* Gives random values to the next request of
* every customers.
*/
void rdm_customers_req(customer * custs, const int nb_custs) {
for (id = 0; id < nb_custs; id++) {
rdm_customer_req(&custs[id]);
}
}
/**
* Prints what the banker holds and the max value computed
*/
void report_banker(const banker bkr) {
printf("Banker\nStock:\t");
for (res = 0; res < RES_TYPE; res++) {
printf("\t%d", bkr.stock[res]);
}
printf("\nTotal:\t");
for (res = 0; res < RES_TYPE; res++) {
printf("\t%d", bkr.total_res[res]);
}
printf("\nSafe:\t");
for (res = 0; res < RES_TYPE; res++) {
printf("\t%d", bkr.safe_state[res]);
}
printf("\nDeny:\t");
for (res = 0; res < RES_TYPE; res++) {
printf("\t%d", bkr.deny_count[res]);
}
printf("\n");
}
void find_ideal_res_for_banker(const customer * custs, const int nb_custs, banker * bkr){
// Computes the available number of ressources
for (res = 0; res < RES_TYPE; res++) {
bkr->total_res[res] = 0;
// Computes the total number for each ressources
for (id = 0; id < nb_custs; id++) {
bkr->total_res[res] += custs[id].max_res[res];
}
// Multiplies total by 0.6 and round DOWN to find the ideal value.
bkr->stock[res] = (3*bkr->total_res[res]/ 5);
bkr->safe_state[res] = -1;
}
}
/**
* Find the minimum number of ressources needed for one of the customer
* to complete his project (and thus give back his ressources)
*/
void update_safe_states(const customer * custs, const int nb_custs, banker * bkr) {
int remaining;
// Iterates over all ressources
for (res = 0; res < RES_TYPE; res++) {
bkr->safe_state[res] = bkr->total_res[res];
// Looks for the min needed to finish a project
for (id = 0; id < nb_custs; id++) {
remaining = custs[id].max_res[res] - custs[id].stock[res];
// Checks that the stock can still be useful to somebody else
if (bkr->safe_state[res] > remaining) {
// Checks that the customer does not go past limit
if (remaining < 0) {
remaining = 0;
}
bkr->safe_state[res] = remaining;
}
}
}
}
int banker_grant_req(customer cust, const int res_id, banker bkr) {
// Computes what would be the value of the stocks after
int bank_aftr = bkr.stock[res_id] - cust.request[res_id];
int cust_aftr = cust.stock[res_id] + cust.request[res_id];
// Checks that the customer does not ask past limit
if (cust_aftr <= cust.max_res[res_id]) {
// Checks that the request is consistent with the stock
if (bank_aftr >=0) {
if (bank_aftr >= bkr.safe_state[res_id]) {
return 1;
}//else {printf("Banks becomes lower than safe_state.\n");}
}//else {printf("Bank becomes negative.\n");}
}//else {printf("Customer asked over limit.\n");}
return 0;
}
void process_transfer(customer * cust, const int res_id, banker * bkr) {
//printf("res #%d: [init=%d] ", res_id, bkr->stock[res_id]);
//printf("- %d = ", cust->request[res_id]);
bkr->stock[res_id] -= cust->request[res_id];
cust->stock[res_id] += cust->request[res_id];
cust->request[res_id] = 0;
//printf("%d\n", bkr->stock[res_id]);
if (cust->stock[res_id] >= cust->max_res[res_id]) {
bkr->stock[res_id] += cust->stock[res_id];
cust->stock[res_id] = 0;
}
}
void reset_deny_count(banker * bkr) {
for (res_id = 0; res_id < RES_TYPE; res_id++) {
bkr->deny_count[res_id] = 0;
}
}