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/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 fbb740f..d415ab5 100644 --- a/Makefile +++ b/Makefile @@ -1,105 +1,55 @@ -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 $@) +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 -fdata-sections -ffunction-sections -Wl,--gc-sections +O=o + +.phony: all clean +all: bin/opt bin/gpx2 clean: - $(RM) -r $(objDir) - -cleanbin: clean - $(RM) -r $(binDir)/$(app) - -buildrepo: - @$(call make-repo) + @find | grep '\.o$$' | xargs rm -f + @rm -f bin/opt bin/gpx2 -define make-repo - for dir in $(srcDirs); \ - do \ - mkdir -p $(objDir)/$$dir; \ - done -endef +%.$O: %.cpp + $(CXX) $(CFLAGS) $(<) -c -o $(@) -# 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 +bin/%: $(OFILES) bin/%.$(O) + $(CXX) $(CFLAGS) $^ -o $@ 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. diff --git a/bin/gpx2.cpp b/bin/gpx2.cpp new file mode 100644 index 0000000..9faa0dc --- /dev/null +++ b/bin/gpx2.cpp @@ -0,0 +1,130 @@ +#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 "GPX2.hpp" + +#include "Constants.hpp" + +//begin the genetic algorithm +void GA(); + +//set arguments +void initArgs(int, char *[]); + +//1 -name argumento tour_name REQUIRED +//2 -lib caminho para o .tsp +//3 -size tamanho da pop REQUIRED +//4 -id ID da run(usado para log +//5 -lk porcentagem de população inicial gerado pelo LK +//6 -newpop tipo de geração da nova poop +//7 -nbest n best para serem salvos para a proxima geração +//8 -bestfitness best fitness conhecida +// ex: GA -n berlin52 -l lib/ -s 100 -id 3 -lk 0.1 -np 1 -nb 4 -bf 255 +// ex: GA -name berlin52 -size 100 + +#include "OX.hpp" + +int main(int argc, char *argv[]) { + random_device rng; + Globals::urng.seed(rng()); + + initArgs(argc,argv); + + ImportData dataFile(Config::LIB_PATH+Config::NAME); + Globals::map.setCityList(dataFile.getCitiesCoord()); + + // cout << "scanning" << endl; + std::string line; + std::vector tour1; + std::vector tour2; + int tmp; + + std::getline(std::cin, line); + std::istringstream iss1(line); + std::getline(std::cin, line); + std::istringstream iss2(line); + + // cout << "pushing" << endl; + while (iss1 >> tmp) { + tour1.push_back(tmp); + } + 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 initArgs(int argc, char *argv[]){ + string NAME = "name|n"; + // 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"; + + 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(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"); + + try{ + arg.validateArguments(); + }catch(std::runtime_error &e){ + std::cout< +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()); + + // 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< &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/cross/gpx/includes/GPX2.hpp b/include/GPX2.hpp similarity index 100% rename from src/cross/gpx/includes/GPX2.hpp rename to include/GPX2.hpp diff --git a/src/cross/gpx/includes/GPX2Fusion.hpp b/include/GPX2Fusion.hpp similarity index 100% rename from src/cross/gpx/includes/GPX2Fusion.hpp rename to include/GPX2Fusion.hpp diff --git a/src/cross/gpx/includes/GPX2Structs.hpp b/include/GPX2Structs.hpp similarity index 100% rename from src/cross/gpx/includes/GPX2Structs.hpp rename to include/GPX2Structs.hpp diff --git a/src/cross/gpx/includes/GPX2Support.hpp b/include/GPX2Support.hpp similarity index 100% rename from src/cross/gpx/includes/GPX2Support.hpp rename to include/GPX2Support.hpp diff --git a/src/base/includes/Globals.hpp b/include/Globals.hpp similarity index 100% rename from src/base/includes/Globals.hpp rename to include/Globals.hpp diff --git a/src/base/includes/ImportData.hpp b/include/ImportData.hpp similarity index 100% rename from src/base/includes/ImportData.hpp rename to include/ImportData.hpp diff --git a/src/base/includes/Log.hpp b/include/Log.hpp similarity index 100% rename from src/base/includes/Log.hpp rename to include/Log.hpp diff --git a/src/cross/gpx/includes/Node.hpp b/include/Node.hpp similarity index 100% rename from src/cross/gpx/includes/Node.hpp rename to include/Node.hpp diff --git a/src/cross/OX/OX.hpp b/include/OX.hpp similarity index 100% rename from src/cross/OX/OX.hpp rename to include/OX.hpp diff --git a/src/opt/Opt.hpp b/include/Opt.hpp similarity index 100% rename from src/opt/Opt.hpp rename to include/Opt.hpp diff --git a/src/cross/gpx/includes/Partition.hpp b/include/Partition.hpp similarity index 100% rename from src/cross/gpx/includes/Partition.hpp rename to include/Partition.hpp diff --git a/src/base/includes/Population.hpp b/include/Population.hpp similarity index 100% rename from src/base/includes/Population.hpp rename to include/Population.hpp diff --git a/src/base/includes/Utils.hpp b/include/Utils.hpp similarity index 100% rename from src/base/includes/Utils.hpp rename to include/Utils.hpp diff --git a/mkfile b/mkfile new file mode 100644 index 0000000..8c164b1 --- /dev/null +++ b/mkfile @@ -0,0 +1,54 @@ +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 + +all:V: bin/opt bin/gpx2 + +clean:V: + find | grep '\.o$' | xargs rm -f + rm -f bin/opt bin/gpx2 + +%.$O: %.cpp + $CXX $CFLAGS $prereq -c -o $target + +bin/%: $OFILES bin/%.o + $CXX $CFLAGS $prereq -o $target diff --git a/src/base/sources/City.cpp b/src/base/City.cpp similarity index 100% rename from src/base/sources/City.cpp rename to src/base/City.cpp diff --git a/src/base/sources/Coordinates.cpp b/src/base/Coordinates.cpp similarity index 100% rename from src/base/sources/Coordinates.cpp rename to src/base/Coordinates.cpp diff --git a/src/base/sources/GAUtils.cpp b/src/base/GAUtils.cpp similarity index 74% rename from src/base/sources/GAUtils.cpp rename to src/base/GAUtils.cpp index 8d3e9bd..40a11fe 100644 --- a/src/base/sources/GAUtils.cpp +++ b/src/base/GAUtils.cpp @@ -15,7 +15,6 @@ using std::uniform_int_distribution; #include "GPX2.hpp" #include "ImportData.hpp" -#include "AntColony.hpp" #include "Constants.hpp" #include @@ -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: "< 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); +} diff --git a/src/base/sources/Globals.cpp b/src/base/Globals.cpp similarity index 100% rename from src/base/sources/Globals.cpp rename to src/base/Globals.cpp diff --git a/src/base/sources/ImportData.cpp b/src/base/ImportData.cpp similarity index 100% rename from src/base/sources/ImportData.cpp rename to src/base/ImportData.cpp diff --git a/src/base/sources/Log.cpp b/src/base/Log.cpp similarity index 100% rename from src/base/sources/Log.cpp rename to src/base/Log.cpp diff --git a/src/base/sources/Population.cpp b/src/base/Population.cpp similarity index 100% rename from src/base/sources/Population.cpp rename to src/base/Population.cpp diff --git a/src/base/sources/Utils.cpp b/src/base/Utils.cpp similarity index 100% rename from src/base/sources/Utils.cpp rename to src/base/Utils.cpp diff --git a/src/cross/AntColony/Ant.cpp b/src/cross/AntColony/Ant.cpp deleted file mode 100644 index 92474de..0000000 --- a/src/cross/AntColony/Ant.cpp +++ /dev/null @@ -1,93 +0,0 @@ -#include "Ant.hpp" - -#include "Globals.hpp" - -#include "Constants.hpp" - -#include "Utils.hpp" - -#include -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< 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/sources/GPX2Fusion.cpp b/src/cross/gpx/GPX2Fusion.cpp similarity index 98% rename from src/cross/gpx/sources/GPX2Fusion.cpp rename to src/cross/gpx/GPX2Fusion.cpp index c013e85..60f1f4a 100644 --- a/src/cross/gpx/sources/GPX2Fusion.cpp +++ b/src/cross/gpx/GPX2Fusion.cpp @@ -1,5 +1,6 @@ #include "GPX2Fusion.hpp" #include "GPX2Support.hpp" +#include "Partition.hpp" #include using std::find; @@ -106,7 +107,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 +304,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/GPX2Support.cpp similarity index 99% rename from src/cross/gpx/sources/GPX2Support.cpp rename to src/cross/gpx/GPX2Support.cpp index 37f45ae..187f7e1 100644 --- a/src/cross/gpx/sources/GPX2Support.cpp +++ b/src/cross/gpx/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()); } @@ -581,30 +579,3 @@ int GPX2Support::whichPartition(const string id, GPX2Structs::PartitionMap parti } return (-1); } - - - - - - - - - - - - - - - - - - - - - - - - - - - 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/main.cpp b/src/main.cpp deleted file mode 100644 index 145d5bf..0000000 --- a/src/main.cpp +++ /dev/null @@ -1,202 +0,0 @@ -#include -using std::random_device; - -#include -using std::ofstream; - -#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 "Constants.hpp" - -//begin the genetic algorithm -void GA(); - -//set arguments -void initArgs(int, char *[]); - -//1 -name argumento tour_name REQUIRED -//2 -lib caminho para o .tsp -//3 -size tamanho da pop REQUIRED -//4 -id ID da run(usado para log -//5 -lk porcentagem de população inicial gerado pelo LK -//6 -newpop tipo de geração da nova poop -//7 -nbest n best para serem salvos para a proxima geração -//8 -bestfitness best fitness conhecida -// ex: GA -n berlin52 -l lib/ -s 100 -id 3 -lk 0.1 -np 1 -nb 4 -bf 255 -// ex: GA -name berlin52 -size 100 - -#include "OX.hpp" - -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?"< (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 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"; - - 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(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"); - - try{ - arg.validateArguments(); - }catch(std::runtime_error &e){ - std::cout< &t){ }else{ return(false); } -} \ No newline at end of file +}