![]() |
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 <WNS/scheduler/grouper/OptimalGrouper.hpp> 00029 00030 using namespace wns::scheduler; 00031 using namespace wns::scheduler::grouper; 00032 00033 STATIC_FACTORY_REGISTER_WITH_CREATOR(OptimalGrouper, GroupingProviderInterface, "OptimalGrouper", wns::PyConfigViewCreator); 00034 00035 00036 OptimalGrouper::OptimalGrouper(const wns::pyconfig::View& config) 00037 : AllPossibleGroupsGrouper(config) 00038 { 00039 } 00040 00041 AllPossibleGroupsGrouper::Partition 00042 OptimalGrouper::makeGrouping(int _maxBeams, unsigned int _noOfStations) 00043 { // wrapper for recursive function 00044 maxBeams = _maxBeams; 00045 noOfStations = _noOfStations; 00046 00047 // start with the emptyGrouping and the first group 00048 Partition emptyPartition; 00049 00050 emptyPartition.servedStations = std::bitset<MAX_STATIONS>(0); 00051 emptyPartition.groups.clear(); 00052 emptyPartition.totalThroughput = 0.0; 00053 00054 throughputCurrentBestGrouping= 0.0; 00055 throughputTrivialGrouping = getTPperGroupTrivialGrouping(noOfStations); 00056 00057 makeGroupingRecursively(emptyPartition, 0); 00058 00059 groupingGainProbeBus->put(throughputCurrentBestGrouping / throughputTrivialGrouping); 00060 00061 return currentBestGrouping; 00062 } 00063 00064 void 00065 OptimalGrouper::makeGroupingRecursively(Partition currentGroups, int firstGroup) 00066 { 00067 // This function is the heart of the optimal grouper because it performs the 00068 // exhaustive search for the optimal grouping. It needs the following member 00069 // variables to perform its search: 00070 // - allPossibleGroups which contains all possible station combinations and 00071 // has to be computed before 00072 // - noOfStations an integer that contains the total numbers of users to be grouped 00073 // 00074 // makeGrouping recursively enumerates all valid partitions of the set of 00075 // active users. A partition is valid if every user is covered exactly once 00076 00077 if (currentGroups.servedStations.count() == noOfStations) 00078 { // all stations served, partitioning done 00079 // now check if this is a new best solution 00080 00081 float TPperGroups = (float) (currentGroups.totalThroughput) / (float)(currentGroups.groups.size()); 00082 00083 if (TPperGroups > throughputCurrentBestGrouping) { 00084 // FIXME(jke): 00085 // LOG_INFO("New best grouping found with gain of ", TPperGroups / throughputTrivialGrouping); 00086 currentBestGrouping = currentGroups; 00087 throughputCurrentBestGrouping = TPperGroups; 00088 } 00089 return; 00090 } 00091 else { 00092 // i runs from beam firstGroup..maxGroups 00093 // This is important for speedup: the order in which the groups 00094 // are found is not important. Like this, only the grouping in 00095 // canoncial ordering is found 00096 00097 // j runs over number of stations in Group i 00098 00099 for (unsigned int i = firstGroup; i < allPossibleGroups.size(); ++i) { 00100 // do a bitwise AND of the two bitsets to check whether the set of 00101 // already covered stations in curentGroups and the stations in the 00102 // group to be considered (allPossibleGroups[i]) conflict 00103 if ((allPossibleGroups[i].servedStations & currentGroups.servedStations).count() == 0) { 00104 // all stations not yet covered 00105 00106 Partition newGrouping = currentGroups; 00107 00108 // set stations as covered in new grouping 00109 // this is simply the bitwise OR of stations already covered and 00110 // newly covered by allPossibleGroups[i] 00111 newGrouping.servedStations = (allPossibleGroups[i].servedStations | currentGroups.servedStations); 00112 00113 // add group to new grouping 00114 newGrouping.groups.push_back(i); 00115 newGrouping.totalThroughput += allPossibleGroups[i].throughPut; 00116 00117 makeGroupingRecursively(newGrouping, i+1); 00118 } 00119 } 00120 return; 00121 } 00122 } 00123 00124 00125
1.5.5