From bdd9d16b06496001293d8c8c8e1dd31edc58e0e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Macholda?= Date: Mon, 29 Dec 2025 18:10:58 +0100 Subject: [PATCH 01/10] resolve sortPopulation linking conflict MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit function was defined in the header file and included multiple times Signed-off-by: Tomáš Macholda --- src/base/includes/GAUtils.hpp | 8 +++----- src/base/sources/GAUtils.cpp | 6 +++++- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/base/includes/GAUtils.hpp b/src/base/includes/GAUtils.hpp index 44e4396..341b2ef 100644 --- a/src/base/includes/GAUtils.hpp +++ b/src/base/includes/GAUtils.hpp @@ -4,9 +4,6 @@ #include "Population.hpp" namespace GAUtils{ - auto sortPopulation = [](vector &a, vector &b) { return getFitness(a) < getFitness(b); - }; - //Import the map, the tours generated by the LK and fill the population void init(Population &); @@ -44,6 +41,7 @@ namespace GAUtils{ vector roulete(Population&); vector nearestNeighbor(); -} -#endif \ No newline at end of file + int sortPopulation(vector &a, vector &b); +} +#endif diff --git a/src/base/sources/GAUtils.cpp b/src/base/sources/GAUtils.cpp index 8d3e9bd..088b253 100644 --- a/src/base/sources/GAUtils.cpp +++ b/src/base/sources/GAUtils.cpp @@ -336,4 +336,8 @@ vector GAUtils::nearestNeighbor() { }while(!cityList.empty()); return tmp; -} \ No newline at end of file +} + +int GAUtils::sortPopulation(vector &a, vector &b){ + return getFitness(a) < getFitness(b); +} From f54d873fcafcc49c77b3b77993c0b639b0d3a338 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Macholda?= Date: Mon, 29 Dec 2025 19:32:00 +0100 Subject: [PATCH 02/10] resolve segfault because of erasing vector end() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomáš Macholda --- src/cross/gpx/sources/GPX2Fusion.cpp | 4 ++-- src/cross/gpx/sources/GPX2Support.cpp | 4 +--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/cross/gpx/sources/GPX2Fusion.cpp b/src/cross/gpx/sources/GPX2Fusion.cpp index c013e85..5005c10 100644 --- a/src/cross/gpx/sources/GPX2Fusion.cpp +++ b/src/cross/gpx/sources/GPX2Fusion.cpp @@ -106,7 +106,7 @@ void GPX2Fusion::fusePartitions(vector &fuseW // Apagar o último nó pois é onde ele se conecta na partição que será unida if (!tmp.second.empty()) { - tmp.second.erase(tmp.second.end()); + tmp.second.pop_back(); } } @@ -303,7 +303,7 @@ bool GPX2Fusion::unfeasiblePartitionsConnected(GPX2Structs::PartitionMap &partit nodesAlreadyChecked.push_back(connectedId); } else { // Apaga por estar conectado com uma feasible - partitions[node.second]->getConnectedTo().erase(partitions[node.second]->getConnectedTo().end()); + partitions[node.second]->getConnectedTo().pop_back(); } } } diff --git a/src/cross/gpx/sources/GPX2Support.cpp b/src/cross/gpx/sources/GPX2Support.cpp index 37f45ae..48ef61a 100644 --- a/src/cross/gpx/sources/GPX2Support.cpp +++ b/src/cross/gpx/sources/GPX2Support.cpp @@ -74,9 +74,7 @@ void GPX2Support::cleanInsideAccess(GPX2Structs::PartitionMap &partitions, GPX2S accessNodesAV.push_back(result.second.back()); result.second.erase(result.second.begin()); - result.second.erase(result.second.end()); - - + result.second.pop_back(); p.second->getNodes().insert(p.second->getNodes().end(),result.second.begin(), result.second.end()); } From d8383103be5a3164300a6fd8dfab0cbef5bc0132 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Macholda?= Date: Fri, 2 Jan 2026 15:45:13 +0100 Subject: [PATCH 03/10] makefile refactoring MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomáš Macholda --- src/main.cpp => bin/gpx2.cpp | 59 +++++---- {src/cross/AntColony => include}/Ant.hpp | 0 .../cross/AntColony => include}/AntColony.hpp | 0 {src/args => include}/Arg.hpp | 0 {src/base/includes => include}/City.hpp | 0 .../cross/AntColony => include}/Constants.hpp | 0 .../base/includes => include}/Coordinates.hpp | 0 {src/base/includes => include}/GAUtils.hpp | 0 {src/cross/gpx/includes => include}/GPX2.hpp | 0 .../gpx/includes => include}/GPX2Fusion.hpp | 0 .../gpx/includes => include}/GPX2Structs.hpp | 0 .../gpx/includes => include}/GPX2Support.hpp | 0 {src/base/includes => include}/Globals.hpp | 0 {src/base/includes => include}/ImportData.hpp | 0 {src/base/includes => include}/Log.hpp | 0 {src/cross/gpx/includes => include}/Node.hpp | 0 {src/cross/OX => include}/OX.hpp | 0 {src/opt => include}/Opt.hpp | 0 .../gpx/includes => include}/Partition.hpp | 0 {src/base/includes => include}/Population.hpp | 0 {src/base/includes => include}/Utils.hpp | 0 mkfile | 54 ++++++++ src/base/{sources => }/City.cpp | 0 src/base/{sources => }/Coordinates.cpp | 0 src/base/{sources => }/GAUtils.cpp | 99 ++++++++------- src/base/{sources => }/Globals.cpp | 0 src/base/{sources => }/ImportData.cpp | 0 src/base/{sources => }/Log.cpp | 0 src/base/{sources => }/Population.cpp | 0 src/base/{sources => }/Utils.cpp | 0 src/cross/AntColony/Ant.cpp | 93 -------------- src/cross/AntColony/AntColony.cpp | 70 ----------- src/cross/AntColony/Constants.cpp | 118 ------------------ src/cross/gpx/{sources => }/GPX2.cpp | 0 src/cross/gpx/{sources => }/GPX2Fusion.cpp | 1 + src/cross/gpx/{sources => }/GPX2Support.cpp | 0 src/cross/gpx/{sources => }/Node.cpp | 0 src/cross/gpx/{sources => }/Partition.cpp | 0 src/opt/Opt.cpp | 2 +- 39 files changed, 133 insertions(+), 363 deletions(-) rename src/main.cpp => bin/gpx2.cpp (87%) rename {src/cross/AntColony => include}/Ant.hpp (100%) rename {src/cross/AntColony => include}/AntColony.hpp (100%) rename {src/args => include}/Arg.hpp (100%) rename {src/base/includes => include}/City.hpp (100%) rename {src/cross/AntColony => include}/Constants.hpp (100%) rename {src/base/includes => include}/Coordinates.hpp (100%) rename {src/base/includes => include}/GAUtils.hpp (100%) rename {src/cross/gpx/includes => include}/GPX2.hpp (100%) rename {src/cross/gpx/includes => include}/GPX2Fusion.hpp (100%) rename {src/cross/gpx/includes => include}/GPX2Structs.hpp (100%) rename {src/cross/gpx/includes => include}/GPX2Support.hpp (100%) rename {src/base/includes => include}/Globals.hpp (100%) rename {src/base/includes => include}/ImportData.hpp (100%) rename {src/base/includes => include}/Log.hpp (100%) rename {src/cross/gpx/includes => include}/Node.hpp (100%) rename {src/cross/OX => include}/OX.hpp (100%) rename {src/opt => include}/Opt.hpp (100%) rename {src/cross/gpx/includes => include}/Partition.hpp (100%) rename {src/base/includes => include}/Population.hpp (100%) rename {src/base/includes => include}/Utils.hpp (100%) create mode 100644 mkfile rename src/base/{sources => }/City.cpp (100%) rename src/base/{sources => }/Coordinates.cpp (100%) rename src/base/{sources => }/GAUtils.cpp (75%) rename src/base/{sources => }/Globals.cpp (100%) rename src/base/{sources => }/ImportData.cpp (100%) rename src/base/{sources => }/Log.cpp (100%) rename src/base/{sources => }/Population.cpp (100%) rename src/base/{sources => }/Utils.cpp (100%) delete mode 100644 src/cross/AntColony/Ant.cpp delete mode 100644 src/cross/AntColony/AntColony.cpp delete mode 100644 src/cross/AntColony/Constants.cpp rename src/cross/gpx/{sources => }/GPX2.cpp (100%) rename src/cross/gpx/{sources => }/GPX2Fusion.cpp (99%) rename src/cross/gpx/{sources => }/GPX2Support.cpp (100%) rename src/cross/gpx/{sources => }/Node.cpp (100%) rename src/cross/gpx/{sources => }/Partition.cpp (100%) diff --git a/src/main.cpp b/bin/gpx2.cpp similarity index 87% rename from src/main.cpp rename to bin/gpx2.cpp index 145d5bf..ba44422 100644 --- a/src/main.cpp +++ b/bin/gpx2.cpp @@ -4,6 +4,8 @@ using std::random_device; #include using std::ofstream; +#include + #include using std::cout; using std::endl; @@ -26,6 +28,8 @@ using std::stoi; #include "GAUtils.hpp" #include "Log.hpp" #include "Arg.hpp" +#include "ImportData.hpp" +#include "Opt.hpp" #include "Constants.hpp" @@ -52,37 +56,30 @@ int main(int argc, char *argv[]) { random_device rng; Globals::urng.seed(rng()); - // vector t1,t2; - // t1.push_back(1); - // t1.push_back(2); - // t1.push_back(3); - // t1.push_back(4); - // t1.push_back(5); - // t1.push_back(6); - - // t2.push_back(5); - // t2.push_back(6); - // t2.push_back(4); - // t2.push_back(2); - // t2.push_back(1); - // t2.push_back(3); - // Globals::TOUR_SIZE = t1.size(); - - // cout<<"chegou aqui?"< tour; - initArgs(argc,argv); + std::getline(std::cin, line); + std::istringstream iss(line); + int tmp; - GA(); + cout << "pushing" << endl; + while (iss >> tmp) { + tour.push_back(tmp); + } + std::vector res; + cout << "optimizing" << endl; + Opt::optimize(tour); + for (auto i : tour) + cout << i << " "; return 0; } @@ -98,8 +95,8 @@ void GA() { auto start = std::chrono::high_resolution_clock::now(); GAUtils::init(pop); - AntMap::initMap(); - AntMap::updatePheromoneMap(pop.getBestTour()); + // AntMap::initMap(); + // AntMap::updatePheromoneMap(pop.getBestTour()); // cout<<"tour size "< @@ -115,8 +114,8 @@ Population GAUtils::generateNewPopulation(Population &pop) { return crossOX(pop); }else if(Config::NEW_POP_TYPE==1){ return crossAllxAllwithNBestAndReset(pop); - }else if(Config::NEW_POP_TYPE==2){ - return crossGPX2WithAntColony(pop); + // }else if(Config::NEW_POP_TYPE==2){ + // return crossGPX2WithAntColony(pop); }else{ //default return crossAllxAllwithNBestAndReset(pop); @@ -196,74 +195,74 @@ Population GAUtils::crossAllxAllwithNBestAndReset(Population &pop){ return newPop; } -Population GAUtils::crossGPX2WithAntColony(Population &pop){ - Population newPop, tmpPop; - vector currentTour; +// Population GAUtils::crossGPX2WithAntColony(Population &pop){ +// Population newPop, tmpPop; +// vector currentTour; - sort(pop.getPopulation().begin(), pop.getPopulation().end(),sortPopulation); +// sort(pop.getPopulation().begin(), pop.getPopulation().end(),sortPopulation); - for (unsigned i = 0; i < Config::POP_SIZE; i++) { - currentTour = pop.getPopulation()[i]; - for (unsigned j = 0; j < Config::POP_SIZE; j++) { - if (i != j) { - vector t = GPX2::crossover(pop.getPopulation()[j], currentTour); - currentTour = t; - } - } +// for (unsigned i = 0; i < Config::POP_SIZE; i++) { +// currentTour = pop.getPopulation()[i]; +// for (unsigned j = 0; j < Config::POP_SIZE; j++) { +// if (i != j) { +// vector t = GPX2::crossover(pop.getPopulation()[j], currentTour); +// currentTour = t; +// } +// } - tmpPop.getPopulation().push_back(currentTour); - } +// tmpPop.getPopulation().push_back(currentTour); +// } - sort(tmpPop.getPopulation().begin(), tmpPop.getPopulation().end(),sortPopulation); +// sort(tmpPop.getPopulation().begin(), tmpPop.getPopulation().end(),sortPopulation); - newPop.getPopulation().insert(newPop.getPopulation().end(),tmpPop.getPopulation().begin(),tmpPop.getPopulation().begin()+Config::N_BEST); +// newPop.getPopulation().insert(newPop.getPopulation().end(),tmpPop.getPopulation().begin(),tmpPop.getPopulation().begin()+Config::N_BEST); - tmpPop = AntColony().run(Config::POP_SIZE-(newPop.getPopulation().size())); +// tmpPop = AntColony().run(Config::POP_SIZE-(newPop.getPopulation().size())); - newPop.getPopulation().insert(newPop.getPopulation().end(),tmpPop.getPopulation().begin(),tmpPop.getPopulation().end()); +// newPop.getPopulation().insert(newPop.getPopulation().end(),tmpPop.getPopulation().begin(),tmpPop.getPopulation().end()); - return newPop; -} +// return newPop; +// } -Population GAUtils::crossGPX2WithAntColonyAndReset(Population &pop){ - Population newPop, tmpPop; - vector currentTour; +// Population GAUtils::crossGPX2WithAntColonyAndReset(Population &pop){ +// Population newPop, tmpPop; +// vector currentTour; - sort(pop.getPopulation().begin(), pop.getPopulation().end(),sortPopulation); +// sort(pop.getPopulation().begin(), pop.getPopulation().end(),sortPopulation); - for (unsigned i = 0; i < Config::POP_SIZE/10; i++) { - currentTour = pop.getPopulation()[i]; - for (unsigned j = 0; j < Config::POP_SIZE; j++) { - if (i != j) { - vector t = GPX2::crossover(pop.getPopulation()[j], currentTour); - currentTour = t; - } - } +// for (unsigned i = 0; i < Config::POP_SIZE/10; i++) { +// currentTour = pop.getPopulation()[i]; +// for (unsigned j = 0; j < Config::POP_SIZE; j++) { +// if (i != j) { +// vector t = GPX2::crossover(pop.getPopulation()[j], currentTour); +// currentTour = t; +// } +// } - newPop.getPopulation().push_back(currentTour); - } +// newPop.getPopulation().push_back(currentTour); +// } - fillPopulationWithReset(newPop, Config::POP_SIZE*Config::RESET_PERCENTAGE); +// fillPopulationWithReset(newPop, Config::POP_SIZE*Config::RESET_PERCENTAGE); - sort(newPop.getPopulation().begin(), newPop.getPopulation().end(),sortPopulation); - cout<<"Best tour from GPX2: "< -using std::find; -using std::sort; - -//utility -using std::make_pair; - -#include -using std::uniform_real_distribution; - -#include -using std::cout; -using std::endl; -using std::cin; - -//initialize path with initial city and get copy of pheromoneMap -Ant::Ant(int init){ - path.push_back(init); -} - -Ant::Ant(){} - -double Ant::calcChance(int nextCity){ - double pheromoneNext = AntMap::getPheromoneLevel(path.back(),nextCity); - double niNext = 1.0/distance(path.back(),nextCity); - double top = ((pow(pheromoneNext,AntConstants::alfa))*(pow(niNext,AntConstants::beta))); - - double bottom = 0.0; - { - double pheromoneTmp = 0.0; - double niTmp = 0.0; - for(unsigned city : Globals::map.getCityList()){ - if(find(path.begin(),path.end(),city) == path.end()){ - pheromoneTmp = AntMap::getPheromoneLevel(path.back(),city); - niTmp = 1.0/distance(path.back(),city); - bottom += ((pow(pheromoneTmp,AntConstants::alfa))*(pow(niTmp,AntConstants::beta))); - } - } - } - return top/bottom; -} - -void Ant::run(){ - while(path.size() choices; - double sum{0.0},rng{0.0}; - - for(unsigned city : Globals::map.getCityList()){ - if(find(path.begin(),path.end(),city) == path.end()){ - choices.push_back(make_pair(city,calcChance(city))); - } - } - - sort(choices.begin(),choices.end(),[](Choice& a, Choice& b){return a.second dist(0.0,sum); - - rng = dist(Globals::urng); - for(Choice c : choices){ - rng-=c.second; - if(rng<=0){ - return c.first; - } - } - return choices.back().first; -} - - - -vector& Ant::getPath(){ - return path; -} - -void Ant::setPath(vector path){ - this->path = path; -} \ No newline at end of file diff --git a/src/cross/AntColony/AntColony.cpp b/src/cross/AntColony/AntColony.cpp deleted file mode 100644 index 87cf45a..0000000 --- a/src/cross/AntColony/AntColony.cpp +++ /dev/null @@ -1,70 +0,0 @@ -#include "AntColony.hpp" - -#include "Utils.hpp" - -#include "Globals.hpp" - -#include -using std::cout; -using std::endl; - -#include -using std::to_string; - -#include "Constants.hpp" - -#include -using std::uniform_int_distribution; - -#include -using std::sort; - -#include "Opt.hpp" - -int AntColony::iteration = 0; - -Population AntColony::run(unsigned popToFill){ - vector colony; - uniform_int_distribution dist(1,Globals::TOUR_SIZE); - unsigned numberOfAnts{popToFill>Globals::TOUR_SIZE?popToFill:Globals::TOUR_SIZE}; - - for(unsigned i=0;igetFitness(colony.front().getPath())){ - AntMap::bestAntYet = colony.front(); - AntMap::bestFitnessYet = getFitness(AntMap::bestAntYet.getPath()); - } - - // cout<<"iterations without improvement: "<getFitness(colony.front().getPath())?(getFitness(colony.front().getPath())):(bestFitnessYet)); - - Population newPop; - for(unsigned i=0;i colony){ - cout<<"colony size: "< -using std::find; - -#include -using std::cout; -using std::endl; - -#include "Utils.hpp" - -#include -using std::pow; - -double AntConstants::alfa = 2.0; -double AntConstants::beta = 20.0; -double AntConstants::Q = 1.0; -double AntConstants::rho = 0.02; -double AntConstants::Pbest = 0.005; - -double **AntMap::pheromoneMap = nullptr; -int AntMap::bestFitnessYet = 0; -Ant AntMap::bestAntYet; - -//the first city in the TSP problem is 1 not 0 -double AntMap::getPheromoneLevel(int a,int b){ - return AntMap::pheromoneMap[a-1][b-1]; -} - -void AntMap::setPheromoneLevel(int a, int b, double newValue){ - AntMap::pheromoneMap[a-1][b-1] = newValue; -} - - -void AntMap::updatePheromoneMap(const vector& path){ - for(unsigned i=1;i<=Globals::TOUR_SIZE;i++){ - for(unsigned j=1;j<=Globals::TOUR_SIZE;j++){ - if(i!=j){ - double decay{((1-AntConstants::rho)*AntMap::getPheromoneLevel(i,j))}, - add{(constainsEdge(path,i,j)?(AntConstants::Q/getFitness(path)):(0.0))}, - max{maxPheromoneLevel()}, - min{minPheromoneLevel()}, - newValue{decay+add}; - - if(min>max){ - min = max; - } - - if(newValue > max){ - newValue = max; - }else if(newValue < min){ - newValue = min; - } - // cout<<"maxPheromoneLevel: "<& path,int a, int b){ - //find a position in ant`s path - long int aIndex{find(path.begin(),path.end(),a)-path.begin()}; - //if b is next in position them ant path contains the AB edge - return path[(aIndex+1)%Globals::TOUR_SIZE]==b; -} - - -void AntMap::printPheromoneMap(){ - for(unsigned i=1;i<=Globals::TOUR_SIZE;i++){ - for(unsigned j=1;j<=Globals::TOUR_SIZE;j++){ - cout< using std::find; diff --git a/src/cross/gpx/sources/GPX2Support.cpp b/src/cross/gpx/GPX2Support.cpp similarity index 100% rename from src/cross/gpx/sources/GPX2Support.cpp rename to src/cross/gpx/GPX2Support.cpp diff --git a/src/cross/gpx/sources/Node.cpp b/src/cross/gpx/Node.cpp similarity index 100% rename from src/cross/gpx/sources/Node.cpp rename to src/cross/gpx/Node.cpp diff --git a/src/cross/gpx/sources/Partition.cpp b/src/cross/gpx/Partition.cpp similarity index 100% rename from src/cross/gpx/sources/Partition.cpp rename to src/cross/gpx/Partition.cpp diff --git a/src/opt/Opt.cpp b/src/opt/Opt.cpp index 87dbc6e..ffff8cc 100644 --- a/src/opt/Opt.cpp +++ b/src/opt/Opt.cpp @@ -62,4 +62,4 @@ bool Opt::isBetter(edge &e1, edge &e2, vector &t){ }else{ return(false); } -} \ No newline at end of file +} From d4cf562a7b02e0c2a816f2d092c4eb640867c332 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Macholda?= Date: Fri, 2 Jan 2026 15:45:30 +0100 Subject: [PATCH 04/10] add opt.cpp MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomáš Macholda --- .gitignore | 7 ++-- Makefile | 105 ---------------------------------------------------- bin/opt.cpp | 92 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 95 insertions(+), 109 deletions(-) delete mode 100644 Makefile create mode 100644 bin/opt.cpp diff --git a/.gitignore b/.gitignore index e676334..afc37f0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,7 @@ -*.d *.dat -sources/*.o -bin/* +bin/gpx2 +bin/opt *.txt *.log @@ -11,4 +10,4 @@ bin/* .vscode/ scp/__pycache__/* -obj/* \ No newline at end of file +*.o diff --git a/Makefile b/Makefile deleted file mode 100644 index fbb740f..0000000 --- a/Makefile +++ /dev/null @@ -1,105 +0,0 @@ -COM_COLOR = \033[0;34m -OBJ_COLOR = \033[0m -OK_COLOR = \033[0;32m -ERROR_COLOR = \033[0;31m -WARN_COLOR = \033[0;33m -NO_COLOR = \033[m - -OK_STRING = "[OK]" -ERROR_STRING = "[ERROR]" -WARN_STRING = "[WARNING]" -COM_STRING = "Compiling" - - -define run_and_test -printf "%b" "$(COM_COLOR) $(COM_STRING) $(OBJ_COLOR) $(@F) $(NO_COLOR)\r"; \ -$(1) 2> $@.log; \ -RESULT=$$?; \ -if [ $$RESULT -ne 0 ]; then \ - printf "%-60b%b" "$(COM_COLOR) $(COM_STRING) $(OBJ_COLOR) $@" "$(ERROR_COLOR) $(ERROR_STRING) $(NO_COLOR)\n" ; \ -elif [ -s $@.log ]; then \ - printf "%-60b%b" "$(COM_COLOR) $(COM_STRING) $(OBJ_COLOR) $@" "$(WARN_COLOR) $(WARN_STRING) $(NO_COLOR)\n" ; \ -else \ - printf "%-60b%b" "$(COM_COLOR) $(COM_STRING) $(OBJ_COLOR) $(@F)" "$(OK_COLOR) $(OK_STRING) $(NO_COLOR)\n" ; \ -fi; \ -cat $@.log; \ -rm -f $@.log; \ -exit $$RESULT -endef - - -app = GPX2 - -srcExt = cpp -srcDir = src -objDir = obj -binDir = bin -inc = $(shell find -type f -iname "*.hpp" -printf "%h\n" | sort -u) - -debug = 0 - -CFlags = -Wall -std=gnu++17 -O3 -LDFlags = -libs = -libDir = - -#************************ DO NOT EDIT BELOW THIS LINE! **************** -ifeq ($(debug),1) - debug=-g -else - debug= -endif - -inc := $(addprefix -I,$(inc)) -libs := $(addprefix -l,$(libs)) -libDir := $(addprefix -L,$(libDir)) -CFlags += -c $(debug) $(inc) $(libDir) $(libs) -sources := $(shell find $(srcDir) -name '*.$(srcExt)') -srcDirs := $(shell find . -name '*.$(srcExt)' -exec dirname {} \; | uniq) -objects := $(patsubst %.$(srcExt),$(objDir)/%.o,$(sources)) - -ifeq ($(srcExt),cpp) - CC = $(CXX) -else - CFlags += -std=gnu99 -endif - -.phony: all clean cleanbin - -all: $(binDir)/$(app) - -$(binDir)/$(app): COM_STRING = "Linking" -$(binDir)/$(app): buildrepo $(objects) - @mkdir -p `dirname $@` - @$(call run_and_test, $(CC) $(objects) $(LDFlags) -o $@) - -$(objDir)/%.o: COM_STRING = "Compiling" -$(objDir)/%.o: %.$(srcExt) - @$(call make-depend,$<,$@,$(subst .o,.d,$@)) - @$(call run_and_test, $(CC) $(CFlags) $< -o $@) - -clean: - $(RM) -r $(objDir) - -cleanbin: clean - $(RM) -r $(binDir)/$(app) - -buildrepo: - @$(call make-repo) - -define make-repo - for dir in $(srcDirs); \ - do \ - mkdir -p $(objDir)/$$dir; \ - done -endef - -# usage: $(call make-depend,source-file,object-file,depend-file) -define make-depend - $(CC) -MM \ - -MF $3 \ - -MP \ - -MT $2 \ - $(CFlags) \ - $1 -endef \ No newline at end of file diff --git a/bin/opt.cpp b/bin/opt.cpp new file mode 100644 index 0000000..e69a081 --- /dev/null +++ b/bin/opt.cpp @@ -0,0 +1,92 @@ +#include +using std::random_device; + +#include +using std::ofstream; + +#include + +#include +using std::cout; +using std::endl; + +#include +//chrono + +#include +using std::vector; + +#include +using std::invalid_argument; + +#include +using std::stof; +using std::stoi; + +#include "Globals.hpp" +#include "Population.hpp" +#include "GAUtils.hpp" +#include "Log.hpp" +#include "Arg.hpp" +#include "ImportData.hpp" +#include "Opt.hpp" + +#include "Constants.hpp" + + +void initArgs(int, char *[]); + +int main(int argc, char *argv[]) { + random_device rng; + Globals::urng.seed(rng()); + + initArgs(argc,argv); + + // GA(); + ImportData dataFile(Config::LIB_PATH+Config::NAME); + Globals::map.setCityList(dataFile.getCitiesCoord()); + Config::TYPE = Config::type::GEO; + + // cout << "scanning" << endl; + std::string line; + std::vector tour; + + std::getline(std::cin, line); + std::istringstream iss(line); + int tmp; + + // cout << "pushing" << endl; + while (iss >> tmp) { + tour.push_back(tmp); + } + std::vector res; + // cout << "optimizing" << endl; + Opt::optimize(tour); + for (auto i : tour) + cout << i << " "; + cout << std::endl; + + return 0; +} + +void initArgs(int argc, char *argv[]){ + string NAME = "name|n"; + string LIB = "lib|l"; + Arg arg(argc,argv); + arg.setProgramName("GPX2"); + arg.setHelp(); + + arg.newArgument(NAME,true,"name of the tour."); + arg.newArgument(LIB,false,"path to the .tsp file."); + + try{ + arg.validateArguments(); + }catch(std::runtime_error &e){ + std::cout< Date: Fri, 2 Jan 2026 02:01:23 +0100 Subject: [PATCH 05/10] add traditional makefile MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomáš Macholda --- Makefile | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 Makefile diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..b6db6e9 --- /dev/null +++ b/Makefile @@ -0,0 +1,55 @@ +HFILES=\ + include/AntColony.hpp \ + include/Ant.hpp \ + include/Arg.hpp \ + include/City.hpp \ + include/Constants.hpp \ + include/Coordinates.hpp \ + include/GAUtils.hpp \ + include/Globals.hpp \ + include/GPX2Fusion.hpp \ + include/GPX2.hpp \ + include/GPX2Structs.hpp \ + include/GPX2Support.hpp \ + include/ImportData.hpp \ + include/Log.hpp \ + include/Node.hpp \ + include/Opt.hpp \ + include/OX.hpp \ + include/Partition.hpp \ + include/Population.hpp \ + include/Utils.hpp +OFILES=src/opt/Opt.o \ + src/cross/gpx/Partition.o \ + src/cross/gpx/Node.o \ + src/cross/gpx/GPX2Support.o \ + src/cross/gpx/GPX2Fusion.o \ + src/cross/gpx/GPX2.o \ + src/cross/OX/OX.o \ + src/base/Utils.o \ + src/base/Population.o \ + src/base/Log.o \ + src/base/ImportData.o \ + src/base/Globals.o \ + src/base/GAUtils.o \ + src/base/Coordinates.o \ + src/base/City.o \ + src/args/Arg.o + +CXX=g++ +LD=g++ +CFLAGS=-Iinclude -Wall -O3 -g +O=o + +.phony: all clean +all: bin/opt bin/gpx2 + +clean: + @find | grep '\.o$$' | xargs rm -f + @rm -f bin/opt bin/gpx2 + +%.$O: %.cpp + $(CXX) $(CFLAGS) $(<) -c -o $(@) + +bin/%: $(OFILES) bin/%.o + $(CXX) $(CFLAGS) $^ -o $@ From 61c1950aaf900a261490650ac0a73b625d73b8b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=A1clav=20Ku=C4=8Dina?= Date: Fri, 2 Jan 2026 15:40:42 +0100 Subject: [PATCH 06/10] Add 2opt.py --- 2opt.py | 23 +++++++++++++++++++++++ Makefile | 2 +- bin/opt.cpp | 1 - 3 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 2opt.py diff --git a/2opt.py b/2opt.py new file mode 100644 index 0000000..d047391 --- /dev/null +++ b/2opt.py @@ -0,0 +1,23 @@ +import subprocess + +def opt2(tour, problem): + tour = " ".join(map(lambda x: str(x+1), tour)) + #print(tour) + + result = subprocess.run( + [ + "bin/opt", + "-l tsp/", + "-n " + problem + ], + input=tour, + capture_output=True, + text=True + ) + + tour = list(map(lambda x: int(x)-1, result.stdout.split())) + return tour + +tour = [13, 48, 30, 5, 9, 12, 50, 6, 22, 49, 36, 15, 43, 45, 31, 20, 24, 25, 0, 39, 3, 8, 46, 18, 21, 32, 10, 2, 33, 40, 34, 44, 17, 1, 37, 42, 19, 28, 47, 16, 7, 4, 27, 11, 29, 35, 38, 14, 51, 23, 41, 26] +tour = opt2(tour, "berlin52") +print(tour) \ No newline at end of file diff --git a/Makefile b/Makefile index b6db6e9..9044bdc 100644 --- a/Makefile +++ b/Makefile @@ -38,7 +38,7 @@ OFILES=src/opt/Opt.o \ CXX=g++ LD=g++ -CFLAGS=-Iinclude -Wall -O3 -g +CFLAGS=-Iinclude -Wall -O3 O=o .phony: all clean diff --git a/bin/opt.cpp b/bin/opt.cpp index e69a081..e6d9c3c 100644 --- a/bin/opt.cpp +++ b/bin/opt.cpp @@ -45,7 +45,6 @@ int main(int argc, char *argv[]) { // GA(); ImportData dataFile(Config::LIB_PATH+Config::NAME); Globals::map.setCityList(dataFile.getCitiesCoord()); - Config::TYPE = Config::type::GEO; // cout << "scanning" << endl; std::string line; From 57ab33bc368ce595d6a2651136f641866826e661 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Macholda?= Date: Fri, 2 Jan 2026 16:08:32 +0100 Subject: [PATCH 07/10] add gpx2.cpp MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomáš Macholda --- Makefile | 2 +- bin/gpx2.cpp | 137 +++++++++++++-------------------------------------- 2 files changed, 35 insertions(+), 104 deletions(-) diff --git a/Makefile b/Makefile index 9044bdc..952a02f 100644 --- a/Makefile +++ b/Makefile @@ -38,7 +38,7 @@ OFILES=src/opt/Opt.o \ CXX=g++ LD=g++ -CFLAGS=-Iinclude -Wall -O3 +CFLAGS=-Iinclude -Wall -O3 -g O=o .phony: all clean diff --git a/bin/gpx2.cpp b/bin/gpx2.cpp index ba44422..9faa0dc 100644 --- a/bin/gpx2.cpp +++ b/bin/gpx2.cpp @@ -30,6 +30,7 @@ using std::stoi; #include "Arg.hpp" #include "ImportData.hpp" #include "Opt.hpp" +#include "GPX2.hpp" #include "Constants.hpp" @@ -58,117 +59,62 @@ int main(int argc, char *argv[]) { initArgs(argc,argv); - // GA(); ImportData dataFile(Config::LIB_PATH+Config::NAME); Globals::map.setCityList(dataFile.getCitiesCoord()); - Config::TYPE = Config::type::GEO; - cout << "scanning" << endl; + // cout << "scanning" << endl; std::string line; - std::vector tour; + std::vector tour1; + std::vector tour2; + int tmp; std::getline(std::cin, line); - std::istringstream iss(line); - int tmp; + std::istringstream iss1(line); + std::getline(std::cin, line); + std::istringstream iss2(line); - cout << "pushing" << endl; - while (iss >> tmp) { - tour.push_back(tmp); + // cout << "pushing" << endl; + while (iss1 >> tmp) { + tour1.push_back(tmp); } - std::vector res; - cout << "optimizing" << endl; - Opt::optimize(tour); - for (auto i : tour) + while (iss2 >> tmp) { + tour2.push_back(tmp); + } + // cout << "optimizing" << endl; + std::vector res = GPX2::crossover(tour1, tour2); + for (auto i : res) cout << i << " "; + cout << std::endl; return 0; } -void GA() { - Population pop; - bool foundBestWithoutGA = true; - - ofstream *logFile{Log::initLogFile()}; - - Log::printHeader(*logFile); - - auto start = std::chrono::high_resolution_clock::now(); - - GAUtils::init(pop); - // AntMap::initMap(); - // AntMap::updatePheromoneMap(pop.getBestTour()); - - // cout<<"tour size "< (finishInitPop - start).count()); - - auto startGA = std::chrono::high_resolution_clock::now(); - - int i{0}, firstBestFitness{pop.bestFitness()}; - *logFile << "\nFirst fitness " << firstBestFitness << endl; - while(GAUtils::stop(pop,*logFile)){ - foundBestWithoutGA = false; - i++; - pop = GAUtils::generateNewPopulation(pop); - // AntMap::printPheromoneMap(); - *logFile << "gen " << i << " best fitness " << pop.bestFitness() << endl; - - } - - if(foundBestWithoutGA){ - *logFile << "Found best without GA" << endl; - cout << "Found best without GA" << endl; - } - - auto finishGA = std::chrono::high_resolution_clock::now(); - Log::printTime(*logFile,"GA execution time:", - std::chrono::duration (finishGA - startGA).count()); - - auto finish = std::chrono::high_resolution_clock::now(); - Log::printTime(*logFile,"Total execution time:", - std::chrono::duration (finish - start).count()); - - Log::printFooter(*logFile,pop,i,firstBestFitness); - - (*logFile).close(); - delete logFile; - // AntMap::deleteMap(); -} - void initArgs(int argc, char *argv[]){ string NAME = "name|n"; - string SIZE = "size|s"; + // string SIZE = "size|s"; string LIB = "lib|l"; - string ID = "id"; - string LK = "lk"; - string NEW_POP = "newpop|np"; - string N_BEST = "nbest|nb"; - string BEST_FITNESS = "bestfitness|bf"; - string RESET = "reset|r"; - string GEN_NEW_TOUR = "newtour|nt"; + // string ID = "id"; + // string LK = "lk"; + // string NEW_POP = "newpop|np"; + // string N_BEST = "nbest|nb"; + // string BEST_FITNESS = "bestfitness|bf"; + // string RESET = "reset|r"; + // string GEN_NEW_TOUR = "newtour|nt"; Arg arg(argc,argv); arg.setProgramName("GPX2"); arg.setHelp(); arg.newArgument(NAME,true,"name of the tour."); - arg.newArgument(SIZE,true,"size of the pop."); + // arg.newArgument(SIZE,true,"size of the pop."); arg.newArgument(LIB,false,"path to the .tsp file."); - arg.newArgument(ID,false,"numeric id of the run."); - arg.newArgument(LK,false,"percentage of population to be generated using linkern."); - arg.newArgument(NEW_POP,false,"method to be used to generate the next generation."); - arg.newArgument(N_BEST,false,"number of tours to be saved to the next generation."); - arg.newArgument(BEST_FITNESS,false,"best fitness found to this tour."); - arg.newArgument(RESET,false,"percentage of the population to reset each generation"); - arg.newArgument(GEN_NEW_TOUR,false,"mode to generate new tour, used to generate first population and reset"); + // arg.newArgument(ID,false,"numeric id of the run."); + // arg.newArgument(LK,false,"percentage of population to be generated using linkern."); + // arg.newArgument(NEW_POP,false,"method to be used to generate the next generation."); + // arg.newArgument(N_BEST,false,"number of tours to be saved to the next generation."); + // arg.newArgument(BEST_FITNESS,false,"best fitness found to this tour."); + // arg.newArgument(RESET,false,"percentage of the population to reset each generation"); + // arg.newArgument(GEN_NEW_TOUR,false,"mode to generate new tour, used to generate first population and reset"); try{ arg.validateArguments(); @@ -179,21 +125,6 @@ void initArgs(int argc, char *argv[]){ Config::NAME = arg.getOption(NAME); - Config::POP_SIZE = stoi(arg.getOption(SIZE)); string tmp = arg.getOption(LIB); Config::LIB_PATH = tmp.empty()?Config::LIB_PATH:tmp; - tmp = arg.getOption(ID); - Config::ID = tmp.empty()?Config::ID:stoi(tmp); - tmp = arg.getOption(LK); - Config::LK_PERCENTAGE = tmp.empty()?Config::LK_PERCENTAGE:stod(tmp); - tmp = arg.getOption(NEW_POP); - Config::NEW_POP_TYPE = tmp.empty()?Config::NEW_POP_TYPE:stoi(tmp); - tmp = arg.getOption(N_BEST); - Config::N_BEST = tmp.empty()?Config::N_BEST:stoi(tmp); - tmp = arg.getOption(BEST_FITNESS); - Config::BEST_FITNESS = tmp.empty()?Config::BEST_FITNESS:stoi(tmp); - tmp = arg.getOption(RESET); - Config::RESET_PERCENTAGE = tmp.empty()?Config::RESET_PERCENTAGE:stod(tmp); - tmp = arg.getOption(GEN_NEW_TOUR); - Config::NEW_TOUR_MODE = tmp.empty()?Config::NEW_TOUR_MODE:stod(tmp); } From 0e3f070f927bb43530d27a002b41226a75f1ad5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Macholda?= Date: Fri, 2 Jan 2026 18:29:06 +0100 Subject: [PATCH 08/10] more cflags section gc --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 952a02f..d415ab5 100644 --- a/Makefile +++ b/Makefile @@ -38,7 +38,7 @@ OFILES=src/opt/Opt.o \ CXX=g++ LD=g++ -CFLAGS=-Iinclude -Wall -O3 -g +CFLAGS=-Iinclude -Wall -O3 -fdata-sections -ffunction-sections -Wl,--gc-sections O=o .phony: all clean @@ -51,5 +51,5 @@ clean: %.$O: %.cpp $(CXX) $(CFLAGS) $(<) -c -o $(@) -bin/%: $(OFILES) bin/%.o +bin/%: $(OFILES) bin/%.$(O) $(CXX) $(CFLAGS) $^ -o $@ From bd456cdd2031f9b8577ce5ea7aad17a6332912bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Macholda?= Date: Fri, 2 Jan 2026 18:31:06 +0100 Subject: [PATCH 09/10] remove tour logging in .txt files --- src/cross/gpx/GPX2.cpp | 11 ++--------- src/cross/gpx/GPX2Support.cpp | 27 --------------------------- 2 files changed, 2 insertions(+), 36 deletions(-) diff --git a/src/cross/gpx/GPX2.cpp b/src/cross/gpx/GPX2.cpp index 4d01876..4a626bd 100644 --- a/src/cross/gpx/GPX2.cpp +++ b/src/cross/gpx/GPX2.cpp @@ -62,14 +62,7 @@ vector GPX2::crossover(vector redT, vector blueT) // Step 9 - //return obj.convertChoosenChild(); - vector offspring{obj.convertChoosenChild()}; - if(getFitness(redT) > getFitness(offspring) && getFitness(blueT) > getFitness(offspring) ){ - Log::printTourFile(redT,"red"); - Log::printTourFile(blueT,"blue"); - Log::printTourFile(offspring,"off"); - } - return offspring; + return obj.convertChoosenChild(); } // ----------------------------------------------------------------------------- @@ -336,4 +329,4 @@ GPX2::~GPX2() GPX2Support::deletePartitionMap(unfeasiblePartitions); partitionsChoosen.clear(); feasiblePartitions.clear(); -} \ No newline at end of file +} diff --git a/src/cross/gpx/GPX2Support.cpp b/src/cross/gpx/GPX2Support.cpp index 48ef61a..187f7e1 100644 --- a/src/cross/gpx/GPX2Support.cpp +++ b/src/cross/gpx/GPX2Support.cpp @@ -579,30 +579,3 @@ int GPX2Support::whichPartition(const string id, GPX2Structs::PartitionMap parti } return (-1); } - - - - - - - - - - - - - - - - - - - - - - - - - - - From 9ffb2595349994e0f8cbe1a34862317051f68d0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Macholda?= Date: Mon, 9 Feb 2026 17:55:35 +0100 Subject: [PATCH 10/10] README: disclaimer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomáš Macholda --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index dea1397..3d88a13 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,7 @@ +## Disclaimer + +This README is vastly out of date. You'll need to RTFS + # GPX2 (Generalized Partition Crossover 2) for solving the TSP (Travelling Salesperson Problem) Repository for the development and testing of the Generalized Partition Crossover 2 (GPX2) algorithm.