//Retorna la descomposicion en key-path del grafo pasado por parametro Collection* KeyPathLocalSearch::KeyPathDecomp(Graph *g){ Graph *grafo = g->Copy(); Collection *K = new Collection(); //nodos que pueden ser extremos de los key-path, son terminales o key-nodes Collection * terminals = g->GetTerminals(); Collection * key_nodes = g->GetKeyNodes(true); Collection * end_nodes = terminals->Union(key_nodes); int node, currentNode, lastIdentifier, degree; bool isTerminal, isKeyNode; //para cada posible nodo extremo de key-path for (int i=0; i<end_nodes->Size(); i++){ node = ((Integer*)end_nodes->GetItem(i))->GetValue(); Collection * end_node_adyacents = grafo->GetAdyacents(node); //para cada adyacente al nodo extremo for (int j = 0; j < end_node_adyacents->Size(); j++){ lastIdentifier = node; //creo el camino Path * aux = new Path(g); //agrego el extremo aux->Add(node); //calculo el nodo siguiente del camino currentNode = ((Integer*)end_node_adyacents->GetItem(j))->GetValue(); degree = grafo->GetNodeDegree(currentNode); if (grafo->IsNodeEnabled(currentNode) && degree != 0){ do { //agrego nodo al camino aux->Add(currentNode); Collection * adyacents = grafo->GetAdyacents(currentNode); //calculo si es terminal y si es key-node isTerminal = g->IsTerminal(currentNode); isKeyNode = g->IsKeyNode(currentNode); //si es nodo intermedio actualizo el currentNode if(! isTerminal && ! isKeyNode){ if(((Integer*)adyacents->GetItem(0))->GetValue() == lastIdentifier){ lastIdentifier = currentNode; currentNode = ((Integer*)adyacents->GetItem(1))->GetValue(); } else{ lastIdentifier = currentNode; currentNode = ((Integer*)adyacents->GetItem(0))->GetValue(); } } adyacents->Destroy(); }while(! isTerminal && ! isKeyNode); //mientras este en nodos intermedios K->Add((Object*)aux); //apago aristas y nodos del path, dejo prendidos los extremos if (aux->Length() > 2) { for (int ind=1; ind<aux->Length()-1; ind++){ Collection *adyacents = grafo->GetAdyacents(aux->GetNode(ind)); //apago aristas si es que existen for (int iter=0; iter<adyacents->Size();iter++){ if (grafo->ExistEdge(aux->GetNode(ind),((Integer*)adyacents->GetItem(iter))->GetValue())) grafo->DisableEdge(aux->GetNode(ind),((Integer*)adyacents->GetItem(iter))->GetValue()); } grafo->DisableNode(aux->GetNode(ind)); adyacents->Destroy(); } } else //key-path de dos nodos { grafo->DisableEdge(aux->GetNode(0),aux->GetNode(1)); } } else{ delete aux; } } end_node_adyacents->Destroy(); } terminals->Destroy(); key_nodes->Destroy(); delete end_nodes; delete grafo; return K; }