//El algoritmo toma como entrada el grafo factible solucion encontrado. //Retorna el grafo solucion optimizado mediante busqueda local basada en key-paths. Graph* KeyPathLocalSearch::KeyPathLS(Graph *graph){ //Hago una copia para trabajar en el algoritmo Graph * gsol = graph->Copy(); bool improve = true; //seteo la semilla srand((unsigned)time(0)); //genero el grafo original antes de la construccion greedy Graph *G = gsol->Copy(); G->EnableAll(); Path *p, *shortest; int index,x,y; Collection *nodes; //buscamos soluciones vecinas analizando cada key-path en gsol y remplazando //los mismos por otro para mejorar los costos sin perder la factibilidad. while (improve){ improve = false; //descomposicion en key-paths del grafo Collection *K = KeyPathDecomp(gsol); //genero coleccion de flags para marcar key-paths ya analizados Collection *analized = new Collection(); for (int i = 0; i<K->Size(); i++) analized->Add((Object*) new Boolean(false)); while (not(improve) and NotAnalizedKP(analized)){ //sorteo key-path a analizar index = GetRandomIndex(analized); ((Boolean*)analized->GetItem(index))->SetValue(true); //obtengo el key-path a analizar p = (Path*)K->GetItem(index); //quito del grafo original los nodos del grafo solucion y las aristas adyacentes Graph *mu = G->Copy(); Collection *enabled = gsol->GetEnabledNodes(); mu->Rest(enabled); enabled->Destroy(); nodes = mu->GetEnabledNodes(); //habilito los nodos del key-path examinado y las aristas correspondientes for(int ind = 0; ind < p->Length(); ind++){ mu->EnableNode(p->GetNode(ind)); x = p->GetNode(ind); for (int j = 0; j<nodes->Size(); j++){ y = ((Integer*)nodes->GetItem(j))->GetValue(); if (mu->ExistEdge(x,y)) mu->EnableEdge(x,y); } } nodes->Destroy(); for(int ind = 0; ind < p->Length()-1; ind++) mu->EnableEdge(p->GetNode(ind),p->GetNode(ind+1)); //obtengo el camino mas corto entre los extremos del key-path shortest = Algorithms::Dijkstra(mu,p->GetNode(0),p->GetNode(p->Length()-1)); if (shortest != NULL){ //comparo los costos if((shortest->GetCost()) < (p->GetCost())){ //quito los nodos del key-path del grafo solucion y sus aristas adyacentes, los extremos los dejo if (p->Length() > 2){ for(int ind = 1; ind < p->Length()-1; ind++){ Collection * adyacents = gsol->GetAdyacents(p->GetNode(ind)); for (int j = 0; j < adyacents->Size(); j++) gsol->DisableEdge(p->GetNode(ind),((Integer*)adyacents->GetItem(j))->GetValue()); gsol->DisableNode(p->GetNode(ind)); adyacents->Destroy(); } } else //key-path de dos nodos gsol->DisableEdge(p->GetNode(0),p->GetNode(1)); //agrego los nodos del camino mas corto encontrado y las aristas de este, los extremos ya estan for (int ind = 0; ind < shortest->Length()-1; ind++){ x = shortest->GetNode(ind); y = shortest->GetNode(ind+1); if (gsol->ExistEdge(x,y)) gsol->EnableEdge(x,y); gsol->EnableNode(x); gsol->EnableNode(y); } //encontre una mejora para el grafo solucion improve = true; } } delete shortest; delete mu; } analized->Destroy(); K->Destroy(); } delete G; return gsol; }
void Shader::OnCommand(wxCommandEvent& evt) { Project *project = Project::GetProject(); Panel *panel; Undoer *undoer; Graph *graph; if (project != NULL) { panel = project->GetPanel(); if (panel != NULL) { undoer = panel->GetUndoerCtrl(); graph = panel->GetGraphCtrl(); } } switch (evt.GetId()) { case wxID_OPEN: Open(); break; case wxID_SAVE: Save(); break; case wxID_SAVEAS: SaveAs(); break; case wxID_EXIT: Close(false); break; case wxID_UNDO: undoer->Undo(); break; case wxID_REDO: undoer->Redo(); break; case wxID_CUT: graph->Cut(); break; case wxID_COPY: graph->Copy(); break; case wxID_PASTE: graph->Paste(); break; case wxID_DUPLICATE: graph->Duplicate(); break; case wxID_GROUP: graph->GroupNodes(); break; case wxID_UNGROUP: graph->UngroupNodes(); break; case wxID_SAVEGROUP: graph->SaveGroup(); break; case wxID_COPYMETAFILE: graph->CopyAsMetafile(); break; case wxID_CONFIGURE: project->Configure(); break; case wxID_RELOADLIBS: //project->ReloadLibs(); break; } }