Skip to content

Commit

Permalink
AZP: add ARiSeL GeoDaCenter#2266
Browse files Browse the repository at this point in the history
  • Loading branch information
lixun910 committed Oct 30, 2020
1 parent 8b1053b commit 364ef82
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 26 deletions.
17 changes: 15 additions & 2 deletions Algorithms/azp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,19 @@ RegionMaker::~RegionMaker()
}
}

void RegionMaker::Copy(RegionMaker& rm)
{
this->init_regions = rm.init_regions;
this->unassignedAreas = rm.unassignedAreas;
this->assignedAreas = rm.assignedAreas;
this->areaNoNeighbor = rm.areaNoNeighbor;
this->area2Region = rm.area2Region;
this->region2Area = rm.region2Area;
this->potentialRegions4Area = rm.potentialRegions4Area;
this->candidateInfo = rm.candidateInfo;
this->objInfo = rm.objInfo;
}

void RegionMaker::InitFromRegion(std::vector<int>& init_regions)
{
// check init regions, index start from 1
Expand Down Expand Up @@ -989,7 +1002,7 @@ void MaxpRegionMaker::InitSolution()
r = r + 1; // create another region
}
}
std::cout << r << std::endl;
//std::cout << r << std::endl;
// find potential
if (unassignedAreas.size() > 0) {
for (int i=0; i<region2Area.size(); ++i) {
Expand Down Expand Up @@ -1068,7 +1081,7 @@ init_areas(_init_areas), max_attemps(_max_attemps)
for (int i=0; i<solution.size(); ++i) {
solution[i] += 1; // index starts from 1 not 0
}
AZP azp(p, w, data, dist_matrix, n, m, c, solution, seed);
AZP azp(p, w, data, dist_matrix, n, m, c, 0, solution, seed);
std::vector<int> results = azp.GetResults();
double init_of = azp.GetInitObjectiveFunction();
double of = azp.GetFinalObjectiveFunction();
Expand Down
63 changes: 50 additions & 13 deletions Algorithms/azp.h
Original file line number Diff line number Diff line change
Expand Up @@ -379,19 +379,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 +455,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 +487,6 @@ class RegionMaker

// object function value
double objInfo;

std::vector<ZoneControl> controls;

Xoroshiro128Random rng;

bool is_control_satisfied;
};

////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -585,11 +590,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) {
// better initial solution
this->Copy(rm);
}
}
}
initial_objectivefunction = this->objInfo;
double best_score = this->objInfo;
bool improvement = true;
Expand Down Expand Up @@ -655,12 +670,23 @@ 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) {
// better initial solution
this->Copy(rm);
}
}
}

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

Expand Down Expand Up @@ -748,12 +774,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) {
// better initial solution
this->Copy(rm);
}
}
}

if (tabuLength <= 0) {
tabuLength = 10;
}
Expand Down
65 changes: 54 additions & 11 deletions DialogTools/AZPDlg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ void AZPDlg::CreateControls()
AddSimpleInputCtrls(panel, vbox, false, true/*show spatial weights controls*/);

// Parameters
wxFlexGridSizer* gbox = new wxFlexGridSizer(9,2,5,0);
wxFlexGridSizer* gbox = new wxFlexGridSizer(10,2,5,0);

// Number of Regions
wxStaticText* st_region = new wxStaticText(panel, wxID_ANY, _("Number of Regions:"));
Expand All @@ -90,26 +90,48 @@ void AZPDlg::CreateControls()

// Method
wxStaticText* st19 = new wxStaticText(panel, wxID_ANY, _("Method:"));
wxString choices19[] = {"AZP", "AZP-Tabu Search", "AZP-Simulated Annealing"};
m_localsearch = new wxChoice(panel, wxID_ANY, wxDefaultPosition, wxSize(200,-1), 3, choices19);
wxString choices19[] = {"AZP", "AZP-Tabu Search", "AZP-Simulated Annealing", "ARiSeL"};
m_localsearch = new wxChoice(panel, wxID_ANY, wxDefaultPosition, wxSize(200,-1), 4, choices19);
m_localsearch->SetSelection(0);
wxBoxSizer *hbox19_1 = new wxBoxSizer(wxHORIZONTAL);
hbox19_1->Add(new wxStaticText(panel, wxID_ANY, _("Tabu Length:")));
m_tabulength = new wxTextCtrl(panel, wxID_ANY, "10");
hbox19_1->Add(m_tabulength);
m_tabulength->Disable();

wxBoxSizer *hbox19_2 = new wxBoxSizer(wxHORIZONTAL);
hbox19_2->Add(new wxStaticText(panel, wxID_ANY, _("Cooling Rate:")));
m_coolrate= new wxTextCtrl(panel, wxID_ANY, "0.85");
hbox19_2->Add(m_coolrate);
m_coolrate->Disable();

wxBoxSizer *hbox19_1 = new wxBoxSizer(wxHORIZONTAL);
hbox19_1->Add(new wxStaticText(panel, wxID_ANY, _("Tabu Length:")));
m_tabulength = new wxTextCtrl(panel, wxID_ANY, "10");
hbox19_1->Add(m_tabulength);
m_tabulength->Disable();

wxBoxSizer *vbox19 = new wxBoxSizer(wxVERTICAL);
vbox19->Add(m_localsearch, 1, wxEXPAND);
vbox19->Add(hbox19_1, 1, wxEXPAND);
vbox19->Add(hbox19_2, 1, wxEXPAND);
gbox->Add(st19, 0, wxALIGN_TOP | wxRIGHT | wxLEFT, 10);
gbox->Add(vbox19, 1, wxEXPAND);

// ARiSeL
wxBoxSizer *hbox19_3 = new wxBoxSizer(wxHORIZONTAL);
hbox19_3->Add(new wxStaticText(panel, wxID_ANY, _("Inits:")));
m_inits = new wxTextCtrl(panel, wxID_ANY, "5");
hbox19_3->Add(m_inits);
m_inits->Disable();

wxStaticText* st20 = new wxStaticText(panel, wxID_ANY, _("ARiSeL:"));
wxBoxSizer *hbox20 = new wxBoxSizer(wxHORIZONTAL);
chk_arisel = new wxCheckBox(panel, wxID_ANY, "");
m_inits = new wxTextCtrl(panel, wxID_ANY, "10", wxDefaultPosition, wxSize(30,-1));
m_inits->Disable();

hbox20->Add(chk_arisel,0, wxALIGN_CENTER_VERTICAL);
hbox20->Add(m_inits,0,wxALIGN_CENTER_VERTICAL);
hbox20->Add(new wxStaticText(panel, wxID_ANY, _("Construction Re-runs (inits)")),0,wxALIGN_CENTER_VERTICAL);
gbox->Add(st20, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT | wxLEFT, 10);
gbox->Add(hbox20, 1, wxEXPAND);

// Minimum Bound Control
AddMinBound(panel, gbox);

Expand Down Expand Up @@ -224,7 +246,12 @@ void AZPDlg::CreateControls()
seedButton->Bind(wxEVT_BUTTON, &AZPDlg::OnChangeSeed, this);
chk_lisa->Bind(wxEVT_CHECKBOX, &AZPDlg::OnLISACheck, this);
m_localsearch->Bind(wxEVT_CHOICE, &AZPDlg::OnLocalSearch, this);
chk_arisel->Bind(wxEVT_CHECKBOX, &AZPDlg::OnAriselCheck, this);
}

void AZPDlg::OnAriselCheck(wxCommandEvent& event)
{
m_inits->Enable(chk_arisel->IsChecked());
}

void AZPDlg::OnLocalSearch(wxCommandEvent& event)
Expand Down Expand Up @@ -594,6 +621,22 @@ void AZPDlg::OnOK(wxCommandEvent& event )
}
}

// no ARiSeL by default
int inits = 0;
if (chk_arisel->IsChecked()) {
wxString str_inits = m_inits->GetValue();
long n_inits;
if (str_inits.ToLong(&n_inits)) {
inits = (int)n_inits;
}
if (inits < 1) {
wxString err_msg = _("Inits for ARISeL is the number of times the construction of initial feasible solution repeated, it has to be an integer number larger than 1 (default is 10).");
wxMessageDialog dlg(NULL, err_msg, _("Error"), wxOK | wxICON_ERROR);
dlg.ShowModal();
return;
}
}

// Get random seed
long long rnd_seed = (long long) time(0);
if (chk_seed->GetValue()) rnd_seed = GdaConst::gda_user_seed;
Expand All @@ -607,17 +650,17 @@ void AZPDlg::OnOK(wxCommandEvent& event )
RegionMaker* azp;
if ( local_search_method == 0) {
azp = new AZP(p, gw->gal, input_data, &dm, rows, columns,
controllers, init_regions, rnd_seed);
controllers, inits, init_regions, rnd_seed);

} else if ( local_search_method == 1) {
int convergence_criteria = std::max(10, rows / p); // vs 230 * sqrt(p)
azp = new AZPTabu(p, gw->gal, input_data, &dm, rows, columns,
controllers, tabu_length, convergence_criteria,
init_regions, rnd_seed);
inits, init_regions, rnd_seed);
} else {
int max_iter = 1;
azp = new AZPSA(p, gw->gal, input_data, &dm, rows, columns,
controllers, cool_rate, max_iter, init_regions, rnd_seed);
controllers, cool_rate, max_iter, inits, init_regions, rnd_seed);
}
if (azp->IsSatisfyControls() == false) {
wxString msg = _("The clustering results violate the requirement of minimum bound or minimum number per region. Please adjust the input and try again.");
Expand Down
3 changes: 3 additions & 0 deletions DialogTools/AZPDlg.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ class AZPDlg : public AbstractClusterDlg
void OnSeedCheck(wxCommandEvent& event);
void OnChangeSeed(wxCommandEvent& event);
void OnLISACheck(wxCommandEvent& event);
void OnAriselCheck(wxCommandEvent& event);

virtual void update(TableState* o);
virtual void OnCheckMinBound(wxCommandEvent& event);
Expand All @@ -57,6 +58,7 @@ class AZPDlg : public AbstractClusterDlg
private:
wxCheckBox* chk_seed;
wxCheckBox* chk_lisa;
wxCheckBox* chk_arisel;

wxChoice* combo_lisa;

Expand All @@ -70,6 +72,7 @@ class AZPDlg : public AbstractClusterDlg
wxTextCtrl* txt_regions;
wxTextCtrl* m_tabulength;
wxTextCtrl* m_coolrate;
wxTextCtrl* m_inits;
wxButton* seedButton;

wxString select_floor;
Expand Down

0 comments on commit 364ef82

Please sign in to comment.