예제 #1
0
    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(";");
    }
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;
}
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");
}
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;
}
예제 #7
0
void NetworkManager::addAssignment(Link * vlink, NetPath & netPath)
{
    for ( NetPath::iterator i = netPath.begin(); i != netPath.end(); i++ )
        (*i)->assign(*vlink);
}
예제 #8
0
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;
}