@@ -30,6 +30,80 @@ namespace marxan {
30
30
using namespace algorithms ;
31
31
using namespace utils ;
32
32
33
+ class ImportTraceSaver
34
+ {
35
+ public:
36
+ ImportTraceSaver ()
37
+ {
38
+ ttfp = nullptr ;
39
+ Rfp = nullptr ;
40
+ iRowCounter = 1 ;
41
+ iRowLimit = 0 ;
42
+ }
43
+
44
+ void init (int irun, int puno, int puvalid, const string& savename, const vector<int >& R)
45
+ {
46
+ string tempname2, paddedRun = utils::intToPaddedString (irun, 5 );
47
+ tempname2 = savename + " _itimp_objective" + paddedRun + " .csv" ;
48
+ writename = fnames.outputdir + tempname2;
49
+ if ((ttfp = fopen (writename.c_str (), " w" )) == NULL )
50
+ displayErrorMessage (" cannot create threshold trace file %s\n " , writename.c_str ());
51
+ fprintf (ttfp, " improvement,total,pus,cost,connection,penalty,change total\n " );
52
+
53
+ tempname2 = savename + " _itimp_zones" + paddedRun + " .csv" ;
54
+ writename = fnames.outputdir + tempname2;
55
+ if ((Rfp = fopen (writename.c_str (), " w" )) == NULL )
56
+ displayErrorMessage (" cannot create threshold trace file %s\n " , writename.c_str ());
57
+
58
+ fprintf (Rfp, " configuration" );
59
+ for (int i = 0 ; i < puno; i++)
60
+ fprintf (Rfp, " ,%i" , pu[i].id );
61
+ fprintf (Rfp, " \n 0" );
62
+
63
+ for (int i = 0 ; i < puno; i++)
64
+ fprintf (Rfp, " ,%i" , R[i]);
65
+ fprintf (Rfp, " \n " );
66
+
67
+ iRowCounter = 0 ;
68
+ if (fnames.itimptracerows == 0 )
69
+ iRowLimit = 0 ;
70
+ else
71
+ iRowLimit = floor (puvalid / fnames.itimptracerows );
72
+
73
+ }
74
+
75
+ void append (int i, int puno, const scost& reserve, const scost& change, const vector<int >& R)
76
+ {
77
+ iRowCounter++;
78
+ if (iRowCounter > iRowLimit)
79
+ iRowCounter = 1 ;
80
+
81
+ if (iRowCounter == 1 )
82
+ {
83
+ fprintf (Rfp, " %i" , i);
84
+
85
+ fprintf (ttfp, " %i,%f,%i,%f,%f,%f,%f\n "
86
+ , i, reserve.total
87
+ , reserve.pus , reserve.cost , reserve.connection , reserve.penalty ,
88
+ change.total ); // i,costthresh,pus,cost,connection,penalty
89
+
90
+ for (int j = 0 ; j < puno; j++)
91
+ fprintf (Rfp, " ,%i" , R[j]);
92
+ }
93
+ }
94
+
95
+ ~ImportTraceSaver ()
96
+ {
97
+ if (ttfp != nullptr )
98
+ fclose (ttfp);
99
+ if (Rfp != nullptr )
100
+ fclose (Rfp);
101
+ }
102
+ private:
103
+ FILE* ttfp, * Rfp;
104
+ string writename;
105
+ int iRowCounter, iRowLimit;
106
+ };
33
107
34
108
// iteratively improves a planning unit solutions
35
109
// a descent algorithm un-reserves planning units that don't have a negative value when removed
@@ -38,11 +112,8 @@ namespace marxan {
38
112
scost& reserve, scost& change, double costthresh, double tpf1, double tpf2,
39
113
int clumptype, int irun, int iterations, string savename, stringstream& logBuffer, rng_engine& rngEngine)
40
114
{
41
- int puvalid = 0 , ipu = 0 , imode, ichoice, iRowCounter, iRowLimit ;
115
+ int puvalid = 0 , ipu = 0 , imode, ichoice;
42
116
vector<int > iimparray;
43
- string tempname2, paddedRun = utils::intToPaddedString (irun, 5 );
44
- FILE* ttfp = nullptr , * Rfp = nullptr ;
45
- string writename;
46
117
47
118
logBuffer << " iterativeImprovement start\n " ;
48
119
// counting pu's we need to test
@@ -53,34 +124,9 @@ namespace marxan {
53
124
}
54
125
logBuffer << " iterativeImprovement puvalid " << puvalid << " \n " ;
55
126
127
+ ImportTraceSaver import_trace_saver;
56
128
if (fnames.saveitimptrace )
57
- {
58
- tempname2 = savename + " _itimp_objective" + paddedRun + " .csv" ;
59
- writename = fnames.outputdir + tempname2;
60
- if ((ttfp = fopen (writename.c_str (), " w" )) == NULL )
61
- displayErrorMessage (" cannot create threshold trace file %s\n " , writename.c_str ());
62
- fprintf (ttfp, " improvement,total,pus,cost,connection,penalty,change total\n " );
63
-
64
- tempname2 = savename + " _itimp_zones" + paddedRun + " .csv" ;
65
- writename = fnames.outputdir + tempname2;
66
- if ((Rfp = fopen (writename.c_str (), " w" )) == NULL )
67
- displayErrorMessage (" cannot create threshold trace file %s\n " , writename.c_str ());
68
-
69
- fprintf (Rfp, " configuration" );
70
- for (int i = 0 ; i < puno; i++)
71
- fprintf (Rfp, " ,%i" , pu[i].id );
72
- fprintf (Rfp, " \n 0" );
73
-
74
- for (int i = 0 ; i < puno; i++)
75
- fprintf (Rfp, " ,%i" , R[i]);
76
- fprintf (Rfp, " \n " );
77
-
78
- iRowCounter = 0 ;
79
- if (fnames.itimptracerows == 0 )
80
- iRowLimit = 0 ;
81
- else
82
- iRowLimit = floor (puvalid / fnames.itimptracerows );
83
- }
129
+ import_trace_saver.init (irun, puno, puvalid, savename, R);
84
130
85
131
if (puvalid > 0 )
86
132
{
@@ -102,6 +148,7 @@ namespace marxan {
102
148
{
103
149
// shuffle iimp array
104
150
std::shuffle (iimparray.begin (), iimparray.end (), rngEngine);
151
+ bool was_change = false ;
105
152
106
153
/* **** Doing the improvements ****/
107
154
for (int i = 0 ; i < puvalid && itime <= iterations; i++, itime++)
@@ -117,40 +164,118 @@ namespace marxan {
117
164
{
118
165
displayProgress2 (" It Imp has changed %i with change value %lf \n " , ichoice, change.total );
119
166
doChange (ichoice, puno, R, reserve, change, pu, SM, SM_out, spec, connections, imode, clumptype, logBuffer);
167
+ was_change = true ;
120
168
} // I've just made a good change
121
169
}
122
170
123
171
if (fnames.saveitimptrace )
124
- {
125
- iRowCounter++;
126
- if (iRowCounter > iRowLimit)
127
- iRowCounter = 1 ;
128
-
129
- if (iRowCounter == 1 )
130
- {
131
- fprintf (Rfp, " %i" , i);
172
+ import_trace_saver.append ( itime, puno, reserve, change, R);
132
173
133
- fprintf (ttfp, " %i,%f,%i,%f,%f,%f,%f\n "
134
- , i, reserve.total
135
- , reserve.pus , reserve.cost , reserve.connection , reserve.penalty ,
136
- change.total ); // i,costthresh,pus,cost,connection,penalty
137
-
138
- for (int j = 0 ; j < puno; j++)
139
- fprintf (Rfp, " ,%i" , R[j]);
140
- }
141
- }
142
174
} // no untested PUs left
175
+ if (!was_change)
176
+ {
177
+ logBuffer << " Converged after " << itime << " iterations\n " ;
178
+ break ;
179
+ }
180
+
143
181
}
144
182
}
183
+ appendTraceFile (" iterativeImprovement end\n " );
184
+ } // hill_climbing
145
185
186
+ // iteratively improves a planning unit solutions
187
+ //
188
+ void hill_climbing_two_step (int puno, int spno, const vector<spustuff>& pu, const vector<sconnections>& connections,
189
+ vector<sspecies>& spec, const vector<spu>& SM, vector<spu_out>& SM_out, vector<int >& R, double cm,
190
+ scost& reserve, scost& change, double costthresh, double tpf1, double tpf2,
191
+ int clumptype, int irun, int iterations, string savename, stringstream& logBuffer, rng_engine& rngEngine)
192
+ {
193
+ int puvalid = 0 , ipu = 0 ;
194
+ vector<int > iimparray;
195
+
196
+ logBuffer << " iterativeImprovement start\n " ;
197
+ // counting pu's we need to test
198
+ for (int i = 0 ; i < puno; i++)
199
+ {
200
+ if ((R[i] < 2 ) && (pu[i].status < 2 ))
201
+ puvalid++;
202
+ }
203
+ logBuffer << " iterativeImprovement puvalid " << puvalid << " \n " ;
204
+
205
+ ImportTraceSaver import_trace_saver;
146
206
if (fnames.saveitimptrace )
207
+ import_trace_saver.init (irun, puno, puvalid, savename, R);
208
+
209
+ if (puvalid > 0 )
147
210
{
148
- fclose (ttfp);
149
- fclose (Rfp);
211
+ iimparray.resize (puvalid);
212
+
213
+ for (int i = 0 ; i < puno; i++)
214
+ {
215
+ if ((R[i] < 2 ) && (pu[i].status < 2 ))
216
+ {
217
+ iimparray[ipu] = i;
218
+ ipu++;
219
+ }
220
+ }
221
+
222
+ logBuffer << " iterativeImprovement after array init\n " ;
223
+
224
+
225
+ for (int itime = 1 ; itime <= iterations; )
226
+ {
227
+ // shuffle iimp array
228
+ std::shuffle (iimparray.begin (), iimparray.end (), rngEngine);
229
+ bool was_change = false ;
230
+
231
+ // ***** Doing the improvements ****
232
+
233
+ for (int i0 = 0 ; i0 < puvalid && itime <= iterations; i0++)
234
+ {
235
+ scost change0;
236
+ int ichoice0 = iimparray[i0];
237
+ // remenber old score
238
+ int imode0 = R[ichoice0] == 1 ? -1 : 1 ;
239
+ computeChangeScore (-1 , ichoice0, spno, puno, pu, connections, spec, SM, SM_out, R, cm, imode0, change0, reserve,
240
+ costthresh, tpf1, tpf2, 1 , clumptype);
241
+
242
+ doChange (ichoice0, puno, R, reserve, change, pu, SM, SM_out, spec, connections, imode0, clumptype, logBuffer);
243
+
244
+ for (int i1 = i0+1 ; i1 < puvalid && itime <= iterations; i1++, itime++)
245
+ {
246
+ scost change1;
247
+ int ichoice1 = iimparray[i1];
248
+
249
+ int imode1 = R[ichoice1] == 1 ? -1 : 1 ;
250
+ computeChangeScore (-1 , ichoice1, spno, puno, pu, connections, spec, SM, SM_out, R, cm, imode1, change1, reserve,
251
+ costthresh, tpf1, tpf2, 1 , clumptype);
252
+
253
+ if (change0.total + change1.total < 0 )
254
+ {
255
+ displayProgress2 (" It Imp has changed %i with change value %lf \n " , ichoice1, change.total );
256
+ doChange (ichoice1, puno, R, reserve, change1, pu, SM, SM_out, spec, connections, imode1, clumptype, logBuffer);
257
+ was_change = true ;
258
+ } // I've just made a good change
259
+
260
+ if (fnames.saveitimptrace )
261
+ import_trace_saver.append ( itime, puno, reserve, change, R);
262
+
263
+ } // no untested PUs left
264
+ if (!was_change)
265
+ {
266
+ // undo change
267
+ int imode0_reverted = imode0 == 1 ? -1 : 1 ;
268
+ computeChangeScore (-1 , ichoice0, spno, puno, pu, connections, spec, SM, SM_out, R, cm, imode0_reverted, change0, reserve,
269
+ costthresh, tpf1, tpf2, 1 , clumptype);
270
+
271
+ doChange (ichoice0, puno, R, reserve, change0, pu, SM, SM_out, spec, connections, imode0_reverted, clumptype, logBuffer);
272
+ }
273
+
274
+ }
275
+ }
150
276
}
151
277
152
278
appendTraceFile (" iterativeImprovement end\n " );
153
- } // iterativeImprovement
154
-
279
+ } // hill_climbing_two_step
155
280
} // namespace marxan
156
281
0 commit comments