[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [ns] random seed for Application/Traffic
hi,
i am attaching the files for setting the random seed. you can init a RNG
object and attach it to a traffic source like this
set rng [new RNG]
$rng seed 1
set exptraffic [new Application/Traffic/Exponential]
$exptraffic attach-agent $tcpsrc
$exptraffic seed $rng
have fun,
debo
On Tue, 5 Sep 2000, Tatsuya MORI wrote:
> Debo, thank you so much for your reply.
>
> > I have modified the traffic agents to set the random seed with a RNG
> > object from the OTcl commandline. I can send you the changed expoo.cc if
> > there isnt an easier soln ....
>
> It's just what I need. Would you please send me your modified expoo.cc
> ?
>
> Best regards
>
> -- Tatsuya Mori
>
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/*
* Copyright (c) Xerox Corporation 1997. All rights reserved.
*
* License is granted to copy, to use, and to make and to use derivative
* works for research and evaluation purposes, provided that Xerox is
* acknowledged in all documentation pertaining to any such copy or derivative
* work. Xerox grants no other licenses expressed or implied. The Xerox trade
* name should not be used in any advertising without its written permission.
*
* XEROX CORPORATION MAKES NO REPRESENTATIONS CONCERNING EITHER THE
* MERCHANTABILITY OF THIS SOFTWARE OR THE SUITABILITY OF THIS SOFTWARE
* FOR ANY PARTICULAR PURPOSE. The software is provided "as is" without
* express or implied warranty of any kind.
*
* These notices must be retained in any copies of any part of this software.
*
* @(#) $Header: /usr/src/mash/repository/vint/ns-2/ranvar.h,v 1.12 1999/10/11 22:32:16 haoboy Exp $ (Xerox)
*/
#ifndef ns_ranvar_h
#define ns_ranvar_h
/* XXX still need to clean up dependencies among parameters such that
* when one parameter is changed, other parameters are recomputed as
* appropriate.
*/
#include "random.h"
#include "rng.h"
class RandomVariable : public TclObject {
public:
virtual double value() = 0;
int command(int argc, const char*const* argv);
RandomVariable();
// Debojyoti added this code .... not a part of
// Spaceway. Done for other work but used in
// some simulations
int seed(char *);
protected:
// Debojyoti Dutta added this code
RNG* rng_;
};
class UniformRandomVariable : public RandomVariable {
public:
virtual double value();
UniformRandomVariable();
UniformRandomVariable(double, double);
double* minp() { return &min_; };
double* maxp() { return &max_; };
double min() { return min_; };
double max() { return max_; };
void setmin(double d) { min_ = d; };
void setmax(double d) { max_ = d; };
private:
double min_;
double max_;
};
class ExponentialRandomVariable : public RandomVariable {
public:
virtual double value();
ExponentialRandomVariable();
ExponentialRandomVariable(double);
double* avgp() { return &avg_; };
double avg() { return avg_; };
void setavg(double d) { avg_ = d; };
private:
double avg_;
};
class ParetoRandomVariable : public RandomVariable {
public:
virtual double value();
ParetoRandomVariable();
ParetoRandomVariable(double, double);
double* avgp() { return &avg_; };
double* shapep() { return &shape_; };
double avg() { return avg_; };
double shape() { return shape_; };
void setavg(double d) { avg_ = d; };
void setshape(double d) { shape_ = d; };
private:
double avg_;
double shape_;
double scale_;
};
class ParetoIIRandomVariable : public RandomVariable {
public:
virtual double value();
ParetoIIRandomVariable();
ParetoIIRandomVariable(double, double);
double* avgp() { return &avg_; };
double* shapep() { return &shape_; };
double avg() { return avg_; };
double shape() { return shape_; };
void setavg(double d) { avg_ = d; };
void setshape(double d) { shape_ = d; };
private:
double avg_;
double shape_;
double scale_;
};
class NormalRandomVariable : public RandomVariable {
public:
virtual double value();
NormalRandomVariable();
inline double* avgp() { return &avg_; };
inline double* stdp() { return &std_; };
inline double avg() { return avg_; };
inline double std() { return std_; };
inline void setavg(double d) { avg_ = d; };
inline void setstd(double d) { std_ = d; };
private:
double avg_;
double std_;
};
class LogNormalRandomVariable : public RandomVariable {
public:
virtual double value();
LogNormalRandomVariable();
inline double* avgp() { return &avg_; };
inline double* stdp() { return &std_; };
inline double avg() { return avg_; };
inline double std() { return std_; };
inline void setavg(double d) { avg_ = d; };
inline void setstd(double d) { std_ = d; };
private:
double avg_;
double std_;
};
class ConstantRandomVariable : public RandomVariable {
public:
virtual double value();
ConstantRandomVariable();
ConstantRandomVariable(double);
double* valp() { return &val_; };
double val() { return val_; };
void setval(double d) { val_ = d; };
private:
double val_;
};
class HyperExponentialRandomVariable : public RandomVariable {
public:
virtual double value();
HyperExponentialRandomVariable();
HyperExponentialRandomVariable(double, double);
double* avgp() { return &avg_; };
double* covp() { return &cov_; };
double avg() { return avg_; };
double cov() { return cov_; };
void setavg(double d) { avg_ = d; };
void setcov(double d) { cov_ = d; };
private:
double avg_;
double cov_;
double alpha_;
};
#define INTER_DISCRETE 0 // no interpolation (discrete)
#define INTER_CONTINUOUS 1 // linear interpolation
#define INTER_INTEGRAL 2 // linear interpolation and round up
struct CDFentry {
double cdf_;
double val_;
};
class EmpiricalRandomVariable : public RandomVariable {
public:
virtual double value();
virtual double interpolate(double u, double x1, double y1, double x2, double y2);
EmpiricalRandomVariable();
double& minCDF() { return minCDF_; }
double& maxCDF() { return maxCDF_; }
protected:
int command(int argc, const char*const* argv);
int loadCDF(const char* filename);
int lookup(double u);
double minCDF_; // min value of the CDF (default to 0)
double maxCDF_; // max value of the CDF (default to 1)
int interpolation_; // how to interpolate data (INTER_DISCRETE...)
int numEntry_; // number of entries in the CDF table
int maxEntry_; // size of the CDF table (mem allocation)
CDFentry* table_; // CDF table of (val_, cdf_)
};
#endif
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/*
* Copyright (c) Xerox Corporation 1997. All rights reserved.
*
* License is granted to copy, to use, and to make and to use derivative
* works for research and evaluation purposes, provided that Xerox is
* acknowledged in all documentation pertaining to any such copy or derivative
* work. Xerox grants no other licenses expressed or implied. The Xerox trade
* name should not be used in any advertising without its written permission.
*
* XEROX CORPORATION MAKES NO REPRESENTATIONS CONCERNING EITHER THE
* MERCHANTABILITY OF THIS SOFTWARE OR THE SUITABILITY OF THIS SOFTWARE
* FOR ANY PARTICULAR PURPOSE. The software is provided "as is" without
* express or implied warranty of any kind.
*
* These notices must be retained in any copies of any part of this software.
*/
#ifndef lint
static const char rcsid[] =
"@(#) $Header: /usr/src/mash/repository/vint/ns-2/ranvar.cc,v 1.15 1999/10/11 22:32:15 haoboy Exp $ (Xerox)";
#endif
#include <stdio.h>
#include "ranvar.h"
RandomVariable::RandomVariable()
{
rng_ = RNG::defaultrng();
}
// -------------------------------------------------------
// Debojyoti added this code
// This change was done for
// a work done at USC.
int RandomVariable::seed(char *x){
Tcl& tcl = Tcl::instance();
rng_ = (RNG*)TclObject::lookup(x);
if (rng_ == 0) {
tcl.resultf("no such RNG %s", x);
return(TCL_ERROR);
}
return(TCL_OK);
}
// -------------------------------------------------------
int RandomVariable::command(int argc, const char*const* argv)
{
Tcl& tcl = Tcl::instance();
if (argc == 2) {
if (strcmp(argv[1], "value") == 0) {
tcl.resultf("%6e", value());
return(TCL_OK);
}
}
if (argc == 3) {
if (strcmp(argv[1], "use-rng") == 0) {
rng_ = (RNG*)TclObject::lookup(argv[2]);
if (rng_ == 0) {
tcl.resultf("no such RNG %s", argv[2]);
return(TCL_ERROR);
}
return(TCL_OK);
}
}
return(TclObject::command(argc, argv));
}
static class UniformRandomVariableClass : public TclClass {
public:
UniformRandomVariableClass() : TclClass("RandomVariable/Uniform"){}
TclObject* create(int, const char*const*) {
return(new UniformRandomVariable());
}
} class_uniformranvar;
UniformRandomVariable::UniformRandomVariable()
{
bind("min_", &min_);
bind("max_", &max_);
}
UniformRandomVariable::UniformRandomVariable(double min, double max)
{
min_ = min;
max_ = max;
}
double UniformRandomVariable::value()
{
return(rng_->uniform(min_, max_));
}
static class ExponentialRandomVariableClass : public TclClass {
public:
ExponentialRandomVariableClass() : TclClass("RandomVariable/Exponential") {}
TclObject* create(int, const char*const*) {
return(new ExponentialRandomVariable());
}
} class_exponentialranvar;
ExponentialRandomVariable::ExponentialRandomVariable()
{
bind("avg_", &avg_);
}
ExponentialRandomVariable::ExponentialRandomVariable(double avg)
{
avg_ = avg;
}
double ExponentialRandomVariable::value()
{
return(rng_->exponential(avg_));
}
static class ParetoRandomVariableClass : public TclClass {
public:
ParetoRandomVariableClass() : TclClass("RandomVariable/Pareto") {}
TclObject* create(int, const char*const*) {
return(new ParetoRandomVariable());
}
} class_paretoranvar;
ParetoRandomVariable::ParetoRandomVariable()
{
bind("avg_", &avg_);
bind("shape_", &shape_);
}
ParetoRandomVariable::ParetoRandomVariable(double avg, double shape)
{
avg_ = avg;
shape_ = shape;
}
double ParetoRandomVariable::value()
{
/* yuck, user wants to specify shape and avg, but the
* computation here is simpler if we know the 'scale'
* parameter. right thing is to probably do away with
* the use of 'bind' and provide an API such that we
* can update the scale everytime the user updates shape
* or avg.
*/
return(rng_->pareto(avg_ * (shape_ -1)/shape_, shape_));
}
/* Pareto distribution of the second kind, aka. Lomax distribution */
static class ParetoIIRandomVariableClass : public TclClass {
public:
ParetoIIRandomVariableClass() : TclClass("RandomVariable/ParetoII") {}
TclObject* create(int, const char*const*) {
return(new ParetoIIRandomVariable());
}
} class_paretoIIranvar;
ParetoIIRandomVariable::ParetoIIRandomVariable()
{
bind("avg_", &avg_);
bind("shape_", &shape_);
}
ParetoIIRandomVariable::ParetoIIRandomVariable(double avg, double shape)
{
avg_ = avg;
shape_ = shape;
}
double ParetoIIRandomVariable::value()
{
return(rng_->paretoII(avg_ * (shape_ - 1), shape_));
}
static class NormalRandomVariableClass : public TclClass {
public:
NormalRandomVariableClass() : TclClass("RandomVariable/Normal") {}
TclObject* create(int, const char*const*) {
return(new NormalRandomVariable());
}
} class_normalranvar;
NormalRandomVariable::NormalRandomVariable()
{
bind("avg_", &avg_);
bind("std_", &std_);
}
double NormalRandomVariable::value()
{
return(rng_->normal(avg_, std_));
}
static class LogNormalRandomVariableClass : public TclClass {
public:
LogNormalRandomVariableClass() : TclClass("RandomVariable/LogNormal") {}
TclObject* create(int, const char*const*) {
return(new LogNormalRandomVariable());
}
} class_lognormalranvar;
LogNormalRandomVariable::LogNormalRandomVariable()
{
bind("avg_", &avg_);
bind("std_", &std_);
}
double LogNormalRandomVariable::value()
{
return(rng_->lognormal(avg_, std_));
}
static class ConstantRandomVariableClass : public TclClass {
public:
ConstantRandomVariableClass() : TclClass("RandomVariable/Constant"){}
TclObject* create(int, const char*const*) {
return(new ConstantRandomVariable());
}
} class_constantranvar;
ConstantRandomVariable::ConstantRandomVariable()
{
bind("val_", &val_);
}
ConstantRandomVariable::ConstantRandomVariable(double val)
{
val_ = val;
}
double ConstantRandomVariable::value()
{
return(val_);
}
/* Hyperexponential distribution code adapted from code provided
* by Ion Stoica.
*/
static class HyperExponentialRandomVariableClass : public TclClass {
public:
HyperExponentialRandomVariableClass() :
TclClass("RandomVariable/HyperExponential") {}
TclObject* create(int, const char*const*) {
return(new HyperExponentialRandomVariable());
}
} class_hyperexponentialranvar;
HyperExponentialRandomVariable::HyperExponentialRandomVariable()
{
bind("avg_", &avg_);
bind("cov_", &cov_);
alpha_ = .95;
}
HyperExponentialRandomVariable::HyperExponentialRandomVariable(double avg, double cov)
{
alpha_ = .95;
avg_ = avg;
cov_ = cov;
}
double HyperExponentialRandomVariable::value()
{
double temp, res;
double u = Random::uniform();
temp = sqrt((cov_ * cov_ - 1.0)/(2.0 * alpha_ * (1.0 - alpha_)));
if (u < alpha_)
res = Random::exponential(avg_ - temp * (1.0 - alpha_) * avg_);
else
res = Random::exponential(avg_ + temp * (alpha_) * avg_);
return(res);
}
/*
// Empirical Random Variable:
// CDF input from file with the following column
// 1. Possible values in a distrubutions
// 2. Number of occurances for those values
// 3. The CDF for those value
// code provided by Giao Nguyen
*/
static class EmpiricalRandomVariableClass : public TclClass {
public:
EmpiricalRandomVariableClass() : TclClass("RandomVariable/Empirical"){}
TclObject* create(int, const char*const*) {
return(new EmpiricalRandomVariable());
}
} class_empiricalranvar;
EmpiricalRandomVariable::EmpiricalRandomVariable() : minCDF_(0), maxCDF_(1), maxEntry_(32), table_(0)
{
bind("minCDF_", &minCDF_);
bind("maxCDF_", &maxCDF_);
bind("interpolation_", &interpolation_);
bind("maxEntry_", &maxEntry_);
}
int EmpiricalRandomVariable::command(int argc, const char*const* argv)
{
Tcl& tcl = Tcl::instance();
if (argc == 3) {
if (strcmp(argv[1], "loadCDF") == 0) {
if (loadCDF(argv[2]) == 0) {
tcl.resultf("%s loadCDF %s: invalid file",
name(), argv[2]);
return (TCL_ERROR);
}
return (TCL_OK);
}
}
return RandomVariable::command(argc, argv);
}
int EmpiricalRandomVariable::loadCDF(const char* filename)
{
FILE* fp;
char line[256];
CDFentry* e;
fp = fopen(filename, "r");
if (fp == 0)
return 0;
if (table_ == 0)
table_ = new CDFentry[maxEntry_];
for (numEntry_=0; fgets(line, 256, fp); numEntry_++) {
if (numEntry_ >= maxEntry_) { // resize the CDF table
maxEntry_ *= 2;
e = new CDFentry[maxEntry_];
for (int i=numEntry_-1; i >= 0; i--)
e[i] = table_[i];
delete table_;
table_ = e;
}
e = &table_[numEntry_];
// Use * and l together raises a warning
sscanf(line, "%lf %*f %lf", &e->val_, &e->cdf_);
}
return numEntry_;
}
double EmpiricalRandomVariable::value()
{
if (numEntry_ <= 0)
return 0;
double u = rng_->uniform(minCDF_, maxCDF_);
int mid = lookup(u);
if (mid && interpolation_ && u < table_[mid].cdf_)
return interpolate(u, table_[mid-1].cdf_, table_[mid-1].val_,
table_[mid].cdf_, table_[mid].val_);
return table_[mid].val_;
}
double EmpiricalRandomVariable::interpolate(double x, double x1, double y1, double x2, double y2)
{
double value = y1 + (x - x1) * (y2 - y1) / (x2 - x1);
if (interpolation_ == INTER_INTEGRAL) // round up
return ceil(value);
return value;
}
int EmpiricalRandomVariable::lookup(double u)
{
// always return an index whose value is >= u
int lo, hi, mid;
if (u <= table_[0].cdf_)
return 0;
for (lo=1, hi=numEntry_-1; lo < hi; ) {
mid = (lo + hi) / 2;
if (u > table_[mid].cdf_)
lo = mid + 1;
else hi = mid;
}
return lo;
}
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
/*
* Copyright (c) Xerox Corporation 1997. All rights reserved.
*
* License is granted to copy, to use, and to make and to use derivative
* works for research and evaluation purposes, provided that Xerox is
* acknowledged in all documentation pertaining to any such copy or derivative
* work. Xerox grants no other licenses expressed or implied. The Xerox trade
* name should not be used in any advertising without its written permission.
*
* XEROX CORPORATION MAKES NO REPRESENTATIONS CONCERNING EITHER THE
* MERCHANTABILITY OF THIS SOFTWARE OR THE SUITABILITY OF THIS SOFTWARE
* FOR ANY PARTICULAR PURPOSE. The software is provided "as is" without
* express or implied warranty of any kind.
*
* These notices must be retained in any copies of any part of this software.
*/
#ifndef lint
static const char rcsid[] =
"@(#) $Header: /usr/src/mash/repository/vint/ns-2/expoo.cc,v 1.10 1999/07/01 00:08:18 tomh Exp $ (Xerox)";
#endif
#include <stdlib.h>
#include "random.h"
#include "trafgen.h"
#include "ranvar.h"
// Debojyoti's modifications
#include "string.h"
#include "app.h"
/* implement an on/off source with exponentially distributed on and
* off times. parameterized by average burst time, average idle time,
* burst rate and packet size.
*/
class EXPOO_Traffic : public TrafficGenerator {
public:
EXPOO_Traffic();
virtual double next_interval(int&);
virtual void timeout();
// Debojyoti
int command(int argc, const char*const* argv);
protected:
void init();
double ontime_; /* average length of burst (sec) */
double offtime_; /* average length of idle time (sec) */
double rate_; /* send rate during on time (bps) */
double interval_; /* packet inter-arrival time during burst (sec) */
unsigned int rem_; /* number of packets left in current burst */
/* new stuff using RandomVariable */
ExponentialRandomVariable burstlen_;
ExponentialRandomVariable Offtime_;
};
static class EXPTrafficClass : public TclClass {
public:
EXPTrafficClass() : TclClass("Application/Traffic/Exponential") {}
TclObject* create(int, const char*const*) {
return (new EXPOO_Traffic());
}
} class_expoo_traffic;
// ------------------------------------------------------------
// Added by Debojyoti
// This is to seed the random number generator
// Used this to do some simulations
int EXPOO_Traffic::command(int argc, const char*const* argv){
if(argc==3){
if (strcmp(argv[1], "seed") == 0) {
int seed = atoi(argv[2]);
burstlen_.seed(argv[2]);
Offtime_.seed(argv[2]);
return (TCL_OK);
}
}
return Application::command(argc,argv);
}
// -------------------------------------------------------------
EXPOO_Traffic::EXPOO_Traffic() : burstlen_(0.0), Offtime_(0.0)
{
bind_time("burst_time_", &ontime_);
bind_time("idle_time_", Offtime_.avgp());
bind_bw("rate_", &rate_);
bind("packetSize_", &size_);
}
void EXPOO_Traffic::init()
{
/* compute inter-packet interval during bursts based on
* packet size and burst rate. then compute average number
* of packets in a burst.
*/
interval_ = (double)(size_ << 3)/(double)rate_;
burstlen_.setavg(ontime_/interval_);
rem_ = 0;
if (agent_)
agent_->set_pkttype(PT_EXP);
}
double EXPOO_Traffic::next_interval(int& size)
{
double t = interval_;
if (rem_ == 0) {
/* compute number of packets in next burst */
rem_ = int(burstlen_.value() + .5);
/* make sure we got at least 1 */
if (rem_ == 0)
rem_ = 1;
/* start of an idle period, compute idle time */
t += Offtime_.value();
}
rem_--;
size = size_;
return(t);
}
void EXPOO_Traffic::timeout()
{
if (! running_)
return;
/* send a packet */
// The test tcl/ex/test-rcvr.tcl relies on the "NEW_BURST" flag being
// set at the start of any exponential burst ("talkspurt").
if (nextPkttime_ != interval_ || nextPkttime_ == -1)
agent_->sendmsg(size_, "NEW_BURST");
else
agent_->sendmsg(size_);
/* figure out when to send the next one */
nextPkttime_ = next_interval(size_);
/* schedule it */
if (nextPkttime_ > 0)
timer_.resched(nextPkttime_);
}