-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path3_openMP.cpp
More file actions
161 lines (135 loc) · 5.09 KB
/
3_openMP.cpp
File metadata and controls
161 lines (135 loc) · 5.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#include <iostream>
#include <fstream>
#include <unordered_map>
#include <vector>
#include <algorithm>
#include <chrono>
#include <limits>
#include <omp.h>
using namespace std;
using namespace std::chrono;
// Função para gerar permutações
void generate_permutations(vector<int>& nodes, vector<vector<int>>& permutations) {
sort(nodes.begin(), nodes.end()); // Ordena os nós para garantir todas as permutações
do {
// Adiciona 0 no início e no fim de cada permutação
vector<int> perm = {0};
perm.insert(perm.end(), nodes.begin(), nodes.end());
perm.push_back(0);
permutations.push_back(perm);
} while (next_permutation(nodes.begin(), nodes.end()));
}
// Função para ajustar permutações com base nas restrições
void adjust_permutations(vector<vector<int>>& permutations, const vector<vector<int>>& adj_matrix, const unordered_map<int, int>& demands, int vehicle_capacity, int num_stops) {
#pragma omp parallel for
for (size_t perm_index = 0; perm_index < permutations.size(); ++perm_index) {
auto& perm = permutations[perm_index];
int current_capacity = 0;
int stops = 0;
for (auto it = perm.begin() + 1; it != perm.end() - 1; ++it) {
int from = *(it - 1);
int to = *it;
// Verifica se não há caminho entre dois nós consecutivos
if (adj_matrix[from][to] == -1) {
it = perm.insert(it, 0);
current_capacity = 0; // Reinicia a capacidade após retorno ao depósito
stops = 0; // Reinicia o contador de paradas
continue;
}
// Verifica se a capacidade do veículo é excedida
if (demands.find(to) != demands.end()) {
current_capacity += demands.at(to);
stops++; // Incrementa o contador de paradas
}
if (current_capacity > vehicle_capacity || stops > num_stops) {
if (*(it - 1) != 0) { // Evita inserções repetidas de retornos ao depósito
it = perm.insert(it, 0);
current_capacity = demands.at(to); // Reinicia a capacidade com a demanda do nó atual
stops = 1; // Reinicia o contador de paradas com a parada atual
}
}
}
}
}
// Função para encontrar a rota de menor custo
vector<int> find_min_cost_route(const vector<vector<int>>& permutations, const vector<vector<int>>& adj_matrix) {
vector<int> min_cost_route;
int min_cost = numeric_limits<int>::max();
#pragma omp parallel
{
vector<int> local_min_cost_route;
int local_min_cost = numeric_limits<int>::max();
#pragma omp for nowait
for (size_t i = 0; i < permutations.size(); ++i) {
const auto& perm = permutations[i];
int cost = 0;
bool valid_route = true;
for (size_t j = 0; j < perm.size() - 1; ++j) {
int from = perm[j];
int to = perm[j + 1];
if (adj_matrix[from][to] == -1) {
valid_route = false;
break;
}
cost += adj_matrix[from][to];
}
if (valid_route && cost < local_min_cost) {
local_min_cost = cost;
local_min_cost_route = perm;
}
}
#pragma omp critical
{
if (local_min_cost < min_cost) {
min_cost = local_min_cost;
min_cost_route = local_min_cost_route;
}
}
}
cout << "Menor custo encontrado: " << min_cost << endl;
return min_cost_route;
}
int main() {
auto start = high_resolution_clock::now();
ifstream infile("grafo.txt");
if (!infile) {
cerr << "Não foi possível abrir o arquivo grafo.txt" << endl;
return 1;
}
int num_nodes;
infile >> num_nodes;
unordered_map<int, int> demands;
for (int i = 1; i < num_nodes; ++i) {
int node, demand;
infile >> node >> demand;
demands[node] = demand;
}
vector<vector<int>> adj_matrix(num_nodes, vector<int>(num_nodes, -1));
int num_edges;
infile >> num_edges;
for (int i = 0; i < num_edges; ++i) {
int from, to, weight;
infile >> from >> to >> weight;
adj_matrix[from][to] = weight;
}
infile.close();
vector<int> nodes;
for (int i = 1; i < num_nodes; ++i) {
nodes.push_back(i);
}
vector<vector<int>> permutations;
generate_permutations(nodes, permutations);
int vehicle_capacity = 15;
int num_stops = 5;
adjust_permutations(permutations, adj_matrix, demands, vehicle_capacity, num_stops);
vector<int> min_cost_route = find_min_cost_route(permutations, adj_matrix);
cout << "Rota de menor custo: ";
for (int node : min_cost_route) {
cout << node << " ";
}
cout << endl;
auto end = high_resolution_clock::now();
auto duration = duration_cast<milliseconds>(end - start).count();
cout << "Tempo total de execução: " << duration << " ms." << endl;
return 0;
}