#ifndef SIMULATED_ANNEALING_HEADER_12647_H #define SIMULATED_ANNEALING_HEADER_12647_H #define SIMULATED_ANNEALING_DISABLE_SHOWCRATES 1 #define SIMULATED_ANNEALING_DISABLE_SHOWITRNUM 2 #include #include #include #include #include #include namespace sa { class solution { std::vector items; std::default_random_engine gen; int capacity; int fitness; int iterations; int iteration; auto calculate_boxes()->int { int count = 1; long long now = 0; for (auto i : items) { if (now + i > capacity) { count++; now = i; continue; } now += i; } return count; } static void print_box(int box, std::queue &stored) { std::cout << "Caixa " << box << ":"; while (!stored.empty()) { std::cout << ' ' << stored.front(); stored.pop(); } std::cout << '\n'; } public: solution() = default; solution(const solution &other, int itr): items(other.items), gen(other.gen), capacity(other.capacity), fitness(other.fitness), iteration(itr) {} solution(const std::vector &items, int capacity): // Gera a solução inicial gen(std::random_device()()), capacity(capacity), iteration(0) { std::multiset its; for (auto i : items) { its.insert(i); } this->items.resize(items.size()); size_t i = 0; long long cap = capacity; while (!its.empty()) { auto itr = its.upper_bound(cap); if (itr == its.begin()) { cap = capacity; cap -= *its.begin(); itr = its.begin(); } else { itr--; cap -= *itr; } this->items[i] = *itr; its.erase(itr); i++; } fitness = calculate_boxes(); } void setneighbor() { // Gera um vizinho da solução std::uniform_int_distribution<> dist(0, items.size() - 1); int first = dist(gen); int second = 0; while ((second = dist(gen)) == first) {} std::swap(items[first], items[second]); fitness = calculate_boxes(); } void randomize() { std::shuffle(items.begin(), items.end(), gen); fitness = calculate_boxes(); } void swap(solution &other) { std::swap(fitness, other.fitness); std::swap(items, other.items); std::swap(capacity, other.capacity); std::swap(gen, other.gen); std::swap(iteration, other.iteration); } void print_sol(char flags = 0) const { if(!(flags & SIMULATED_ANNEALING_DISABLE_SHOWITRNUM)){ std::cout << "Iteração da solução: " << iteration << '\n'; std::cout << "Número de iterações calculadas: " << iterations << '\n'; } std::cout << "Número de caixas: " << fitness << '\n'; if(!(flags & SIMULATED_ANNEALING_DISABLE_SHOWCRATES)){ int box_now = 1; long long now = 0; std::queue items_stored; for (auto i : items) { if (now + i > capacity) { print_box(box_now, items_stored); box_now++; now = i; } else { now += i; } items_stored.push(i); } print_box(box_now, items_stored); std::cout << '\n'; } } void setiterations(int itr) { iterations = itr; } static auto simulated_annealing(int capacity, const std::vector &items, double alpha, double temp, double temp_min)->solution; }; } // namespace sa #endif