-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathAllStars.cpp
332 lines (296 loc) · 12.1 KB
/
AllStars.cpp
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
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
#include <iostream>
#include "Expressions.hpp"
#include "Matrix.hpp"
#include "MarkovMonoid.hpp"
#include "StabilisationMonoid.hpp"
#include "StarHeight.hpp"
#include <chrono>
#include <fstream>
#include <sstream>
#ifdef MSVC
#include <windows.h>
#include <time.h>
#else
#include <unistd.h>
#endif
using namespace std;
ExplicitAutomaton * expa = NULL;
int letters_nb = 2;
bool random_mode = false;
int max_state_nb = 5;
//return true iff an increment was performed
bool inc_mat(ExplicitMatrix & m) {
auto stnb = m.coefficients.size();
for(int i = 0 ; (i < stnb); i++) {
for(int j =0; (j < stnb); j++) {
if(m.coefficients[i][j]==0) {
m.coefficients[i][j] = 1;
for(int i0 = 0 ; i0 < i; i0++) {
for(int j0 =0; j0 < stnb; j0++) {
m.coefficients[i0][j0] = 0;
}
}
for(int j0 =0; j0 < j; j0++) {
m.coefficients[i][j0] = 0;
}
return true;
}
}
}
return false;
}
bool inc_mat_and_states() {
auto & matrices = expa->matrices;
for(int letter = 0; (letter < letters_nb); letter++) {
auto res = inc_mat(matrices[letter]);
if(res) {
for(int letter0 = 0; letter0 < letter; letter0++)
matrices[letter0].clear(0);
return true;
}
}
return false;
}
void random_automaton(int stnb) {
delete expa;
expa = new ExplicitAutomaton(stnb,letters_nb);
expa->initialState = 0;
expa->finalStates.push_back(stnb - 1);
auto & matrices = expa->matrices;
for(int letter = 0 ; letter < letters_nb; letter++) {
auto & mat = matrices[letter];
mat.clear(0);
for(int i = 0 ; (i < stnb); i++)
mat.coefficients[i][ rand() % stnb ] = 1;
}
}
void pusage(char* s)
{
cout << "Usage: " << s << "[-v] [-f] [-a automaton_id] [-b automaton_id] [-r] [-m max_state_nb] [-l] [-i] [-z] [-y exp_number]" << endl;
cout << "\t-v verbose on [default off]" << endl;
cout << "\t-f file output on [default off]" << endl;
cout << "\t-a automaton_id compute for a specific automaton id# " << endl;
cout << "\t-b automaton_id compute for automata with >= id# " << endl;
cout << "\t-r random choice of automaton [default off]" << endl;
cout << "\t-m max_state_nb specifies max number of states [default 15]" << endl;
cout << "\t-l do not use loop heuristic [default yes]" << endl;
cout << "\t-i do not use minimization [default yes]" << endl;
cout << "\t-p do not use pruning [default yes]" << endl;
cout << "\t-z try all combinations of heuristics [default no]" << endl;
cout << "\t-y number_of_experiments [default 100]" << endl;
exit(0);
}
bool use_loop_heuristic = true;
bool use_minimization = true;
bool use_prune = true;
string filename() {
stringstream filename;
filename << "starheight_" << (random_mode ? "random" : "enumerative") << "_";
filename << "_loopheur_" << (use_loop_heuristic ? "on" : "off") << "_minim_heur" << (use_minimization ? "on" : "off") << "_prune_heur" << (use_prune ? "on" : "off");
return filename.str();
}
int main(int argc, char **argv)
{
cout << "Stamina rules" << endl;
// unsigned int seed = time(NULL);
int opt;
bool verbose = false;
bool out_file = false;
bool compare_heuristics = false;
int experiments_nb = 100;
bool just_one_id = true;
int aut_id = -1;
while((opt = getopt(argc,argv, "vhfrliza:m:y:")) != -1)
{
switch(opt)
{
case 'h':
pusage(argv[0]);
case 'v':
cout << "Verbose on "<< endl;
verbose = true;
break;
case 'f':
cout << "Output file on "<< endl;
out_file = true;
break;
case 'r':
cout << "Random mode on "<< endl;
random_mode = true;
break;
case 'a':
aut_id = atoi(optarg);
cout << "Automaton id #" << aut_id<< endl;
just_one_id = true;
break;
case 'b':
aut_id = atoi(optarg);
cout << "Automaton id #" << aut_id<< endl;
just_one_id = false;
break;
case 'm':
max_state_nb = atoi(optarg);
if(max_state_nb <= 0) max_state_nb = 1;
cout << "Max states #" << max_state_nb<< endl;
break;
case 'y':
experiments_nb = atoi(optarg);
if(experiments_nb <= 0) experiments_nb = 1;
break;
case 'z':
compare_heuristics = true;
cout << "Comparing heuristics" << endl;
break;
case 'l':
use_loop_heuristic = false;
if(!compare_heuristics) cout << "Disabling loop heuristic" << endl;
break;
case 'i':
use_minimization = false;
if(!compare_heuristics) cout << "Disabling minimization" << endl;
break;
case 'p':
use_prune = false;
cout << "Disabling pruning" << endl;
break;
default:
pusage(argv[0]);
}
}
cout << "Experiments nb" << experiments_nb<< endl;
if(aut_id>=0) random_mode = false;
if(compare_heuristics) {
use_loop_heuristic= false;
use_minimization = false;
}
if(!compare_heuristics) {
ofstream file(filename() + ".csv", ofstream::app);
file << "#;StarHeight;LoopComplexity;AutomatonSize;MonoidDim;";
file << "MonoidSize;RewriteRulesNb;VectorsNb;ComputationTime(ms);";
file << "LoopHeur;MinHeur";
file << endl;
file.close();
} else {
for(int loop = 0; loop<=1; loop++) {
for(int mini = 0; mini <= 1; mini++) {
use_loop_heuristic = loop;
use_minimization = mini;
ofstream file(filename() + ".csv", ofstream::app);
file << "#;StarHeight;LoopComplexity;AutomatonSize;MonoidDim;";
file << "MonoidSize;RewriteRulesNb;VectorsNb;ComputationTime(ms);";
file << "LoopHeur;MinHeur";
file << endl;
file.close();
}
}
}
uint cur_aut_id = 1;
uint exp_nb = 0;
auto base = std::chrono::high_resolution_clock::now();
for(int stnb = 1 ; stnb < max_state_nb; stnb++) {
delete expa;
expa = new ExplicitAutomaton(stnb,letters_nb);
expa->initialState = 0;
expa->finalStates.push_back(stnb -1);
while(true) {
if(aut_id < 0 || cur_aut_id >= aut_id) {
auto start = std::chrono::high_resolution_clock::now();
unsigned int seed
= chrono::duration_cast<chrono::microseconds>(start - base).count();
if(random_mode)
{
cout << "Random seed " << seed << endl;
srand(seed);
stnb = 1 + (rand() % (max_state_nb - 1));
cout << "New random automaton with " << stnb << " states and seed " << seed << endl;
random_automaton(stnb);
}
ClassicAut aut(*expa);
if(!aut.iscomplete()) {
// cout << "Automaton #" << cur_aut_id << " not complete" << endl;
} else if (!aut.isdet()){
//cout << "Automaton #" << cur_aut_id << " not deterministic" << endl;
} else {
if(!random_mode) {
cout << "Automaton #" << cur_aut_id << " complete and deterministic" << endl;
}
if(!compare_heuristics || (!use_minimization && !use_loop_heuristic))
exp_nb++;
UnstableMultiMonoid * monoid = NULL;
const ExtendedExpression * witness = NULL;
int loopComplexity;
auto h = computeStarHeight(
aut,
monoid,
witness,
loopComplexity,
out_file,
verbose,
"AllStars",
use_loop_heuristic,
use_minimization,
use_prune
);
auto end = std::chrono::high_resolution_clock::now();
auto ctime = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
cout << "Computation time " << ctime << endl;
if(monoid != NULL) {
cout << "StarHeight " << h << endl;
ofstream file(filename() + ".csv", ofstream::app);
file << (random_mode ? seed : cur_aut_id) << ";" << h << ";" << loopComplexity << ";";
file << stnb << ";" << VectorInt::GetStateNb() << ";";
file << monoid->expr_to_mat.size();
file << ";" << monoid->rewriteRules.size() << ";" << int_vectors.size();
file << ";" << ctime;
file << ";" << (int) use_loop_heuristic;
file << ";" << (int) use_minimization;
file << ";" << (int) use_prune;
file << endl;
file.close();
delete monoid; monoid = NULL;
} else {
cout << "StarHeight " << h << endl;
ofstream file(filename() + ".csv", ofstream::app);
file << (random_mode ? seed : cur_aut_id) << ";" << h << ";" << loopComplexity << ";";
file << stnb << ";" << VectorInt::GetStateNb()<< ";" << 0;
file << ";" << 0 << ";" << 0;
file << ";" << ctime;
file << ";" << (int) use_loop_heuristic;
file << ";" << (int) use_minimization;
file << ";" << (int) use_prune;
file << endl;
file.close();
}
}
}
if(compare_heuristics && !use_loop_heuristic && !use_minimization)
{ use_minimization = true; }
else if(compare_heuristics && !use_loop_heuristic && use_minimization)
{ use_loop_heuristic =true; use_minimization = false;}
else if(compare_heuristics && use_loop_heuristic && !use_minimization)
{ use_minimization = true;}
else if(!random_mode){
if(compare_heuristics) {
use_loop_heuristic = false;
use_minimization = false;
}
if(just_one_id && aut_id >= 0 && cur_aut_id >= aut_id) {
cout << "Performed single experiment on id " << aut_id << "." << endl;
break;
}
cur_aut_id++;
if(exp_nb > experiments_nb){
cout << "Max experiments number attained." << endl;
break;
}
bool ret = inc_mat_and_states();
if(!ret) break;
}
}
if(just_one_id && aut_id >= 0 && cur_aut_id >= aut_id) {
cout << "Performed single experiment on id " << aut_id << "." << endl;
break;
}
}
cout << "Experiment over " << endl;
}