int main(int argc, char* argv[]) { output = fopen("final", "wb"); argc--; path = malloc(MAX_PATH * sizeof(char)); isMaster = 1; //only works with number of files that are a power of two! if(!isPowerOfTwo(argc)) { printf("# of args(%i) not power of 2\n", argc); return 0; } filenames = malloc(sizeof(char*) * argc); //stores files into global array for(int i = 0; i < argc; i++) { filenames[i] = argv[i + 1]; } //number of levels in the tree, discluding the master node max_levels = (int)(log(argc) / log(2)); spawnChildren(max_levels); free(filenames); fclose(output); sleep(1); return 0; }
/* Recursively spawns 2 children per parent * Determines who is whom(master, parents, children) */ void spawnChildren(int levels) { //no more levels underneath you means you are a leaf process if(levels == 0) { readSort(); return; } int len = strlen(path); if(isMaster) pipe(fd[UP]); pipe(fd[LEFT]); pipe(fd[RIGHT]); //spawns 2 children at a single parent, prevents child //having another child within the fork'd process int pid = fork(); //parent if(pid > 0) { int pid2 = fork(); //child if(pid2 == 0) { if(!isMaster) { if(levels-1) printf("Parent(%d) spawned process(%d).\n", getppid(), getpid()); else printf("Parent(%d) spawned leaf process(%d).\n", getppid(), getpid()); } else printf("Master(%d) spawned process(%d).\n", getppid(), getpid()); isMaster = 0; dup2(fd[RIGHT][WRITE], fd[UP][WRITE]); close(fd[LEFT][WRITE]); close(fd[RIGHT][WRITE]); //record path path[len] = '1'; path[len+1] = '\0'; spawnChildren(levels-1); return; } } //child else { if(!isMaster) { if(levels-1) printf("Parent(%d) spawned process(%d).\n", getppid(), getpid()); else printf("Parent(%d) spawned leaf process(%d).\n", getppid(), getpid()); } else printf("Master(%d) spawned process(%d).\n", getppid(), getpid()); isMaster = 0; dup2(fd[LEFT][WRITE], fd[UP][WRITE]); close(fd[RIGHT][WRITE]); close(fd[LEFT][WRITE]); //record path path[len] = '0'; path[len+1] = '\0'; spawnChildren(levels-1); return; } //parent or master if(levels > 0) { if(isMaster) close(fd[UP][WRITE]); close(fd[UP][READ]); close(fd[LEFT][WRITE]); close(fd[RIGHT][WRITE]); //numbers to be compared int num[2]; //status of reading from buffer int status[2]; //which side is finished int finished[2]; //initial values status[LEFT] = read(fd[LEFT][READ], &num[LEFT], sizeof(int)); if(status[LEFT] != sizeof(int)) finished[LEFT] = 1; else finished[LEFT] = 0; status[RIGHT] = read(fd[RIGHT][READ], &num[RIGHT], sizeof(int)); if(status[RIGHT] != sizeof(int)) finished[RIGHT] = 1; else finished[RIGHT] = 0; while(finished[LEFT] == 0 || finished[RIGHT] == 0) { if(!finished[LEFT] && (num[LEFT] < num[RIGHT] || finished[RIGHT])) { //if not at top keep sending up if(!isMaster) write(fd[UP][WRITE], &num[LEFT], sizeof(int)); //otherwise you're the master and write to file else fprintf(output, "%u\n", num[LEFT]); status[LEFT] = read(fd[LEFT][READ], &num[LEFT], sizeof(int)); //no more bytes to read if(status[LEFT] != sizeof(int)) { close(fd[LEFT][READ]); finished[LEFT] = 1; } } else if(!finished[RIGHT] && (num[RIGHT] <= num[LEFT] || finished[LEFT])) { //if not at top keep sending up if(!isMaster) write(fd[UP][WRITE], &num[RIGHT], sizeof(int)); //otherwise you're the master and write to file else fprintf(output, "%u\n", num[RIGHT]); status[RIGHT] = read(fd[RIGHT][READ], &num[RIGHT], sizeof(int)); //no more bytes to read if(status[RIGHT] != sizeof(int)) { close(fd[RIGHT][READ]); finished[RIGHT] = 1; } } } close(fd[UP][WRITE]); if(isMaster) printf("Wrote sorted file to 'final'.\n"); } }
bool NaiveAlgorithm::tick() { cpFloat bestFitness = -INFINITY; // we want zero fitness cpFloat worstFitness = INFINITY; cpFloat lastBestFitness = bestIndividual ? bestIndividual->fitness : bestFitness; std::vector<SystemInfo *>nextGen = spawnChildren(); // add old population for (size_t popIter = 0; popIter <population.size(); popIter++) { // reset the individual... by copying! SystemInfo *individual = population[popIter]; MachineSystem *original = individual->system; MachineSystem *copy = new MachineSystem(*original); individual->system = copy; delete original; nextGen.push_back(individual); } for (size_t popIter = 0; popIter <nextGen.size(); popIter++) { SystemInfo *individual = nextGen[popIter]; stepSystem(individual); individual->fitness = evaluateSystem(individual); } // cut the population back down to size std::sort(nextGen.begin(), nextGen.end(), isMoreFit); bestIndividual = nextGen.front(); bestFitness = bestIndividual->fitness; worstFitness = nextGen.back()->fitness; std::vector<SystemInfo *>::iterator deleteIt = nextGen.begin()+population.size(); while (deleteIt != nextGen.end()) { SystemInfo *unfit = *deleteIt; assert(unfit != bestIndividual); delete unfit; deleteIt = nextGen.erase(deleteIt); } if (bestFitness > allTimeBestFitness) allTimeBestFitness = bestFitness; assert(nextGen.size() == population.size()); population = nextGen; fprintf(stderr, "BEST FITNESS: %f \n", bestFitness); fprintf(stderr, "WORST FITNESS: %f \n", worstFitness); if (lastBestFitness == bestFitness) stagnantGenerations++; else stagnantGenerations = 0; bool stop = (generations >= maxGenerations) || goodEnoughFitness(bestFitness) || (stagnantGenerations >= maxStagnation); generations++; logPopulationStatistics(); if (stop) { fprintf(stderr, "ALL TIME BEST FITNESS: %f\n", allTimeBestFitness); } return stop; }