asim.cc
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:22k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /*
  2.  * asim.cc
  3.  * Copyright (C) 2000 by the University of Southern California
  4.  * $Id: asim.cc,v 1.11 2005/08/25 18:58:01 johnh Exp $
  5.  *
  6.  * This program is free software; you can redistribute it and/or
  7.  * modify it under the terms of the GNU General Public License,
  8.  * version 2, as published by the Free Software Foundation.
  9.  *
  10.  * This program is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  * GNU General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU General Public License along
  16.  * with this program; if not, write to the Free Software Foundation, Inc.,
  17.  * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
  18.  *
  19.  *
  20.  * The copyright of this module includes the following
  21.  * linking-with-specific-other-licenses addition:
  22.  *
  23.  * In addition, as a special exception, the copyright holders of
  24.  * this module give you permission to combine (via static or
  25.  * dynamic linking) this module with free software programs or
  26.  * libraries that are released under the GNU LGPL and with code
  27.  * included in the standard release of ns-2 under the Apache 2.0
  28.  * license or under otherwise-compatible licenses with advertising
  29.  * requirements (or modified versions of such code, with unchanged
  30.  * license).  You may copy and distribute such a system following the
  31.  * terms of the GNU GPL for this module and the licenses of the
  32.  * other code concerned, provided that you include the source code of
  33.  * that other code when and as the GNU GPL requires distribution of
  34.  * source code.
  35.  *
  36.  * Note that people who make modified versions of this module
  37.  * are not obligated to grant this special exception for their
  38.  * modified versions; it is their choice whether to do so.  The GNU
  39.  * General Public License gives permission to release a modified
  40.  * version without this exception; this exception also makes it
  41.  * possible to release a modified version which carries forward this
  42.  * exception.
  43.  *
  44.  */
  45. #include "config.h"
  46. #include <math.h>
  47. #include <stdio.h>
  48. #include <stdlib.h>
  49. #include <string.h>
  50. #include <strings.h>
  51. #include <assert.h>
  52. #include <iostream>
  53. #include "agent.h"
  54. // Integration of Ashish's RED and asim
  55. #define _RED_ROUTER_MAIN_
  56. #include "asim.h"
  57. #define sp " " 
  58. typedef struct c{
  59.   int no; // no of edges in the connection
  60.   double delay; // total delay;
  61.   double drop; // total drop prob
  62.   double p_tput;
  63.   double t;
  64.   // The short flow stuff
  65.   int is_sflow; // boolean to indicate whether there is a short flow
  66.   double slambda; // The arrival rate of the connections
  67.   int snopkts; // average of no of packets each short flow givies
  68.   RedRouter * red;
  69.   int scaled; // Whether this flow has been scaled or not
  70. }flow_stats;
  71. typedef struct n{
  72.   int red; // flag to notify whether its a red queue or not
  73.   double pmin, pmax, minth, maxth; // RED parameters
  74.   double lambda; // Arrival rate - Packets per second
  75.   double plambda; // Temp lambda value. previous lambda
  76.   double tlambda;
  77.   double mu; // Consumption rate - Packets per second
  78.   double prop; // Propagation delay of the link
  79.   double qdelay; // Store the queuing delay for each link
  80.   int    buffer; // Total buffer
  81.   double drop; // probability of drop
  82.   int nflows; // Number of flows through this link
  83.   int *theflows; // The flows through this link
  84.   double scaled_lambda;
  85.   double unscaled_lambda;
  86.   double utput; // unscaled tput 
  87.   double uc; // unscaled capacity
  88.   // For ashish
  89.   RedRouter * redrouter;
  90. }link_stats;
  91. class asim : public NsObject{
  92. public:
  93.   // data structures 
  94.   int nConnections; // Number of connections
  95.   int K, MaxHops; // 
  96.   int nLinks; // Number of links 
  97.   int **Adj; // Stores the edge list of each connection
  98.   int *nAdj; // Stores the no of edges per connection
  99.   
  100.   link_stats* links;
  101.   flow_stats* flows;
  102.   
  103.   double min(double x, double y){
  104.     return (x<y)?x:y;
  105.   }
  106.   double padhye(double rtt, double p){
  107.     
  108.     double rto = 1;
  109.     double t=1;
  110.     t = rtt*sqrt(2*p/3)+rto*min(1,(3*sqrt(3*p/8)))*p*(1+32*p*p);
  111.     return min(20/rtt,1/t);
  112.     
  113.   }
  114.   
  115.   double Po(double rho, int K){
  116.     
  117.     if(rho==1)
  118.       return 1.0/(K+1);
  119.     
  120.     double t;
  121.     t=(1.0*(1-rho))/(1.0-pow(rho,K));
  122.     return t;
  123.     
  124.   }
  125.   double Pk(double rho, int K, int k){
  126.     
  127.     if(rho==1)
  128.       return 1.0/(K+1);
  129.     
  130.     double t;
  131.     t=(1-rho)*pow(rho,k);
  132.     t/=1-pow(rho,K+1);
  133.     return t;
  134.   }  
  135.   double Lq(double rho, int K){
  136.     double t1,t2;
  137.     
  138.     if(rho==1){
  139.       return (1.0*K*(K-1))/(2.0*(K+1));
  140.     }
  141.     
  142.     t1=rho*1.0/(1-rho);
  143.     t2=rho*1.0/(1-pow(rho,K+1));
  144.     t2*=K*pow(rho,K)+1;
  145.     return (t1-t2)/2;
  146.     
  147.   }
  148.   
  149.   int command (int argc, const char*const* argv){
  150.     if (strcmp(argv[1], "run") == 0) {
  151.       int niter=0;
  152.       for(int i=0; i<20; i++){
  153. CalcLinkDelays(1);
  154. CalcPerFlowDelays();
  155. newupdate(niter);
  156.       }
  157.       //PrintResults();  
  158.       return (TCL_OK);
  159.     }
  160.     
  161.     if (strcmp(argv[1], "readinput") == 0) {
  162.       GetInputs((char*)argv[2]);
  163.       //cout << "All inputs properly obtained from " << argv[2] <<endl ; 
  164.       return (TCL_OK);
  165.     }
  166.     if (strcmp(argv[1], "get-link-drop") == 0) {
  167.       cout << "Hi";
  168.       Tcl& tcl = Tcl::instance();
  169.       tcl.resultf("%lf",get_link_drop(atoi(argv[2])));
  170.       return (TCL_OK);
  171.     }
  172.     if (strcmp(argv[1], "get-link-delay") == 0) {
  173.       Tcl& tcl = Tcl::instance();
  174.       tcl.resultf("%lf",get_link_delay(atoi(argv[2])));
  175.       return (TCL_OK);
  176.     }  
  177.     if (strcmp(argv[1], "get-link-tput") == 0) {
  178.       Tcl& tcl = Tcl::instance();
  179.       tcl.resultf("%lf",get_link_tput(atoi(argv[2])));
  180.       return (TCL_OK);
  181.     }  
  182.     if (strcmp(argv[1], "get-flow-tput") == 0) {
  183.       Tcl& tcl = Tcl::instance();
  184.       tcl.resultf("%lf",get_flow_tput(atoi(argv[2])));
  185.       return (TCL_OK);
  186.     }
  187.     if (strcmp(argv[1], "get-flow-delay") == 0) {
  188.       Tcl& tcl = Tcl::instance();
  189.       tcl.resultf("%lf",get_flow_delay(atoi(argv[2])));
  190.       return (TCL_OK);
  191.     }      
  192.     if (strcmp(argv[1], "get-flow-drop") == 0) {
  193.       Tcl& tcl = Tcl::instance();
  194.       tcl.resultf("%lf",get_flow_drop(atoi(argv[2])));
  195.       return (TCL_OK);
  196.     }
  197. return 0;
  198.   }
  199.   
  200.   double get_link_drop(int x){
  201.     assert(x<nLinks);
  202.     return links[x].drop;
  203.   }
  204.   double get_link_delay(int x){
  205.     assert(x<nLinks);
  206.     return links[x].qdelay + links[x].prop ;
  207.   }
  208.   double get_link_qdelay(int x){
  209.     assert(x<nLinks);
  210.     return links[x].qdelay;
  211.   }
  212.   double get_link_pdelay(int x){
  213.     assert(x<nLinks);
  214.     return links[x].prop;
  215.   }
  216.   double get_link_tput(int x){
  217.     assert(x<nLinks);
  218.     return links[x].lambda;
  219.   }
  220.   double get_flow_delay(int x){
  221.     assert(x<nConnections);
  222.     return flows[x].delay;
  223.   }
  224.   double get_flow_tput(int x){
  225.     assert(x<nConnections);
  226.     return flows[x].p_tput;
  227.   }
  228.   double get_flow_drop(int x){
  229.     assert(x<nConnections);
  230.     return flows[x].drop;
  231.   }
  232.   void GetInputs(char *argv) {
  233.     
  234.     // error if usage is wrong 
  235.     /*    
  236.     if (argc != 2) {
  237.       fprintf(stderr,"Usage: %s  <InputFile>n", argv[0]);
  238.       exit(-1); 
  239.       }*/
  240.     
  241.   // No error 
  242.   MaxHops = 0;
  243.   // K = atoi(argv[1]);
  244.   // assert(K >= 1);
  245.   // Init links and connections 
  246.   nConnections = 0;
  247.   nLinks = 0;
  248.   // Start the reading process
  249.   FILE *f;
  250.   f = fopen(argv,"r");
  251.   assert(f);
  252.   char s[256];
  253.   while (fgets(s, 255, f)) {
  254.     // Read a token 
  255.     char *t;
  256.     t = strtok(s, " tn");
  257.     // Ignore comments 
  258.     if (!t || !t[0] || (t[0] == '#') || !strncasecmp(t, "comment", 6))
  259.       continue;
  260.     
  261.     // Define the number of connections
  262.     if (!strcasecmp(t,"n")) {
  263.       t = strtok(NULL," t");
  264.       assert(t);
  265.       nConnections = atoi(t);
  266.       assert(nConnections > 0);
  267.       assert(nConnections >= 0);
  268.       nAdj = new int[nConnections];
  269.       Adj = new int*[nConnections];
  270.       flows = new flow_stats[nConnections];
  271.       for (int i=0; i<nConnections; ++i)
  272. nAdj[i] = -1;
  273.       continue;
  274.     }
  275.     // Define the number of links
  276.     else if (!strcasecmp(t,"m")) {
  277.       t = strtok(NULL," t");
  278.       assert(t);
  279.       // #of links defined
  280.       nLinks = atoi(t);
  281.       assert(nLinks > 0);
  282.       // Allocate space for sotring lambdas and mus
  283.       links = new link_stats[nLinks];
  284.       continue;
  285.     }
  286.     // Enter each route 
  287.     else if (!strcasecmp(t,"route")) {
  288.       assert (nConnections > 0);
  289.       assert (nLinks > 0);
  290.       t = strtok(NULL," t");
  291.       assert(t);
  292.       int i = atoi(t);
  293.       assert(i > 0 && i<= nConnections);
  294.       i--;
  295.  
  296.      // We dunno whether this will be short flow specs
  297.       flows[i].is_sflow = 0; // Lets assume its a normal flow
  298.       flows[i].drop = 0; // Assume ideal case to start off
  299.       flows[i].scaled = 0; // Not scaled as yet
  300.       t = strtok(NULL," t");
  301.       assert(t);
  302.       nAdj[i] = atoi(t);
  303.       assert(nAdj[i] > 0 && nAdj[i] <= nLinks);
  304.       Adj[i] = new int[nAdj[i]];
  305.       for (int j=0; j<nAdj[i]; ++j) {
  306. t = strtok(NULL," t");
  307. assert(t);
  308. int l = atoi(t);
  309. assert(l > 0 && l <= nLinks);
  310. l--;
  311. Adj[i][j] = l;
  312.       }
  313.       if (MaxHops < nAdj[i]) MaxHops = nAdj[i];
  314.       
  315.       t = strtok(NULL," t");
  316.       // assert(t);
  317.     
  318.       // Short flows stuff 
  319.       if (t && !strcasecmp(t,"sh")) {
  320. // There are short flows on this route.
  321. flows[i].is_sflow = 1;
  322.       
  323. // read the slambda
  324. t = strtok(NULL," t");
  325. assert(t);
  326. double  tmp = atof(t);
  327. flows[i].slambda = tmp;
  328. // read the snopkts
  329. t = strtok(NULL," t");
  330. assert(t);
  331. int  tmpi = atoi(t);
  332. flows[i].snopkts = tmpi;
  333.       }
  334.       
  335.       continue;
  336.     }
  337.     else if(!strcasecmp(t,"link")){
  338.       assert (nLinks > 0);
  339.       // Get the link number
  340.       t = strtok(NULL," t");
  341.       assert(t);
  342.       int i = atoi(t);
  343.       assert(i > 0 && i<= nLinks);
  344.       i--;
  345.       // Get the prop delay
  346.       t = strtok(NULL," t");
  347.       assert(t);
  348.       double p = atof(t);
  349.       assert(p>=0); 
  350.       links[i].prop = p;
  351.       // Get the lambda for this link
  352.       t = strtok(NULL," t");
  353.       assert(t);
  354.       p = atof(t);
  355.       assert(p>=0);
  356.       links[i].lambda = 0;
  357.       links[i].tlambda = p;
  358.       links[i].plambda = p;
  359.       // Get the mu for this link
  360.       t = strtok(NULL," t");
  361.       assert(t);
  362.       p = atof(t);
  363.       assert(p>=0);
  364.       links[i].mu = p;
  365.       // Get the buffer for this link
  366.       t = strtok(NULL," t");
  367.       assert(t);
  368.       int t1 = atoi(t);
  369.       assert(t1>0);
  370.       links[i].buffer = t1;
  371.       // Check for RED Q or not
  372.       t = strtok(NULL," t");
  373.       if(t && !strcasecmp(t,"red")){
  374. // must be a red queue
  375. // input red parameters
  376. // all parameters between 0 and 1
  377. links[i].red=1;
  378. // get minth
  379. t = strtok(NULL," t");
  380. double dt = atof(t); 
  381. //assert(dt>=0 && dt<=1);
  382. links[i].minth=dt;
  383. // get pmin
  384. t = strtok(NULL," t");
  385. dt = atof(t); 
  386. //assert(dt>=0 && dt<=1);
  387. links[i].pmin=dt;
  388. // get maxth
  389. t = strtok(NULL," t");
  390. dt = atof(t); 
  391. //assert(dt>=0 && dt<=1);
  392. links[i].maxth=dt;
  393. // get pmax
  394. t = strtok(NULL," t");
  395. dt = atof(t); 
  396. //assert(dt>=0 && dt<=1);
  397. links[i].pmax=dt;
  398. // Invoke Ashish's RED module ... ignore pmin .....
  399. links[i].redrouter = new RedRouter((int)links[i].minth, 
  400.    (int)links[i].maxth,
  401.    links[i].pmax);
  402. assert(links[i].red);
  403.       }
  404.       else{
  405. links[i].red=0;
  406.       }
  407.       continue;
  408.     }
  409.     assert(0);
  410.   }
  411.   // Check whether everything is all right 
  412.   assert (nConnections > 0);
  413.   assert (nLinks > 0);
  414.   int i;
  415.   for (i=0; i<nConnections; ++i)
  416.     assert(nAdj[i] > 0);
  417.   
  418.   // check all the edges and store all the connections that flow 
  419.   // through a particular link
  420.   
  421.   for(i=0;i<nLinks;i++){
  422.     //    cout << i << sp;
  423.     int c=0; links[i].tlambda=0;
  424.     for(int j=0;j<nConnections;j++){
  425.       for(int k=0;k<nAdj[j];k++){
  426. if(Adj[j][k]==i){
  427.   c++;
  428. }
  429.       }
  430.     }
  431.     links[i].nflows=c;
  432.     //cout << c << sp;
  433.     if(c){
  434.       links[i].theflows = new int[c];
  435.       c = 0;
  436.       // Store teh flows
  437.       for(int j=0;j<nConnections;j++){
  438. for(int k=0;k<nAdj[j];k++){
  439.   if(Adj[j][k]==i){
  440.     if(flows[j].is_sflow){
  441.       links[i].lambda+=flows[j].slambda*flows[j].snopkts;
  442.     }
  443.     links[i].theflows[c++]=j;
  444.     //     cout << links[i].theflows[c-1] << sp;
  445.   }
  446. }
  447.       }
  448.       // cout << " slambda = " << links[i].lambda;
  449.     }
  450.     else links[i].theflows = 0; // no connection passing through this edge
  451.     //cout << endl;
  452.   }
  453.   /*
  454.   char c= getchar();
  455.   for(int i=0;i<nConnections;i++){
  456.     cout << "connection" << sp << i << sp << "-"; 
  457.     for(int j=0;j<nAdj[i];j++){
  458.       cout << sp << Adj[i][j];
  459.     }
  460.     cout << endl;
  461.   }
  462.   */
  463.   
  464. }
  465. double redFn(double minth, double pmin,
  466.      double maxth, double pmax, double qlength){
  467.   assert(qlength>=0 && qlength<=1);
  468.   assert(pmax>=0 && pmax<=1);
  469.   assert(pmin>=0 && pmin<=1);
  470.   assert(minth>=0 && minth<=1);
  471.   assert(maxth>=0 && maxth<=1);
  472.   assert(maxth>=minth);
  473.   assert(pmax>pmin);
  474.   //Double t;
  475.   if(qlength<minth)
  476.     return 0;
  477.   if(qlength>maxth)
  478.     return 1;
  479.   return pmin + (qlength-minth)/(pmax-pmin);
  480. }
  481. void  CalcLinkDelays(int flag = 0){
  482.   // flag = 1 means enable RED
  483.   // Calculate Link delays ... basically queuing delays
  484.   for(int i=0; i<nLinks; i++){
  485.     double rho = links[i].lambda/links[i].mu;
  486.     double qlength = Lq(rho,links[i].buffer);
  487.     links[i].qdelay = qlength/links[i].mu; 
  488.     links[i].drop = Pk(rho,links[i].buffer,links[i].buffer);
  489. //cout << "rho = " << rho << " drop = " << links[i].drop << endl;
  490.     // Special code for RED gateways
  491.     if(flag){
  492.       if(links[i].red){
  493. double minth, maxth, pmin, pmax, delay,p;
  494. minth = links[i].minth;
  495. maxth = links[i].maxth;
  496. pmin = links[i].pmin;
  497. pmax = links[i].pmax;
  498. /* Debo's RED approx
  499. links[i].drop = redFn(minth,pmin,maxth,pmax,qlength/links[i].buffer);
  500. qlength = (1-links[i].drop)*links[i].buffer;
  501. links[i].qdelay = qlength/links[i].mu; 
  502. */
  503. // Ashish's RED approx.
  504. p=(links[i].redrouter)->ComputeProbability(rho, delay);
  505. links[i].drop = p;
  506. qlength = Lq(rho*(1-p), links[i].buffer);
  507. links[i].qdelay = delay;
  508.       }
  509.     }
  510.     //cout << "delay = " << links[i].qdelay << " and drop = " << links[i].drop << endl;
  511.   }
  512. }
  513. void CalcPerFlowDelays(){
  514.   for(int i=0; i<nConnections; i++){
  515.     double d = 0, p = 1 ;
  516.     // Calculate drops and delays
  517.     for(int j=0;j<nAdj[i];j++){
  518.       d += 2*links[Adj[i][j]].prop + links[Adj[i][j]].qdelay;
  519.       p *= 1-links[Adj[i][j]].drop;
  520.     }
  521.     p = 1-p;
  522.     flows[i].no = nAdj[i];
  523.     flows[i].delay = d;
  524.     flows[i].drop = p;
  525.     flows[i].t = flows[i].p_tput;    
  526.     // p is the end2end drop prob
  527.     // If its normal flow, calculate Padhye's stuff
  528.     // If its short flow, use our approximations
  529.     // Nothing more
  530.     
  531.     if(flows[i].is_sflow){
  532.       // If k flows come and each each flow has n packets to 
  533.       // send then 
  534.       double t = (flows[i].slambda*flows[i].snopkts);
  535.       flows[i].p_tput = t/(1-p);
  536.     }
  537.     else{
  538.       // regular bulk TCP connections, Padhye et. al.
  539.       if(!p){
  540. // cout << "Oops, something wrong";
  541.       }
  542.       flows[i].p_tput = padhye(d,p);
  543.     }
  544.     //    cout << "connection " << sp << i << sp << d << sp << p; 
  545.     //cout << sp << flows[i].p_tput << endl;
  546.    
  547.   }
  548. }
  549. void PrintData(){
  550.   for(int i=0;i<nLinks;i++){
  551.     cout << i << sp << links[i].lambda << sp << links[i].mu;
  552.     cout << sp << links[i].buffer << endl;
  553.   }
  554. }
  555. void PrintResults(){
  556.   int i;
  557.   for(i=0;i<nLinks;i++){
  558.     // cout << i << sp << links[i].qdelay << sp << links[i].drop;
  559.     cout << sp << "Qdelay = " << links[i].prop << sp << links[i].lambda;
  560.     cout << sp << links[i].drop << endl;
  561.   }
  562.   for(i=0; i<nConnections; i++){
  563.     cout << i << sp << flows[i].delay << sp;
  564.     cout << flows[i].drop << sp << flows[i].p_tput << sp;
  565.     cout << sp <<  endl;
  566.   }
  567. }
  568. void UpdateHelper(int flag=0){
  569.   // if flag = 1 then update only when link is unscaled as of now
  570.   // if flag = 0 then do the usual update 
  571.   int i;
  572.   for(i=0; i<nLinks; i++){
  573.     links[i].tlambda=0;
  574.   }
  575.   for(i=0; i<nConnections; i++){
  576.     if(!flag || !flows[i].scaled) 
  577.       for(int j=0;j<nAdj[i];j++)
  578. links[Adj[i][j]].tlambda += flows[i].p_tput;
  579.     //    cout << flows[i].p_tput << "n";
  580.   }
  581. }
  582. void Update(int niter){
  583.   UpdateHelper();
  584.   for(int i=0; i<nLinks; i++){
  585.     links[i].plambda = links[i].lambda;
  586.     double t;
  587.     double tk=links[i].mu*(1.1);
  588.     
  589.     if(niter){
  590.       if(links[i].tlambda>tk)
  591. //t = pow((sqrt(links[i].lambda)+sqrt(links[i].mu+5))/2,2);
  592. t = ((links[i].lambda)+tk)/2;
  593.       // t = exp((log(links[i].lambda)+log(links[i].mu+5))/2);
  594.       else
  595. //t = pow((sqrt(links[i].tlambda)+sqrt(links[i].lambda))/2,2);
  596. t= ((links[i].tlambda)+(links[i].lambda))/2;
  597.       // t = exp((log(links[i].tlambda)+log(links[i].lambda))/2);
  598.     }
  599.     else t = links[i].tlambda;
  600.     links[i].lambda = t; // Update the lambda ..........
  601.   }
  602. }  
  603. void Update2(){
  604.   UpdateHelper();
  605.   for(int i=0; i<nLinks; i++){
  606.     links[i].plambda = links[i].lambda;
  607.     links[i].lambda = (links[i].lambda + links[i].tlambda)/2;
  608.   }
  609. }
  610. int allscaled(){
  611.   //cout << nConnections;
  612.   for(int i=0; i<nConnections; i++)
  613.     if(!flows[i].is_sflow && !flows[i].scaled){
  614.       cout << "Connection " << i << " not scaled as yetn";
  615.       return 0;
  616.     }
  617.   //cout << "All are scaledn";
  618.   return 1;
  619. }
  620.   
  621. void Update3(int flag = 0){
  622. // flag = 1 means dont touch short flows in your scaling algo
  623.   double maxtlambda = -1e7;
  624.   int bneck = -1;
  625.   int i;
  626.   // 1st get set scaled var of all flows to 0
  627.   for(i=0; i<nConnections; i++)
  628.     flows[i].scaled = 0;
  629.   // Calculate the tlambdas
  630.   UpdateHelper();
  631.   // Find out the link with the max throughput
  632.   for(i=0; i<nLinks; i++){
  633.     //cout << "after updatehelper link #" << i << " " << links[i].tlambda << "n";
  634.     if(links[i].tlambda>maxtlambda){
  635.       bneck = i;
  636.       maxtlambda = links[i].tlambda;
  637.     }
  638.   }
  639.   cout << "bottleneck = " << bneck << sp << maxtlambda <<endl;
  640.   double tk = links[bneck].mu*(1+links[bneck].drop)+5; 
  641.   // We cant go above this tk ......
  642.   while((maxtlambda > tk + 1) && ! allscaled()){
  643.     cout << "Maxtlambda = " << maxtlambda << " bneck = " << bneck << endl;
  644.     //    cout << "tk =  "<< tk << " maxlambda = " << maxtlambda << endl;
  645.     // Now lets reduce this to tk
  646.     assert(bneck>=0 && bneck<=nLinks);
  647.     int i;
  648.     for(i=0; i<links[bneck].nflows; i++){
  649.  
  650.      // For all the connections passing through this link
  651.       int t = links[bneck].theflows[i]; // get a connection id
  652.       // Now reduce its p_tput iff its not a short flow
  653.       // For short flows we dont do scaling
  654.       if(flag){
  655. if(!flows[t].is_sflow && !flows[t].scaled){
  656.   flows[t].p_tput *= (tk)/maxtlambda;
  657.   //cout << "Flow " << t << " getting scaled to  << " << flows[t].p_tput <<" n";
  658.   flows[t].scaled = 1; // we have scaled this flow already
  659. }
  660.       }
  661.       else
  662. flows[t].p_tput *= (tk)/maxtlambda;
  663.       flows[t].scaled = 1; // we have scaled this flow already 
  664.     }
  665.     for (i=0; i<nLinks;i++){
  666.       cout << "Link " << i << " tlambda = " << links[i].tlambda << endl;
  667.     }
  668.     //Char x =getchar();
  669.     // Recalculate the flows' stats
  670.     UpdateHelper(0);
  671.     // Find out the link with the max throughput
  672.     bneck = -1;
  673.     maxtlambda = -1e7;
  674.     for(i=0; i<nLinks; i++){
  675.       if(links[i].tlambda>maxtlambda){
  676. bneck = i;
  677. maxtlambda = links[i].tlambda;
  678.       }
  679.     }    
  680.     tk = links[bneck].mu*(1+links[bneck].drop)+5;
  681.   }
  682.   Update(0);
  683.   cout << "Out of the converge loopn";
  684.     for (i =0; i<nLinks;i++){
  685.       cout << "Link " << i << " tlambda = " << links[i].tlambda << endl;
  686.     }
  687. }
  688. void newupdate(int niter){
  689.   int i;
  690.   // 1st init all unscaled tputs and cap
  691.   for (i=0;i<nLinks;i++){
  692.     links[i].uc = links[i].mu*(1.05);
  693.     links[i].utput = 0;
  694.   }
  695.   // calc all the unscaled tputs and C set all short flows 
  696.   // to be scaled already 
  697.   for(i=0; i<nConnections; i++){
  698.     if(flows[i].is_sflow)
  699.       flows[i].scaled = 1;
  700.     else 
  701.       flows[i].scaled = 0;
  702.     for(int j=0;j<nAdj[i];j++){
  703.       if(flows[i].is_sflow)
  704. links[Adj[i][j]].uc -= flows[i].p_tput;
  705.       else
  706. links[Adj[i][j]].utput += flows[i].p_tput;
  707.     }
  708.   }
  709.   //  for(i=0; i<nLinks; i++ ){
  710.   //cout << i << sp << links[i].uc << sp << links[i].utput << endl;
  711.   //}
  712.   double maxgamma; // most congested link
  713.   int bneck;
  714.   double t;
  715.   bneck = -1;
  716.   maxgamma = 0;
  717.   for(i=0; i<nLinks; i++){
  718.     if(links[i].uc){
  719.       t=links[i].utput/links[i].uc;
  720.       if(t > maxgamma){
  721. bneck = i;
  722. maxgamma = t;
  723.       }
  724.     }
  725.   }    
  726.   //cout << bneck << endl;
  727.   //char c= getchar();
  728.   /*
  729.   for(i=0;i<nConnections;i++){
  730.     cout << "connection" << sp << i << sp << "-"; 
  731.     for(int j=0;j<nAdj[i];j++){
  732.       cout << sp << Adj[i][j];
  733.     }
  734.     cout << endl;
  735.   }
  736.   */
  737.   // c= getchar();
  738.   while(bneck+1){
  739.     // cout << "bneck = " << bneck << sp << links[bneck].uc << sp << links[bneck].utput << sp << maxgamma << sp << links[bneck].nflows <<endl;
  740.     for(i=0; i<links[bneck].nflows; i++){
  741.      // For all the connections passing through this link
  742.       int t = links[bneck].theflows[i]; // get a connection id
  743.       //     cout << i<< sp << t << sp ;
  744.       // Now reduce its p_tput iff its not a short flow
  745.       // For short flows we dont do scaling
  746.       if(!flows[t].is_sflow && !flows[t].scaled){
  747. flows[t].p_tput /= maxgamma;
  748. //cout << "Flow " << t << " getting scaled to  << " << flows[t].p_tput;
  749. flows[t].scaled = 1; // we have scaled this flow already
  750. for(int j=0;j<nAdj[t];j++){
  751.   // subtract this scaled throughout from all teh links that
  752.   // have this flow. 
  753.   links[Adj[t][j]].uc -= flows[t].p_tput;
  754.   links[Adj[t][j]].utput -= flows[t].p_tput*maxgamma;
  755.   // cout << sp << Adj[i][j];
  756. }
  757. //cout << endl;
  758.       }
  759.     }
  760.     
  761.     // cout << links[bneck].uc << sp << links[bneck].utput << endl;
  762.     
  763.     links[bneck].uc = 0;
  764.     bneck = -1;
  765.     maxgamma = 0;
  766.     for(i=0; i<nLinks; i++){
  767.       if(links[i].uc){
  768. t=links[i].utput/links[i].uc;
  769. if(t > maxgamma){
  770.   bneck = i;
  771.   maxgamma = t;
  772. }
  773.       }
  774.     } 
  775.     /*
  776.     c = getchar();
  777.     for(i=0;i<nConnections;i++){
  778.       cout << "connection" << sp << i << sp << "-"; 
  779.       for(int j=0;j<nAdj[i];j++){
  780. cout << sp << Adj[i][j];
  781.       }
  782.       cout << endl;
  783.       }*/
  784.     
  785.     // c=getchar();
  786.   }
  787.   Update(niter);
  788. }
  789.   asim(){
  790.     // cout << "Reached heren";
  791.   }
  792.   void recv(Packet *, Handler * = 0){}
  793. };
  794. static class AsimClass : public TclClass {
  795. public:
  796.   AsimClass(): TclClass("Asim"){ }
  797.   TclObject * create(int, const char*const*) {
  798.     return (new asim());
  799.   }
  800. } class_asim;
  801. /*
  802. int main(int argc, char **argv) {
  803.   int niter = 0;
  804.   asim sim;
  805.   sim.GetInputs(argc, argv);
  806.   //  PrintResults();
  807.   cout << "Read the input .... n";
  808.   for(int i=0; i<10; i++){
  809.     sim.CalcLinkDelays(1);
  810.     cout << "Calculated link delays ... n";
  811.     //    PrintResults();
  812.     sim.CalcPerFlowDelays();
  813.     cout << "Calculated per flow delays ... n";
  814.     cout << " ------------------------------n";
  815.     sim.newupdate(niter);
  816.     //sim.PrintResults();
  817.     cout << " ------------------------------n"; 
  818.   }
  819.   sim.PrintResults();
  820. }
  821. */