User Manual, Developers Guide and API Documentation

DoAGrouper.cpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002  * This file is part of openWNS (open Wireless Network Simulator)
00003  * _____________________________________________________________________________
00004  *
00005  * Copyright (C) 2004-2009
00006  * Chair of Communication Networks (ComNets)
00007  * Kopernikusstr. 5, D-52074 Aachen, Germany
00008  * phone: ++49-241-80-27910,
00009  * fax: ++49-241-80-22242
00010  * email: info@openwns.org
00011  * www: http://www.openwns.org
00012  * _____________________________________________________________________________
00013  *
00014  * openWNS is free software; you can redistribute it and/or modify it under the
00015  * terms of the GNU Lesser General Public License version 2 as published by the
00016  * Free Software Foundation;
00017  *
00018  * openWNS is distributed in the hope that it will be useful, but WITHOUT ANY
00019  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
00020  * A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
00021  * details.
00022  *
00023  * You should have received a copy of the GNU Lesser General Public License
00024  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00025  *
00026  ******************************************************************************/
00027 
00028 #include <WNS/scheduler/grouper/DoAGrouper.hpp>
00029 
00030 #include <WNS/pyconfig/View.hpp>
00031 #include <WNS/StaticFactory.hpp>
00032 #include <WNS/CandI.hpp>
00033 
00034 #include <list>
00035 #include <math.h>
00036 #include <algorithm>
00037 
00038 using namespace wns::scheduler;
00039 using namespace wns::scheduler::grouper;
00040 
00041 DoATreeBasedGrouper::DoATreeBasedGrouper(const wns::pyconfig::View& config)
00042     : TreeBasedGrouper(config),
00043       strategy(config.get<int>("strategy"))
00044 {}
00045 
00046 float
00047 DoATreeBasedGrouper::getNormalizedDoA(UserID user)
00048 {
00049     float angle = this->friends.ofdmaProvider->estimateDoA(user.getNode());
00050 
00051     if (angle < 0.0)
00052         angle += 2*M_PI;
00053     return angle;
00054 }
00055 
00056 
00057 float
00058 DoATreeBasedGrouper::groupingCost(UserSet group, UserSet newGroup,
00059                                ModeType /* mode */) {
00060     float total = 0.0;
00061     std::vector<float> costs;
00062     costs.clear();
00063 
00064     for (UserSet::const_iterator iter = newGroup.begin();
00065          iter != newGroup.end(); ++iter) {
00066         float cost = groupingCostForAUser(group, *iter);
00067         costs.push_back(cost);
00068         total += cost;
00069     }
00070 
00071     switch (strategy) {
00072     case 0: {
00073         // returns the average cost
00074         return total / float(newGroup.size());
00075         break;
00076     }
00077     case 1: {
00078         // returns the maximum cost a group member experiences
00079         int maxIndex = max_element(costs.begin(), costs.end()) - costs.begin();
00080         return costs[maxIndex];
00081         break;
00082     }
00083     default:{
00084         assure(0,"Wrong strategy");
00085     }
00086     }
00087     assure(0, "Control structure meltdown");
00088     return 0.0; // not reached
00089 }
00090 
00091 
00092 
00093 Grouping
00094 DoATreeBasedGrouper::treeAlgorithm(const UserSet activeUsers, unsigned int maxBeams, ModeType mode)
00095 {
00096     std::vector<TreeLevel> treeLevels;
00097     std::map<float, std::pair<unsigned int, unsigned int> > costs;
00098 
00099     // init the first level
00100     TreeLevel firstLevel;
00101     for (UserSet::const_iterator iter = activeUsers.begin();
00102          iter != activeUsers.end(); ++iter) {
00103         UserSet oneUserGroup;
00104 
00105         oneUserGroup.clear();
00106         oneUserGroup.insert(*iter);
00107 
00108         std::map<UserID, wns::CandI> candis =
00109             getCandIsForGroup(oneUserGroup, mode);
00110 
00111         assure(candis.find(*iter) != candis.end(), "Where is my user gone?");
00112 
00113         // make sure we don't include users that can't even get a suitable SINR
00114         // when served alone
00115         wns::Ratio sinr(candis[*iter].C / candis[*iter].I);
00116         //if (colleagues.registry->getPhyModeForSIR( candis[*iter].C / candis[*iter].I ).second > 0.0001)
00117         //if (phymode->getRate() > 0.0001)
00118         if (colleagues.phyModeMapper->sinrIsAboveLimit(sinr))
00119         {
00120             individualCandIs[*iter] = candis[*iter];
00121             firstLevel.push_back(oneUserGroup);
00122         } else {
00123             // FIXME(fds)...
00124 //          LOG_INFO("discarding user ", colleagues.registry->getNameForUser(*iter), " because even alone its SINR is too bad for transmission");
00125         }
00126     }
00127     int maxTreeHeight = firstLevel.size();
00128     treeLevels.push_back(firstLevel);
00129 
00130     // then build the next higher levels by joining the two best-joinable groups
00131     // from the previous level
00132     for (int i = 0; i < maxTreeHeight; ++i)
00133     {
00134         costs.clear();
00135         // get all possible combinations of two groups, but don't calculate same
00136         // group twice
00137         for (unsigned int g1 = 0; g1 < treeLevels[i].size() - 1; ++g1)
00138             for (unsigned int g2 = g1+1; g2 < treeLevels[i].size(); ++g2)
00139                 if (treeLevels[i][g1].size() + treeLevels[i][g2].size() <= maxBeams)
00140                     // cost function is overwritten by specialized TreeGrouper variant
00141                     costs[groupingCost(treeLevels[i][g1], treeLevels[i][g2], mode)] =
00142                         std::make_pair<unsigned int, unsigned int>(g1,g2);
00143         //      assure(costs.size(), "Not on upmost level but all groups too big
00144         // to join");
00145         if (costs.size() == 0) // could not join two groups, so we are done
00146             break;
00147 
00148         std::pair<unsigned int, unsigned int> bestCombi = min_element(costs.begin(), costs.end())->second;
00149 
00150         // build the next level
00151         TreeLevel nextLevel;
00152 
00153         // first join the the two best joinable groups and then save it
00154         UserSet newGroup = treeLevels[i][bestCombi.first];
00155         newGroup.insert(treeLevels[i][bestCombi.second].begin(),
00156                         treeLevels[i][bestCombi.second].end());
00157         nextLevel.push_back(newGroup);
00158 
00159         // then add the others
00160         for(unsigned int g = 0; g < treeLevels[i].size(); ++g)
00161             if ((g != bestCombi.first) && (g != bestCombi.second))
00162                 nextLevel.push_back(treeLevels[i][g]);
00163 
00164         treeLevels.push_back(nextLevel);
00165         // continue with the just constructed next level
00166     }
00167 
00168     // get the TP for the base case (no SDMA) and calculate the average TP per
00169     // slot. This is the reference value for our grouping gain
00170     float trivialTP = getTPfromTreeLevelByMode(treeLevels[0], mode);
00171     float normalizedTrivialTP = trivialTP / float(treeLevels[0].size());
00172 
00173     std::vector<float> sdmaGain;
00174     sdmaGain.clear();
00175     sdmaGain.push_back(1.0); // the  first level (index 0) is the reference => gain = 1.0
00176 
00177     // now calculate the gain (avg TP per group in grouping on each tree level
00178     // divided by the avg TP per one-user-group in the base case
00179     for (unsigned int i = 1; i < treeLevels.size(); ++i) {
00180         sdmaGain.push_back((getTPfromTreeLevelByMode(treeLevels[i], mode) / treeLevels[i].size()) / normalizedTrivialTP);
00181         MESSAGE_SINGLE(NORMAL, logger, "Level " << i << " has gain of " << sdmaGain[i]);
00182     }
00183 
00184     int maxIndex = max_element(sdmaGain.begin(), sdmaGain.end()) - sdmaGain.begin();
00185 
00186     MESSAGE_SINGLE(NORMAL, logger, "Selecting Level " << maxIndex << " resulting in a gain of " << sdmaGain[maxIndex]);
00187 
00188     groupingGainProbeBus->put(sdmaGain[maxIndex]);
00189 
00190     return convertTreeLevelToGrouping(treeLevels[maxIndex], mode);
00191 }
00192 
00193 
00194 
00195 
00196 

Generated on Wed May 23 03:31:47 2012 for openWNS by  doxygen 1.5.5