⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 testbed.cpp

📁 Bubble Oscillation Algorithm. It is used to implement balancing load traffic, which is similar to wh
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//////////////////////////////////////////////////////////////////////
//  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 + -