QString getAssignmentChain(NetPath path, NetworkOverseer const& network) { if ( path.size() == 0 ) return QString("none"); QStringList result; for ( NetPath::iterator i = path.begin(); i != path.end(); i++) { NetworkingElement * ne = *i; if ( ne->isSwitch() ) { uint uid = network.getIdByElement(ne); result << QString().setNum(uid); } } NetPath::iterator first = path.begin(), last = path.end(); if ( (*first)->isLink() && (*(--last))->isLink() ) { Link * begin = static_cast<Link *>(*first); Link * end = static_cast<Link *>(*last); uint firstComp = network.getIdByElement(begin->getLinkedComputationalElement()); uint lastComp = network.getIdByElement(end->getLinkedComputationalElement()); result.prepend(QString().setNum(firstComp)); result.append(QString().setNum(lastComp)); } return result.join(";"); }
void DijkstraRouter::printPath(const NetPath & path) const { if ( path.empty() ) return; for ( NetPath::const_iterator i = path.begin(); i != path.end(); i++) { Element * element = *i; printf("%s:%lu", element->getName().c_str(), element->getID()); if ( i + 1 != path.end() ) printf(" -> "); } printf("\n"); }
long VirtualLinkRouter::calculateKShortestPathWeight(NetPath& path) { long result = 0l; NetPath::iterator it = path.begin(); NetPath::iterator itEnd = path.end(); for ( ; it != itEnd; ++it ) { result += (*it)->getCapacity(); } return result; }
NetPath VirtualLinkRouter::searchPathDejkstra(VirtualLink * virtualLink, Network * network, SearchPathAlgorithm algorithm) { if ( virtualLink->getFirst() == virtualLink->getSecond() ) return NetPath(); // local variables std::set<ElementWeight, WeightCompare> elementsToParse; std::map<Element * , Link*> incomingEdge; std::map<Element * , std::vector<Link *> > elementLinks; // initializing parameters Links::iterator it = network->getLinks().begin(); Links::iterator itEnd = network->getLinks().end(); std::vector<Link *> * vecLinks = NULL; for ( ; it != itEnd; ++it ) { if ((*it)->getFirst() != virtualLink->getFirst()) elementsToParse.insert(ElementWeight((*it)->getFirst(), LONG_MAX)); // LONG_MAX equals to inf if ((*it)->getSecond() != virtualLink->getFirst()) elementsToParse.insert(ElementWeight((*it)->getSecond(), LONG_MAX)); vecLinks = &elementLinks[(*it)->getFirst()]; if (vecLinks->capacity() < NLinks) vecLinks->reserve(NLinks); vecLinks->push_back(*it); vecLinks = &elementLinks[(*it)->getSecond()]; if (vecLinks->capacity() < NLinks) vecLinks->reserve(NLinks); vecLinks->push_back(*it); } elementsToParse.insert(ElementWeight(virtualLink->getFirst(), 0)); elementsToParse.insert(ElementWeight(virtualLink->getSecond(), LONG_MAX)); Element * currentElement = virtualLink->getFirst(); Link edge("dijkstra edge", 0); ElementWeight temp(NULL, -LONG_MAX); std::set<ElementWeight, WeightCompare>::iterator tempIter; long curWeight = 0; // algorithm itself while ( currentElement != NULL && currentElement != virtualLink->getSecond() ) { temp.element = currentElement; tempIter = elementsToParse.find(temp); assert(tempIter != elementsToParse.end()); curWeight = tempIter->weight; // std::cerr << "currentElement = " << currentElement << ", tempIter->element = " << tempIter->element << ", weight = " << tempIter->weight << '\n'; elementsToParse.erase(tempIter); // going through all neighbors of current element, // parsing their weight and choosing the element with the // lowest weight if ( elementLinks.find(currentElement) == elementLinks.end() ) { return NetPath(); // No links assosiated with element } std::vector<Link *>& curLinks = elementLinks[currentElement]; unsigned int sz = curLinks.size(); for(unsigned int index = 0; index < sz; ++ index) { Link * cur = curLinks[index]; Element * other = cur->getFirst() == currentElement ? cur->getSecond() : cur->getFirst(); temp.element = other; temp.weight = LONG_MAX; tempIter = elementsToParse.find(temp); if ( tempIter != elementsToParse.end() ) { edge.setCapacity(cur->getCapacity()); edge.bindElements(currentElement, other); // weight of reaching the next element from current element long weight = getEdgeWeigth(edge, network, algorithm) + curWeight; if ( weight < tempIter->weight ) { // have to erase and reinsert because weight is a part of the key temp.element = other; temp.weight = weight; elementsToParse.erase(tempIter); elementsToParse.insert(temp); incomingEdge[other] = cur; } } temp.weight = -LONG_MAX; } if (elementsToParse.begin()->weight != LONG_MAX) currentElement = elementsToParse.begin()->element; else return NetPath(); // if an infinite weight is the minimum, it is a fail } if ( currentElement != virtualLink->getSecond() ) return NetPath(); // no way from one element to another // retrieving the way NetPath answer; Element * other = currentElement; // for parsing results with just one edge while ( incomingEdge[currentElement]->getFirst() != virtualLink->getFirst() && incomingEdge[currentElement]->getSecond() != virtualLink->getFirst() ) { answer.push_back(incomingEdge[currentElement]); other = incomingEdge[currentElement]->getFirst() == currentElement ? incomingEdge[currentElement]->getSecond() : incomingEdge[currentElement]->getFirst(); answer.push_back(static_cast<NetworkingElement *>(other)); currentElement = other; } answer.push_back(incomingEdge[other]); // this step may be skiped, but doing for sure std::reverse(answer.begin(), answer.end()); return answer; }
NetPath VirtualLinkRouter::routeKShortestPathsALL(VirtualLink * virtualLink, Network * network, std::vector<NetPath> * pathStorage) { // links and switches that would be removed from the network, // they should be restored after algorithm's finish Links removedLinks; Switches removedSwitches; // first, create the graph with decreased capacities decreaseCapacities(virtualLink, network, &removedLinks, &removedSwitches); // Yen's algorithm NetPath shortest = searchPathDejkstra(virtualLink, network, K_SHORTEST_PATHS); if ( shortest.size() == 0 ) { restoreCapacities(virtualLink, network, &removedLinks, &removedSwitches); return NetPath(); // no path found! } pathStorage->push_back(shortest); Links& links = network->getLinks(); unsigned pathsFound = 1; long pathWeight = calculateKShortestPathWeight(shortest); bool isNewPathFound = true; while ( isNewPathFound && pathsFound < Criteria::kShortestPathDepth() ) { NetPath candidate = shortest; NetPath::iterator it = shortest.begin(); NetPath::iterator itEnd = shortest.end(); isNewPathFound = false; bool isNewCandidateFound = false; Link * linkToRemove = NULL; for ( ; it != itEnd; ++it ) { if ( (*it)->isLink() && links.find(static_cast<Link*>(*it)) != links.end() ) { // removing link and trying dejkstra links.erase(links.find(static_cast<Link*>(*it))); NetPath newPath = searchPathDejkstra(virtualLink, network, K_SHORTEST_PATHS); if ( newPath.size() == shortest.size() ) { isNewPathFound = true; pathStorage->push_back(newPath); ++pathsFound; long weight = calculateKShortestPathWeight(newPath); if ( weight > pathWeight ) { isNewCandidateFound = true; linkToRemove = static_cast<Link*>(*it); pathWeight = weight; candidate = newPath; if ( pathsFound == Criteria::kShortestPathDepth() ) break; } if ( linkToRemove == NULL ) linkToRemove = static_cast<Link*>(*it); // to avoid the situation with removing NULL-link } links.insert(static_cast<Link*>(*it)); // inserting link again } } if ( isNewCandidateFound ) shortest = candidate; if ( isNewPathFound && pathsFound != Criteria::kShortestPathDepth() ) { // restoring the capacity of link being removed linkToRemove->RemoveAssignment(virtualLink); links.erase(links.find(linkToRemove)); removedLinks.insert(linkToRemove); } } // restoring removed capacities restoreCapacities(virtualLink, network, &removedLinks, &removedSwitches); return shortest; }
NetPath DijkstraRouter::search() { if ( !validateInput() ) { printf("[RD]Wrong input\n"); return NetPath(); } if ( link->getFirst() == link->getSecond() ) return NetPath(); std::set<ElementWeight, WeightCompare> elementsToParse; std::map<Element * , Link *> incomingEdge; std::map<Element * , std::vector<Link *> > elementLinks; Links & links = network->getLinks(); for ( Links::iterator i = links.begin(); i != links.end(); i++ ) { Link * l = *i; if ( l->getFirst() != link->getFirst() ) elementsToParse.insert(ElementWeight(l->getFirst(), LONG_MAX)); if ( l->getSecond() != link->getFirst() ) elementsToParse.insert(ElementWeight(l->getSecond(), LONG_MAX)); elementLinks[l->getFirst()].push_back(l); elementLinks[l->getSecond()].push_back(l); } elementsToParse.insert(ElementWeight(link->getFirst(), 0)); elementsToParse.insert(ElementWeight(link->getSecond(), LONG_MAX)); Element * currentElement = link->getFirst(); Link edge("dijkstraedge", 0); ElementWeight temp(0, -LONG_MAX); std::set<ElementWeight, WeightCompare>::iterator tempIter; long curWeight = 0; while ( currentElement != 0 && currentElement != link->getSecond() ) { temp.element = currentElement; tempIter = elementsToParse.find(temp); assert(tempIter != elementsToParse.end()); curWeight = tempIter->weight; elementsToParse.erase(tempIter); if ( elementLinks.find(currentElement) == elementLinks.end() ) return NetPath(); std::vector<Link *>& curLinks = elementLinks[currentElement]; unsigned int size = curLinks.size(); for(unsigned int index = 0; index < size; index++) { Link * cur = curLinks[index]; Element * other = cur->getFirst() == currentElement ? cur->getSecond() : cur->getFirst(); temp.element = other; temp.weight = LONG_MAX; tempIter = elementsToParse.find(temp); if ( tempIter != elementsToParse.end() ) { edge.setCapacity(cur->getCapacity()); edge.bindElements(currentElement, other); long weight = getEdgeWeight(&edge) + curWeight; if ( weight < tempIter->weight ) { temp.element = other; temp.weight = weight; elementsToParse.erase(tempIter); elementsToParse.insert(temp); incomingEdge[other] = cur; } } temp.weight = -LONG_MAX; } if (elementsToParse.begin()->weight != LONG_MAX) currentElement = elementsToParse.begin()->element; else return NetPath(); } if ( currentElement != link->getSecond() ) return NetPath(); Element * other = currentElement; NetPath result; while ( incomingEdge[currentElement]->getFirst() != link->getFirst() && incomingEdge[currentElement]->getSecond() != link->getFirst() ) { result.push_back(incomingEdge[currentElement]); other = incomingEdge[currentElement]->getFirst() == currentElement ? incomingEdge[currentElement]->getSecond() : incomingEdge[currentElement]->getFirst(); result.push_back((NetworkingElement *)other); currentElement = other; } result.push_back(incomingEdge[other]); std::reverse(result.begin(), result.end()); return result; }
void NetworkManager::addAssignment(Link * vlink, NetPath & netPath) { for ( NetPath::iterator i = netPath.begin(); i != netPath.end(); i++ ) (*i)->assign(*vlink); }
Algorithm::Result FirstFitAlgorithm::schedule() { for (Requests::iterator i = requests.begin(); i != requests.end(); i++) { Request * request = *i; Assignment * assignment = new Assignment(request); Algorithm::Result result = SUCCESS; Nodes & vms = request->getVirtualMachines(); for (Nodes::iterator vmi = vms.begin(); vmi != vms.end(); vmi++) { Node * vm = *vmi; Nodes & nodes = network->getNodes(); Nodes::iterator n; for (n = nodes.begin(); n != nodes.end(); n++) { Node * node = *n; if ( node->isAssignmentPossible(*vm) ) { node->assign(*vm); assignment->AddAssignment(vm, node); break; } } if ( n == nodes.end() ) { result = FAILURE; break; } } Stores & storages = request->getStorages(); for (Stores::iterator s = storages.begin(); s != storages.end(); s++) { Store * storage = *s; Stores & stores = network->getStores(); Stores::iterator si; for ( si = stores.begin(); si != stores.end(); si++) { Store * store = *si; if ( store->isAssignmentPossible(*storage) ) { store->assign(*storage); assignment->AddAssignment(storage, store); break; } } if ( si == storages.end() ) { result = FAILURE; break; } } Links & vlinks = request->getVirtualLinks(); for (Links::iterator l = vlinks.begin(); l != vlinks.end(); l++) { Link * dummy = createDummyLink(*l, assignment); if ( dummy == 0 ) { result = FAILURE; break; } NetPath netPath = VirtualLinkRouter::routeDejkstra(dummy, network); delete dummy; if ( netPath.size() == 0 ) { result = FAILURE; break; } for ( NetPath::iterator i = netPath.begin(); i != netPath.end(); i++) { (*i)->assign(**l); } assignment->AddAssignment(*l, netPath); } if ( result == FAILURE ) delete assignment; else assignments.insert(assignment); } printf("Assigned total of %d from %d requests", assignments.size(), requests.size()); if ( assignments.size() == requests.size() ) return SUCCESS; else if ( assignments.size() != 0 ) return PARTIAL; else return FAILURE; }