void GeneraAleatorio() { srand(time(NULL)); int max_nodos=10, min_nodos=6; int max_aristas=5,min_aristas=1; int min_peso=10,max_peso=50; int V=rand()%(max_nodos-min_nodos+1)+min_nodos; Grafo miGrafo; miGrafo.clear(); miGrafo.resize(V); for(int i=0;i<miGrafo.size();i++){ int num_aristas=rand()%(max_aristas-min_aristas+1)+min_aristas; for(int j=0;j<num_aristas;j++){ bool nodo_ok=false; int nodoDestino=-1; while(!nodo_ok){ int duplicado=0; nodoDestino=rand()%V; for(int k=0;k<miGrafo[i].size();k++){ if(miGrafo[i][k].nodo==nodoDestino){ duplicado=1; break; } } if(duplicado==0 && nodoDestino!=i) nodo_ok=true; } miGrafo[i].push_back( Edge(nodoDestino, rand()%(max_peso-min_peso)+min_peso+1) ); } } for(int i=0;i<miGrafo.size();i++){ printf("%d: ",i); for(int j=0;j<miGrafo[i].size();j++){ printf("(D: %d, P: %d)",miGrafo[i][j].nodo,miGrafo[i][j].peso); } printf("\n"); } getchar(); }
void grasp_primer_criterio(Grafo& G, vector<int>& cidm, bool criterio_greedy, bool criterio_busqueda) { vector<int> mejor_solucion; construir_greedy_random(G, mejor_solucion, criterio_greedy); // Criterio de parada 1: hace tantas iteraciones como nodos en el grafo. for (int i = 0; i < G.size(); i++) { // Construir Solucion Greedy Random vector<int> nueva_solucion; construir_greedy_random(G, nueva_solucion, criterio_greedy); // Hacer busqueda local busqueda_local(G, nueva_solucion, criterio_busqueda); // Actualizar Mejor Solucion if (nueva_solucion.size() < mejor_solucion.size()) { mejor_solucion = nueva_solucion; } } cidm = mejor_solucion; }
void construir_greedy_random_primer_criterio(Grafo& G, vector<int>& solucion) { // Criterio de Restricted Candidate List 1: los nodos que cumplan la condicion // de que su grado es por lo menos mejor_grado (de todos los nodos) * GREEDY_RANDOM_ALPHA. int n = G.size(); Nodos nodos(n, Nodo()); for(int u = 0; u < n; u++) { nodos[u].numero = u; nodos[u].grado = G[u].size(); } sort(nodos.begin(), nodos.end(), orden()); solucion = vector<int>(n, NO_INCLUIDO); int nodos_visitados = 0; while (nodos_visitados < n) { int mejor_grado = nodos[0].grado; int window_size = 0; // el maximo indice posible, la RCL va a ser nodos[0...window_size] for (int i = 0; i < nodos.size(); i++) { if (nodos[i].grado >= mejor_grado * GREEDY_RANDOM_ALPHA) { window_size = i; } else { break; } } int indice = random_in_range(0, min(window_size, (int)nodos.size()-1)); int nodo = nodos[indice].numero; solucion[nodo] = INCLUIDO; nodos_visitados++; nodos.erase(nodos.begin()+indice); for (list<int>::iterator itAdyU=G[nodo].begin(); itAdyU != G[nodo].end(); itAdyU++) { int v = *itAdyU; int index = get_indice_nodo(nodos, v); if (index != -1) { // v no esta en el vector de nodos nodos.erase(nodos.begin()+index); nodos_visitados++; } } } }
bool solucion_posible(Grafo& G, vector<int>& solucionCambiar, int cantCambios) { int n = G.size(); bool esSolucion = true; bool finCiclo = false; list<int> verticesCambiados; for (int u = 0; u < n && !finCiclo; u++) { // Si esta INCLUIDO, sus adyacentes no pueden estar INCLUIDOS if (solucionCambiar[u] == INCLUIDO && G[u].size() > 0) { for (list<int>::iterator itAdyU=G[u].begin(); itAdyU != G[u].end() && !finCiclo; ++itAdyU) { int v = *itAdyU; if (solucionCambiar[v] == INCLUIDO) { esSolucion = false; finCiclo = true; } } } else if (G[u].size() > 0) { // Si esta NO INCLUIDO, al menos uno de sus adyacentes tiene que estar INCLUIDO bool adyINCLUIDO = false; for (list<int>::iterator itAdyU=G[u].begin(); itAdyU != G[u].end() && !finCiclo; ++itAdyU) { int v = *itAdyU; if (solucionCambiar[v] == INCLUIDO) { adyINCLUIDO = true; } } if (!adyINCLUIDO && cantCambios == 0) { esSolucion = false; finCiclo = true; } else if(!adyINCLUIDO) { // Salvo la solucion al marcar el vertice solucionCambiar[u] = INCLUIDO; cantCambios --; } } else { // Si es un K1, tiene que estar INCLUIDO esSolucion = solucionCambiar[u] == INCLUIDO; finCiclo = !(solucionCambiar[u] == INCLUIDO); } } return esSolucion; }
void dijkstra(Grafo& grafo, unsigned inicio, vector<float>& pvecino, vector<unsigned>& vecino) { unsigned dim = grafo.size(); vecino = vector<unsigned>(dim, inicio); vector<bool> b = vector<bool>(dim, false); pvecino = vector<float>(dim); for (unsigned i = 0; i < dim; i++) pvecino[i] = grafo(inicio, i); b[inicio] = true; for (unsigned i = 1; i < dim; i++) { unsigned m = ~0; float min = INFINITY; for (unsigned j = 0; j < dim; j++) { if (!b[j] && 0 < pvecino[j] && pvecino[j] < min) { m = j; min = pvecino[j]; } } b[m] = true; for (unsigned j = 0; j < dim; j++) { float pa; if (!b[j] && (pa = pvecino[m] + grafo(m, j)) < pvecino[j]) { pvecino[j] = pa; vecino[j] = m; } } } }
void construir_greedy_random_segundo_criterio(Grafo& G, vector<int>& solucion) { // Criterio de Restricted Candidate List 2: los nodos que cumplan la condicion // de estar entre los 'GREEDY_RANDOM_BETA' (definido antes) mejores nodos. int n = G.size(); Nodos nodos(n, Nodo()); for(int u = 0; u < n; u++) { nodos[u].numero = u; nodos[u].grado = G[u].size(); } sort(nodos.begin(), nodos.end(), orden()); solucion = vector<int>(n, NO_INCLUIDO); int nodos_visitados = 0; while (nodos_visitados < n) { int mejor_grado = nodos[0].grado; int window_size = GREEDY_RANDOM_BETA; // el maximo indice posible, la RCL va a ser nodos[0...window_size] int indice = random_in_range(0, min(window_size, (int)nodos.size()-1)); int nodo = nodos[indice].numero; solucion[nodo] = INCLUIDO; nodos_visitados++; nodos.erase(nodos.begin()+indice); for (list<int>::iterator itAdyU=G[nodo].begin(); itAdyU != G[nodo].end(); itAdyU++) { int v = *itAdyU; int index = get_indice_nodo(nodos, v); if (index != -1) { // v no esta en el vector de nodos nodos.erase(nodos.begin()+index); nodos_visitados++; } } } }