forked from Marxan-source-code/marxan
-
Notifications
You must be signed in to change notification settings - Fork 0
/
iterative_improvement.cpp
153 lines (126 loc) · 5.33 KB
/
iterative_improvement.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
// C++ code for Marxan
// version 2.3 introduced multiple connectivity files and their associated weighting file
// version 2.4.3 introduced 1D and 2D probability
// version 3.0.0 is refactoring of code in 2019
#include <algorithm>
#include <chrono>
#include <ctime>
#include <cfloat>
#include <iostream>
#include <omp.h>
#include <chrono>
// load the required function definition modules
#include "utils.hpp"
#include "algorithms.hpp"
#include "computation.hpp"
#include "clumping.hpp"
#include "anneal.hpp"
#include "heuristics.hpp"
#include "probability.hpp"
#include "input.hpp"
#include "output.hpp"
#include "score_change.hpp"
#include "defines.hpp"
namespace marxan {
using namespace algorithms;
using namespace utils;
// iteratively improves a planning unit solutions
// a descent algorithm un-reserves planning units that don't have a negative value when removed
void iterativeImprovement(int puno, int spno, const vector<spustuff>& pu, const vector<sconnections>& connections,
vector<sspecies>& spec, const vector<spu>& SM, vector<spu_out>& SM_out, vector<int>& R, double cm,
scost& reserve, scost& change, double costthresh, double tpf1, double tpf2,
int clumptype, int irun, string savename, stringstream& logBuffer, rng_engine& rngEngine)
{
int puvalid = 0, i, j, ipu = 0, imode, ichoice, iRowCounter, iRowLimit;
vector<int> iimparray;
double debugfloat;
string tempname2, sRun = to_string(irun), paddedRun = utils::intToPaddedString(irun, 5);
FILE* ttfp = nullptr, * Rfp = nullptr;
string writename;
logBuffer << "iterativeImprovement start\n";
// counting pu's we need to test
for (i = 0; i < puno; i++)
{
if ((R[i] < 2) && (pu[i].status < 2))
puvalid++;
}
logBuffer << "iterativeImprovement puvalid " << puvalid << "\n";
if (fnames.saveitimptrace)
{
tempname2 = savename + "_itimp_objective" + paddedRun + ".csv";
writename = fnames.outputdir + tempname2;
if ((ttfp = fopen(writename.c_str(), "w")) == NULL)
displayErrorMessage("cannot create threshold trace file %s\n", writename.c_str());
fprintf(ttfp, "improvement,total,pus,cost,connection,penalty,change total\n");
tempname2 = savename + "_itimp_zones" + paddedRun + ".csv";
writename = fnames.outputdir + tempname2;
if ((Rfp = fopen(writename.c_str(), "w")) == NULL)
displayErrorMessage("cannot create threshold trace file %s\n", writename.c_str());
fprintf(Rfp, "configuration");
for (i = 0; i < puno; i++)
fprintf(Rfp, ",%i", pu[i].id);
fprintf(Rfp, "\n0");
for (i = 0; i < puno; i++)
fprintf(Rfp, ",%i", R[i]);
fprintf(Rfp, "\n");
iRowCounter = 0;
if (fnames.itimptracerows == 0)
iRowLimit = 0;
else
iRowLimit = floor(puvalid / fnames.itimptracerows);
}
if (puvalid > 0)
{
iimparray.resize(puvalid);
for (i = 0; i < puno; i++)
{
if ((R[i] < 2) && (pu[i].status < 2))
{
iimparray[ipu] = i;
ipu++;
}
}
logBuffer << "iterativeImprovement after array init\n";
// shuffle iimp array
std::shuffle(iimparray.begin(), iimparray.end(), rngEngine);
/***** Doing the improvements ****/
for (i = 0; i < puvalid; i++)
{
ichoice = iimparray[i];
if ((R[ichoice] < 2) && (pu[ichoice].status < 2))
{
imode = R[ichoice] == 1 ? -1 : 1;
computeChangeScore(-1, ichoice, spno, puno, pu, connections, spec, SM, SM_out, R, cm, imode, change, reserve,
costthresh, tpf1, tpf2, 1, clumptype);
if (change.total < 0)
{
displayProgress2("It Imp has changed %i with change value %lf \n", ichoice, change.total);
doChange(ichoice, puno, R, reserve, change, pu, SM, SM_out, spec, connections, imode, clumptype, logBuffer);
} // I've just made a good change
}
if (fnames.saveitimptrace)
{
iRowCounter++;
if (iRowCounter > iRowLimit)
iRowCounter = 1;
if (iRowCounter == 1)
{
fprintf(Rfp, "%i", i);
fprintf(ttfp, "%i,%f,%i,%f,%f,%f,%f\n"
, i, reserve.total
, reserve.pus, reserve.cost, reserve.connection, reserve.penalty,
change.total); // i,costthresh,pus,cost,connection,penalty
for (j = 0; j < puno; j++)
fprintf(Rfp, ",%i", R[j]);
}
}
} // no untested PUs left
}
if (fnames.saveitimptrace)
{
fclose(ttfp);
fclose(Rfp);
}
appendTraceFile("iterativeImprovement end\n");
} // iterativeImprovement
} // namespace marxan