📄 testbed.cpp
字号:
//////////////////////////////////////////////////////////////////////
// Title: Geographic Load Balancing for Cellular Networks
// by emulating the behavior of air bubbles
//
// Description: This project is for dynamically balancing the traffic load
// over a cellular network with fully adaptive antennas by
// emulating the behaviours of a bubble array. Since
// we assume fully adaptive base station antenna in this
// version, antenna agent and simulator are not needed.
//
// Copyright: Copyright (c) 2003
// Company: Elec. Eng. Dept., Queen Mary, University of London
// @author Lin Du (lin.du@elec.qmul.ac.uk)
// @version 1.0
//
//////////////////////////////////////////////////////////////////////
#include "TestBed.h"
//////////////////////////////////////////////////////////////////////
// Default constructors
//////////////////////////////////////////////////////////////////////
TestBed::TestBed() {
}
TestBed::TestBed(char *BSScenarioFile, MAS_AMS *ams, MAS_DF *df) {
simTime = 100; // not used in this project
this->ams = ams;
this->df = df;
ams->tb = this;
df->tb = this;
// Read BS scenario file, initiate bs and ms array.
try {
double data, x, y;
int Color;
// Open BS scenario data file.
ifstream fin(BSScenarioFile, ios::in);
// Initial each BS in a diamond area.
for (int i=0; i<BS_NUMBER; i++) {
fin >> x;
fin >> y;
fin >> data;
fin >> Color;
// Read capacity from BS scenario file
// bsagt[i] = new BaseStation(x, y, data, i+1, Color, df); // Use i+1 as ID, because ID must start from 1.
// set BS capacity from Constants.h
bs[i] = new BaseStation(x, y, AVG_CAPACITY, i+1, Color, df); // Use i+1 as ID, because ID must start from 1.
}
fin.close();
// Set up the BS neighbour for each BS
for (i=0; i<BS_NUMBER; i++) {
bs[i]->findNeighbour(bs);
}
}
catch(...) {
cout << "Fatal Error with BS scenario file: " << BSScenarioFile << endl;
exit(1);
}
// Initial each TU with location (0,0) and demand 0.
for (long i=0; i<TU_NUMBER; i++) {
tu[i] = new TrafficUnit(0, 0, 0, i+1); // Use i+1 as ID, because ID must start from 1.
}
}
/**
* De-constructor
*/
TestBed::~TestBed() {
// Release the memory of all the objs.
for(int i=0; i<BS_NUMBER; i++)
delete bs[i];
for(long tu_i=0; tu_i<TU_NUMBER; tu_i++)
delete tu[tu_i];
}
//////////////////////////////////////////////////////////////////////
// Read TU scenario file.
//////////////////////////////////////////////////////////////////////
void TestBed::ReadMSScenario(char* TrafficScenarioFile) {
try {
// bool on_off; // on talking or not. Not used in this version, coz using the same call generator as negotiation
float buf[3]; //x, y, demand
// Open TU scenario data file.
#ifdef _BINARY_INPUT_
ifstream fin(TrafficScenarioFile, ios::binary); // binary mode
#else
ifstream fin(TrafficScenarioFile); // text mode
#endif
// Initial each TU according to TU scenario data file.
for (long i=0; i<TU_NUMBER; i++) {
#ifdef _BINARY_INPUT_
fin.read((char *)buf, 3*sizeof(float)); // binary mode
#else
fin >> buf[0]; fin >> buf[1]; fin >> buf[2]; // text mode
#endif
// Check if the TU is in forbidden zone, if yes, add one units on its distance to BS.
Point MS_loc( buf[0], buf[1] );
checkMSDistance( MS_loc );
// Set the location and demand of TU
tu[i]->move(MS_loc);
tu[i]->setDemand(buf[2]);
}
fin.close();
}
catch(...){
cout << "Fatal Error with TU scenario file: " << TrafficScenarioFile << endl;
exit(1);
}
// Set up the posibleMS for each BS
for (int i=0; i<BS_NUMBER; i++) {
bs[i]->findPossibleTU(tu, simTime);
}
}
//////////////////////////////////////////////////////////////////////
// Advance the simulting time (update the internal state of call generator)
//////////////////////////////////////////////////////////////////////
void TestBed::advanceSimTime(int timeUnitNum, bool updateCallStatus) {
if (updateCallStatus) {
for (int i=0; i<timeUnitNum; i++) {
// increase the simulating time by TIME_INTERVAL
simTime += TIME_INTERVAL;
for (long j=0; j<TU_NUMBER; j++) {
// update the internal state of MS's call generator
tu[j]->isTalking( simTime );
}
// we don't run subscription process here, because our simulatior is not really
// discrete-event simulatior. It needs too much efforts to do so at present, so
// we leave it to the next version (maybe in OPNET).
}
}
else {
// For recovering from p[revious saved states;
simTime += TIME_INTERVAL * timeUnitNum;
}
}
//////////////////////////////////////////////////////////////////////
// reset the subscription status of the network
//////////////////////////////////////////////////////////////////////
void TestBed::reset() {
long i;
// Reset all the BS
for( i=0; i<BS_NUMBER; i++)
bs[i]->reset();
// reset all the TU
for ( i=0; i<TU_NUMBER; i++)
tu[i]->reset();
}
//////////////////////////////////////////////////////////////////////
// simulating, now only used for evaluating the results of different approach.
//////////////////////////////////////////////////////////////////////
void TestBed::simulate(const bool doAssignment) {
int i;
// Perform assignment for circular allocation scheme, otherwise, no need to do it
if (doAssignment) {
// Reset all the tu
for( i=0; i<TU_NUMBER; i++)
tu[i]->reset();
// Reset all the BS
for( i=0; i<BS_NUMBER; i++)
bs[i]->reset();
// Perform the assignment, if first time, save the assignment into currLAS at BSAgent
for( i=0; i<BS_NUMBER; i++)
bs[i]->assignment();
// save this assignment, only useful for the first time
for( i=0; i<BS_NUMBER; i++)
bs[i]->saveAssignment();
}
// Calculate the system capacity by tu, should be the same as the previous one
systemCapacity = 0;
blockedTU = 0;
for ( i=0; i<MAX_SHARE_NUM; i++)
sharedTU[i] = 0;
double dem;
TrafficUnit **pp_tu = tu;
// Get the system capacity, blocked num, and shared num
for (int j=0; j<TU_NUMBER; j++) {
TrafficUnit *p_tu = *pp_tu;
if( p_tu->isTalking(simTime) ) { // check if it is talking
dem = p_tu->getDemand();
if ( p_tu->isServed() ) { // served
// calculate the system capacity
systemCapacity += dem;
// check how many BS is serving this tu
for( i = MAX_SHARE_NUM - 1; i >= 0; i--) {
if ( p_tu->isServed(i) ) {
sharedTU[i] += dem;
break;
}
}
}
else {
// otherwise, it is blocked
blockedTU += dem;
}
}
pp_tu ++;
}
#ifdef _DEBUG
// for debug, check if the calculation is right or not
double cap = 0;
// Get the system capacity
for (i=0; i<BS_NUMBER; i++) {
cap += bs[i]->getUtilization();
}
double cap2 = 0;
for ( i=0; i<MAX_SHARE_NUM; i++)
cap2 += (i+1) * sharedTU[i];
// they should be equal
_ASSERT( (cap - cap2) < 1.0e-5);
// for debug
#endif
}
//////////////////////////////////////////////////////////////////////
// Return system capacity.
//////////////////////////////////////////////////////////////////////
double TestBed::getSystemCapacity() const{
return systemCapacity;
}
//////////////////////////////////////////////////////////////////////
// Return number of blocked TU.
//////////////////////////////////////////////////////////////////////
double TestBed::getBlockedNum() const{
return blockedTU;
}
//////////////////////////////////////////////////////////////////////
// Return the number of the served TU by n BSs
//////////////////////////////////////////////////////////////////////
double TestBed::getSharedNum(int n) const {
return sharedTU[n];
}
//////////////////////////////////////////////////////////////////////
// Return current simulting time in second
//////////////////////////////////////////////////////////////////////
double TestBed::getTime() const {
return simTime;
}
//////////////////////////////////////////////////////////////////////
// Check the distance from TU to nearest BS, if the distance is less than 1 unit in agent's view,
// add FORBID_DISTANCE to it. The purpose is to avoid any TU too close to BS.
//////////////////////////////////////////////////////////////////////
void TestBed::checkMSDistance(Point &TU_loc) {
double dist, ang;
for(int i=0; i<BS_NUMBER; i++) {
// Check if the distance is less than 1 unit.
dist = TU_loc.distance( *bs[i] );
if( dist <= FORBID_DISTANCE ) {
dist += FORBID_DISTANCE;
ang = bs[i]->angle( TU_loc );
TU_loc.set( dist*cos(Point::deg2Rad(ang)) + bs[i]->getX(), dist*sin(Point::deg2Rad(ang)) + bs[i]->getY() );
// for debug
_ASSERT(TU_loc.distance( *bs[i] ) > FORBID_DISTANCE);
}
}
}
//////////////////////////////////////////////////////////////////////
// Output the macro file for gnuplot
//////////////////////////////////////////////////////////////////////
void TestBed::writeGPResult( char *FileName ){
// Declare the color number for each cluster, used for ploting TU with different color
// Note: 0-2 for different cells, and
// the 3-5 for shared users (soft handover),
// the 6 one for shared by 3 BS (softer)
// the 7 one for blocked users
// the 8 one for BS
int PtStyleNum[] = { 46, 32, 33, 45, 34, 44, 56, 23, 36}; // for windows display
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -