Skip to content

Commit

Permalink
Merge pull request #2291 from GeoDaCenter/v1.18
Browse files Browse the repository at this point in the history
V1.18
  • Loading branch information
lixun910 committed Dec 12, 2020
2 parents 513e4c7 + e922b5d commit cc4e9a9
Show file tree
Hide file tree
Showing 116 changed files with 17,471 additions and 14,124 deletions.
517 changes: 372 additions & 145 deletions Algorithms/azp.cpp

Large diffs are not rendered by default.

239 changes: 218 additions & 21 deletions Algorithms/azp.h
Expand Up @@ -161,6 +161,20 @@ class ObjectiveFunction
}
return ss;
}

virtual double GetRawValue() {
// Calculate the value of the objective function
double ss = 0; // e.g. sum of squares
REGION_AREAS::iterator it;
for (it = regions.begin(); it != regions.end(); ++it) {
int region = it->first;
// objective function of region needs to be computed
double obj = getObjectiveValue(regions[region]);
ss += obj;
}
return ss;
}


virtual void UpdateRegions() {
// region changes, update it's
Expand Down Expand Up @@ -261,7 +275,7 @@ class ObjectiveFunction
boost::unordered_map<int, bool> to_areas = regions[to_region];
from_areas.erase(area);
to_areas[area] = false;

double ss_from = getObjectiveValue(from_areas);
double ss_to = getObjectiveValue(to_areas);

Expand All @@ -288,6 +302,11 @@ class ObjectiveFunction
// use reference here to make actual change
boost::unordered_map<int, bool>& from_areas = regions[from_region];
boost::unordered_map<int, bool>& to_areas = regions[to_region];

if (from_areas.size() <=1) {
// has to make sure each region has at least one area
return 0;
}
from_areas.erase(area);
to_areas[area] = false;

Expand Down Expand Up @@ -315,7 +334,11 @@ class ObjectiveFunction
// adding an area from a region)
areas2Eval[areaID] = true;
}


if (areas2Eval.empty()) {
return false;
}

// remove the area first
int seedArea = areas2Eval.begin()->first;

Expand All @@ -338,7 +361,7 @@ class ObjectiveFunction
// all should be removed if all connected
return areas2Eval.empty();
}

protected:
// n: number of observations
int n;
Expand Down Expand Up @@ -379,19 +402,22 @@ class RegionMaker
// Sets the initial seeds for clustering
void setSeeds(std::vector<int> seeds);

virtual void LocalImproving() = 0;
virtual void LocalImproving() {}

virtual std::vector<int> GetResults() = 0;
virtual std::vector<int> GetResults() { return std::vector<int>();}

virtual double GetInitObjectiveFunction() = 0;
virtual double GetInitObjectiveFunction() { return 0;}

virtual double GetFinalObjectiveFunction() = 0;
virtual double GetFinalObjectiveFunction() { return 0;}

// Check is_control_satisfied
bool IsSatisfyControls();

int GetPRegions() { return region2Area.size();}


void Copy(RegionMaker& rm);

protected:
// Return the areas of a region
//boost::unordered_map<int, bool> returnRegion2Area(int regionID);
Expand Down Expand Up @@ -452,6 +478,14 @@ class RegionMaker

ObjectiveFunction* objective_function;

std::vector<ZoneControl> controls;

Xoroshiro128Random rng;

bool is_control_satisfied;

public:
// for copy
std::vector<int> init_regions;

boost::unordered_map<int, bool> unassignedAreas;
Expand All @@ -476,12 +510,6 @@ class RegionMaker

// object function value
double objInfo;

std::vector<ZoneControl> controls;

Xoroshiro128Random rng;

bool is_control_satisfied;
};

////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -523,12 +551,15 @@ class MaxpRegionMaker : public RegionMaker
}

protected:
std::vector<int> returnRegions();

void InitSolution();

protected:
std::vector<int> init_areas;
};


////////////////////////////////////////////////////////////////////////////////
////// MaxpRegion
////////////////////////////////////////////////////////////////////////////////
Expand All @@ -541,10 +572,10 @@ class MaxpRegion : public RegionMaker
double final_objectivefunction;

public:
MaxpRegion(int max_attemps, GalElement* const w,
MaxpRegion(int max_iter, GalElement* const w,
double** data, // row-wise
RawDistMatrix* dist_matrix,
int n, int m, const std::vector<ZoneControl>& c,
int n, int m, const std::vector<ZoneControl>& c, int inits=0,
const std::vector<int>& init_areas=std::vector<int>(),
long long seed=123456789);

Expand All @@ -564,10 +595,142 @@ class MaxpRegion : public RegionMaker
return final_objectivefunction;
}

void RunAZP(std::vector<int>& solution, long long seed, int i);

void RunConstruction(long long seed);

protected:
std::vector<int> init_areas;

int max_iter;

std::map<double, std::vector<int> > candidates;

int largest_p;

double best_of;

std::vector<int> best_result;

boost::mutex mutex;
};

class MaxpSA : public RegionMaker
{
std::vector<int> final_solution;

double initial_objectivefunction;

double final_objectivefunction;

public:
MaxpSA(int max_iter, GalElement* const w,
double** data, // row-wise
RawDistMatrix* dist_matrix,
int n, int m, const std::vector<ZoneControl>& c,
double alpha = 0.85, int sa_iter= 1, int inits=0,
const std::vector<int>& init_regions=std::vector<int>(),
long long seed=123456789);

virtual ~MaxpSA() {}

virtual void LocalImproving() {}

virtual std::vector<int> GetResults() {
return final_solution;
}

virtual double GetInitObjectiveFunction() {
return initial_objectivefunction;
}

virtual double GetFinalObjectiveFunction() {
return final_objectivefunction;
}

void RunAZP(std::vector<int>& solution, long long seed, int i);

void RunConstruction(long long seed);

protected:
std::vector<int> init_areas;

int max_iter;

double temperature;

double alpha;

int sa_iter;

int largest_p;

double best_of;

std::vector<int> best_result;

std::map<double, std::vector<int> > candidates;

boost::mutex mutex;
};

class MaxpTabu : public RegionMaker
{
std::vector<int> final_solution;

double initial_objectivefunction;

double final_objectivefunction;

public:
MaxpTabu(int max_iter, GalElement* const w,
double** data, // row-wise
RawDistMatrix* dist_matrix,
int n, int m, const std::vector<ZoneControl>& c,
int tabu_length=10, int _conv_tabu=0, int inits=0,
const std::vector<int>& init_areas=std::vector<int>(),
long long seed=123456789);

virtual ~MaxpTabu() {}

virtual void LocalImproving() {}

virtual std::vector<int> GetResults() {
return final_solution;
}

virtual double GetInitObjectiveFunction() {
return initial_objectivefunction;
}

virtual double GetFinalObjectiveFunction() {
return final_objectivefunction;
}

void RunAZP(std::vector<int>& solution, long long seed, int i);

void RunConstruction(long long seed);

int GetConvTabu() { return convTabu;}

protected:
std::vector<int> init_areas;

int max_attemps;
int max_iter;

int tabuLength; //5

int convTabu;

int largest_p;

double best_of;

std::vector<int> best_result;

std::map<double, std::vector<int> > candidates;

boost::mutex mutex;
};

////////////////////////////////////////////////////////////////////////////////
Expand All @@ -585,11 +748,21 @@ class AZP : public RegionMaker
AZP(int p, GalElement* const w,
double** data, // row-wise
RawDistMatrix* dist_matrix,
int n, int m, const std::vector<ZoneControl>& c,
int n, int m, const std::vector<ZoneControl>& c, int inits=0,
const std::vector<int>& init_regions=std::vector<int>(),
long long seed=123456789)
: RegionMaker(p,w,data,dist_matrix,n,m,c,init_regions, seed)
{
if (inits > 0) {
// ARiSeL
for (int i=0; i<inits-1; ++i) {
RegionMaker rm(p,w,data,dist_matrix,n,m,c,init_regions, seed + i);
if (rm.objInfo < this->objInfo && rm.IsSatisfyControls()) {
// better initial solution
this->Copy(rm);
}
}
}
initial_objectivefunction = this->objInfo;
double best_score = this->objInfo;
bool improvement = true;
Expand Down Expand Up @@ -655,17 +828,29 @@ class AZPSA : public RegionMaker
double** data, // row-wise
RawDistMatrix* dist_matrix,
int n, int m, const std::vector<ZoneControl>& c,
double _alpha = 0.85, int _max_iter= 1,
double _alpha = 0.85, int _max_iter= 1, int inits=0,
const std::vector<int>& init_regions=std::vector<int>(),
long long seed=123456789)
: RegionMaker(p,w,data,dist_matrix,n,m,c,init_regions,seed), temperature(1.0),
alpha(_alpha), max_iter(_max_iter)
{
if (inits > 0) {
// ARiSeL
for (int i=0; i<inits-1; ++i) {
RegionMaker rm(p,w,data,dist_matrix,n,m,c,init_regions, seed + i);
if (rm.objInfo < this->objInfo && rm.IsSatisfyControls()) {
// better initial solution
this->Copy(rm);
}
}
}

std::vector<int> init_sol = this->returnRegions();
initial_objectivefunction = this->objInfo;

// local search
BasicMemory basicMemory, localBasicMemory;
basicMemory.updateBasicMemory(this->objInfo, this->returnRegions());

// step a
int k = 0;
Expand All @@ -685,6 +870,7 @@ class AZPSA : public RegionMaker
basicMemory.updateBasicMemory(this->objInfo, this->returnRegions());
}
}
//std::cout << basicMemory.objInfo << std::endl;
// step c
temperature *= alpha; // annealing
if (improved == 1) {
Expand Down Expand Up @@ -748,12 +934,23 @@ class AZPTabu : public RegionMaker
double** data, // row-wise
RawDistMatrix* dist_matrix,
int n, int m, const std::vector<ZoneControl>& c,
int tabu_length=10, int _convTabu=0,
int tabu_length=10, int _convTabu=0, int inits = 0,
const std::vector<int>& init_regions=std::vector<int>(),
long long seed=123456789)
: RegionMaker(p,w,data,dist_matrix,n,m,c,init_regions, seed),
tabuLength(tabu_length), convTabu(_convTabu)
{
if (inits > 0) {
// ARiSeL
for (int i=0; i<inits-1; ++i) {
RegionMaker rm(p,w,data,dist_matrix,n,m,c,init_regions, seed + i);
if (rm.objInfo < this->objInfo && rm.IsSatisfyControls()) {
// better initial solution
this->Copy(rm);
}
}
}

if (tabuLength <= 0) {
tabuLength = 10;
}
Expand All @@ -765,7 +962,7 @@ class AZPTabu : public RegionMaker

this->LocalImproving();

final_solution = this->returnRegions();
final_solution = this->regions;
final_objectivefunction = this->objInfo;
}

Expand Down Expand Up @@ -793,7 +990,7 @@ class AZPTabu : public RegionMaker
protected:
int tabuLength; //5

int convTabu; // 5: 230*numpy.sqrt(pRegions)?ß
int convTabu; // 5: 230*numpy.sqrt(pRegions)?

boost::unordered_map<std::pair<int, int>, double> neighSolutions;

Expand Down

0 comments on commit cc4e9a9

Please sign in to comment.