![]() |
User Manual, Developers Guide and API Documentation |
![]() |
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 "RelayPreferredSINRHeuristic.hpp" 00029 00030 #include <WNS/pyconfig/View.hpp> 00031 #include <WNS/StaticFactory.hpp> 00032 00033 using namespace wns::scheduler; 00034 using namespace wns::scheduler::grouper; 00035 00036 STATIC_FACTORY_REGISTER_WITH_CREATOR( 00037 RelayPreferredSINRHeuristic, 00038 GroupingProviderInterface, 00039 "RelayPreferredSINRHeuristic", 00040 wns::PyConfigViewCreator); 00041 00042 00043 RelayPreferredSINRHeuristic::RelayPreferredSINRHeuristic(const wns::pyconfig::View& config) 00044 : TreeBasedGrouper(config) 00045 { 00046 } 00047 00048 float 00049 RelayPreferredSINRHeuristic::groupingUtility(UserSet group, UserSet newGroup, ModeType mode) { 00050 // merge the two groups 00051 group.insert(newGroup.begin(), newGroup.end()); 00052 00053 std::map<UserID, wns::CandI> candis = 00054 getCandIsForGroup(group, mode); 00055 00056 double sum = 0.0; 00057 00058 for (UserSet::iterator iter = group.begin(); 00059 iter != group.end(); ++iter) 00060 { 00061 assure(candis.find(*iter) != candis.end(), "Where is my user gone?"); 00062 wns::Ratio sinr(candis[*iter].C / candis[*iter].I); 00063 wns::SmartPtr<const wns::service::phy::phymode::PhyModeInterface> phyMode = colleagues.phyModeMapper->getBestPhyMode(sinr); 00064 double tp = phyMode->getDataRate(); 00065 if (tp < 0.001) 00066 return 0.0; // don't allow user without service 00067 else 00068 sum += tp; 00069 } 00070 return sum; 00071 } 00072 00073 00074 00075 float 00076 RelayPreferredSINRHeuristic::getTPfromTreeLevel(TreeLevel level, std::map<UserSet, float> &groupTP) 00077 { 00078 float tpLevel = 0.0; 00079 for (TreeLevel::const_iterator iter = level.begin(); 00080 iter != level.end(); ++iter) 00081 if (groupTP[*iter] < 0.0001) 00082 return 0.0; 00083 else 00084 tpLevel += groupTP[*iter]; 00085 return tpLevel; 00086 } 00087 00088 00089 Grouping 00090 RelayPreferredSINRHeuristic::treeAlgorithm(const UserSet activeUsers, unsigned int maxBeams, ModeType mode) 00091 { 00092 std::vector<TreeLevel> treeLevels; 00093 std::map<UserSet, float> groupTP; // database that stores TP for every group 00094 00095 std::vector<float> sdmaGain; 00096 sdmaGain.clear(); 00097 00098 UserSet relayStations; 00099 UserSet groupableUsers; 00100 for ( UserSet::const_iterator iter = activeUsers.begin(); 00101 iter != activeUsers.end(); ++iter) 00102 { 00103 if ( colleagues.registry->getStationType(*iter) == wns::service::dll::StationTypes::FRS() ) 00104 relayStations.insert(*iter); 00105 else 00106 groupableUsers.insert(*iter); 00107 } 00108 00109 // init the first level 00110 TreeLevel firstLevel; 00111 //for (UserSet::const_iterator iter = activeUsers.begin(); 00112 //iter != activeUsers.end(); ++iter) { 00113 for (UserSet::const_iterator iter = groupableUsers.begin(); 00114 iter != groupableUsers.end(); ++iter) 00115 { 00116 UserSet oneUserGroup; 00117 00118 oneUserGroup.insert(*iter); 00119 00120 std::map<UserID, wns::CandI> candis = 00121 getCandIsForGroup(oneUserGroup, mode); 00122 00123 assure(candis.find(*iter) != candis.end(), "Where is my user gone?"); 00124 00125 // make sure we don't include users that can't even get a suitable SINR 00126 // when served alone 00127 wns::Ratio sinr(candis[*iter].C / candis[*iter].I); 00128 wns::SmartPtr<const wns::service::phy::phymode::PhyModeInterface> phyMode = colleagues.phyModeMapper->getBestPhyMode(sinr); 00129 double tp = phyMode->getDataRate(); 00130 if (tp > 0.0001) 00131 { 00132 groupTP[oneUserGroup] = tp; 00133 individualCandIs[*iter] = candis[*iter]; 00134 firstLevel.push_back(oneUserGroup); 00135 } else { 00136 // FIXME(jke): 00137 // LOG_INFO("discarding user ", colleagues.registry->getNameForUser(*iter), " because even alone its SINR is too bad for transmission"); 00138 } 00139 } 00140 treeLevels.push_back(firstLevel); 00141 unsigned int maxTreeHeight = firstLevel.size(); 00142 00143 // get the TP for the base case (no SDMA) and calculate the average TP per 00144 // slot. This is the reference value for our grouping gain 00145 float trivialTP = getTPfromTreeLevel(treeLevels[0], groupTP); 00146 float normalizedTrivialTP = trivialTP / float(treeLevels[0].size()); 00147 sdmaGain.push_back(1.0); // the first level (index 0) is the reference => gain = 1.0 00148 00149 00150 // then build the next higher levels by joining the two best-joinable groups 00151 // from the previous level 00152 for (unsigned int i = 0; i < maxTreeHeight; ++i) 00153 { 00154 std::map<float, std::pair<unsigned int, unsigned int> > combinedTP; 00155 00156 // get all possible combinations of two groups, but don't calculate same 00157 // group twice 00158 for (unsigned int g1 = 0; g1 < treeLevels[i].size() - 1; ++g1) 00159 for (unsigned int g2 = g1+1; g2 < treeLevels[i].size(); ++g2) 00160 if (treeLevels[i][g1].size() + treeLevels[i][g2].size() <= maxBeams) 00161 // cost function is overwritten by specialized TreeGrouper variant 00162 combinedTP[groupingUtility(treeLevels[i][g1], treeLevels[i][g2], mode)] = 00163 std::make_pair<unsigned int, unsigned int>(g1,g2); 00164 // assure(costs.size(), "Not on upmost level but all groups too big 00165 // to join"); 00166 if (combinedTP.size() == 0) // could not join two groups, so we are done 00167 break; 00168 00169 std::pair<float, std::pair<unsigned int, unsigned int> > maxEntry = *(max_element(combinedTP.begin(), combinedTP.end())); 00170 std::pair<unsigned int, unsigned int> bestCombi = maxEntry.second; 00171 00172 // build the next level 00173 TreeLevel nextLevel; 00174 00175 // first join the the two best joinable groups and then save it 00176 UserSet newGroup = treeLevels[i][bestCombi.first]; 00177 newGroup.insert(treeLevels[i][bestCombi.second].begin(), 00178 treeLevels[i][bestCombi.second].end()); 00179 nextLevel.push_back(newGroup); 00180 00181 // the TP for the new group was delivered by the utility function 00182 groupTP[newGroup] = maxEntry.first; 00183 00184 // then add the others 00185 for (unsigned int g = 0; g < treeLevels[i].size(); ++g) 00186 if ((g != bestCombi.first) && (g != bestCombi.second)) 00187 nextLevel.push_back(treeLevels[i][g]); 00188 00189 // calculate the SDMA gain for next level 00190 sdmaGain.push_back((getTPfromTreeLevel(nextLevel, groupTP) / nextLevel.size()) / normalizedTrivialTP); 00191 treeLevels.push_back(nextLevel); 00192 // continue with the just constructed next level 00193 } 00194 00195 // now see who got the best sdmaGain and convert it to a grouping before returning 00196 00197 int maxIndex = max_element(sdmaGain.begin(), sdmaGain.end()) - sdmaGain.begin(); 00198 00199 MESSAGE_SINGLE(NORMAL, logger, "Selecting Level " << maxIndex << " resulting in a gain of " << sdmaGain[maxIndex]); 00200 00201 groupingGainProbeBus->put(sdmaGain[maxIndex]); 00202 00203 if ( !relayStations.empty() ) 00204 treeLevels[maxIndex].push_back(relayStations); 00205 00206 return convertTreeLevelToGrouping(treeLevels[maxIndex], mode); 00207 } 00208 00209
1.5.5