From 364ef8219fb09b9ffc9e2d10f53aa6729336c4bd Mon Sep 17 00:00:00 2001 From: Xun Li Date: Thu, 29 Oct 2020 23:00:00 -0700 Subject: [PATCH] AZP: add ARiSeL #2266 --- Algorithms/azp.cpp | 17 +++++++++-- Algorithms/azp.h | 63 +++++++++++++++++++++++++++++++--------- DialogTools/AZPDlg.cpp | 65 +++++++++++++++++++++++++++++++++++------- DialogTools/AZPDlg.h | 3 ++ 4 files changed, 122 insertions(+), 26 deletions(-) diff --git a/Algorithms/azp.cpp b/Algorithms/azp.cpp index b1cd3370b..c9b425306 100644 --- a/Algorithms/azp.cpp +++ b/Algorithms/azp.cpp @@ -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& init_regions) { // check init regions, index start from 1 @@ -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 results = azp.GetResults(); double init_of = azp.GetInitObjectiveFunction(); double of = azp.GetFinalObjectiveFunction(); diff --git a/Algorithms/azp.h b/Algorithms/azp.h index bd518232b..1f6ee0f51 100644 --- a/Algorithms/azp.h +++ b/Algorithms/azp.h @@ -379,19 +379,22 @@ class RegionMaker // Sets the initial seeds for clustering void setSeeds(std::vector seeds); - virtual void LocalImproving() = 0; + virtual void LocalImproving() {} - virtual std::vector GetResults() = 0; + virtual std::vector GetResults() { return std::vector();} - 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 returnRegion2Area(int regionID); @@ -452,6 +455,14 @@ class RegionMaker ObjectiveFunction* objective_function; + std::vector controls; + + Xoroshiro128Random rng; + + bool is_control_satisfied; + +public: + // for copy std::vector init_regions; boost::unordered_map unassignedAreas; @@ -476,12 +487,6 @@ class RegionMaker // object function value double objInfo; - - std::vector controls; - - Xoroshiro128Random rng; - - bool is_control_satisfied; }; //////////////////////////////////////////////////////////////////////////////// @@ -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& c, + int n, int m, const std::vector& c, int inits=0, const std::vector& init_regions=std::vector(), long long seed=123456789) : RegionMaker(p,w,data,dist_matrix,n,m,c,init_regions, seed) { + if (inits > 0) { + // ARiSeL + for (int i=0; iobjInfo) { + // better initial solution + this->Copy(rm); + } + } + } initial_objectivefunction = this->objInfo; double best_score = this->objInfo; bool improvement = true; @@ -655,12 +670,23 @@ class AZPSA : public RegionMaker double** data, // row-wise RawDistMatrix* dist_matrix, int n, int m, const std::vector& c, - double _alpha = 0.85, int _max_iter= 1, + double _alpha = 0.85, int _max_iter= 1, int inits=0, const std::vector& init_regions=std::vector(), 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; iobjInfo) { + // better initial solution + this->Copy(rm); + } + } + } + std::vector init_sol = this->returnRegions(); initial_objectivefunction = this->objInfo; @@ -748,12 +774,23 @@ class AZPTabu : public RegionMaker double** data, // row-wise RawDistMatrix* dist_matrix, int n, int m, const std::vector& c, - int tabu_length=10, int _convTabu=0, + int tabu_length=10, int _convTabu=0, int inits = 0, const std::vector& init_regions=std::vector(), 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; iobjInfo) { + // better initial solution + this->Copy(rm); + } + } + } + if (tabuLength <= 0) { tabuLength = 10; } diff --git a/DialogTools/AZPDlg.cpp b/DialogTools/AZPDlg.cpp index 6b4238073..8e3248721 100644 --- a/DialogTools/AZPDlg.cpp +++ b/DialogTools/AZPDlg.cpp @@ -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:")); @@ -90,19 +90,22 @@ 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); @@ -110,6 +113,25 @@ void AZPDlg::CreateControls() 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); @@ -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) @@ -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; @@ -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."); diff --git a/DialogTools/AZPDlg.h b/DialogTools/AZPDlg.h index 34cbb08ed..be8d1d533 100644 --- a/DialogTools/AZPDlg.h +++ b/DialogTools/AZPDlg.h @@ -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); @@ -57,6 +58,7 @@ class AZPDlg : public AbstractClusterDlg private: wxCheckBox* chk_seed; wxCheckBox* chk_lisa; + wxCheckBox* chk_arisel; wxChoice* combo_lisa; @@ -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;