Skip to content

Commit 8e722b9

Browse files
Created two steps hill climbing algorithm.
1 parent 2886084 commit 8e722b9

File tree

3 files changed

+179
-54
lines changed

3 files changed

+179
-54
lines changed

hill_climbing.cpp

Lines changed: 177 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,80 @@ namespace marxan {
3030
using namespace algorithms;
3131
using namespace utils;
3232

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, "\n0");
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+
};
33107

34108
// iteratively improves a planning unit solutions
35109
// a descent algorithm un-reserves planning units that don't have a negative value when removed
@@ -38,11 +112,8 @@ namespace marxan {
38112
scost& reserve, scost& change, double costthresh, double tpf1, double tpf2,
39113
int clumptype, int irun, int iterations, string savename, stringstream& logBuffer, rng_engine& rngEngine)
40114
{
41-
int puvalid = 0, ipu = 0, imode, ichoice, iRowCounter, iRowLimit;
115+
int puvalid = 0, ipu = 0, imode, ichoice;
42116
vector<int> iimparray;
43-
string tempname2, paddedRun = utils::intToPaddedString(irun, 5);
44-
FILE* ttfp = nullptr, * Rfp = nullptr;
45-
string writename;
46117

47118
logBuffer << "iterativeImprovement start\n";
48119
// counting pu's we need to test
@@ -53,34 +124,9 @@ namespace marxan {
53124
}
54125
logBuffer << "iterativeImprovement puvalid " << puvalid << "\n";
55126

127+
ImportTraceSaver import_trace_saver;
56128
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, "\n0");
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);
84130

85131
if (puvalid > 0)
86132
{
@@ -102,6 +148,7 @@ namespace marxan {
102148
{
103149
// shuffle iimp array
104150
std::shuffle(iimparray.begin(), iimparray.end(), rngEngine);
151+
bool was_change = false;
105152

106153
/***** Doing the improvements ****/
107154
for (int i = 0; i < puvalid && itime <= iterations; i++, itime++)
@@ -117,40 +164,118 @@ namespace marxan {
117164
{
118165
displayProgress2("It Imp has changed %i with change value %lf \n", ichoice, change.total);
119166
doChange(ichoice, puno, R, reserve, change, pu, SM, SM_out, spec, connections, imode, clumptype, logBuffer);
167+
was_change = true;
120168
} // I've just made a good change
121169
}
122170

123171
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);
132173

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-
}
142174
} // no untested PUs left
175+
if(!was_change)
176+
{
177+
logBuffer << "Converged after "<< itime << " iterations\n";
178+
break;
179+
}
180+
143181
}
144182
}
183+
appendTraceFile("iterativeImprovement end\n");
184+
} // hill_climbing
145185

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;
146206
if (fnames.saveitimptrace)
207+
import_trace_saver.init(irun, puno, puvalid, savename, R);
208+
209+
if (puvalid > 0)
147210
{
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+
}
150276
}
151277

152278
appendTraceFile("iterativeImprovement end\n");
153-
} // iterativeImprovement
154-
279+
} // hill_climbing_two_step
155280
} // namespace marxan
156281

score_change.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -723,7 +723,7 @@ namespace marxan {
723723

724724

725725
// change the status of a single planning unit
726-
void doChange(int ipu, int puno, vector<int>& R, scost& reserve, scost& change,
726+
void doChange(int ipu, int puno, vector<int>& R, scost& reserve, const scost& change,
727727
const vector<spustuff>& pu, const vector<spu>& SM, vector<spu_out>& SM_out, vector<sspecies>& spec, const vector<sconnections>& connections,
728728
int imode, int clumptype, stringstream& logBuffer)
729729
{

score_change.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ namespace marxan {
4141
vector<sspecies>& spec, const vector<spu>& SM, vector<spu_out>& SM_out, const vector<int>& R, double cm, int imode,
4242
scost& change, scost& reserve, double costthresh, double tpf1, double tpf2,
4343
double timeprop, int clumptype);
44-
void doChange(int ipu, int puno, vector<int>& R, scost& reserve, scost& change,
44+
void doChange(int ipu, int puno, vector<int>& R, scost& reserve, const scost& change,
4545
const vector<spustuff>& pu, const vector<spu>& SM, vector<spu_out>& SM_out, vector<sspecies>& spec, const vector<sconnections>& connections,
4646
int imode, int clumptype, stringstream& logBuffer);
4747
} // namespace marxan

0 commit comments

Comments
 (0)