Author Topic: Can we increase traffic flow rate by increasing maximum speed limit?  (Read 25104 times)

Fu-Kwun Hwang

  • Administrator
  • Hero Member
  • *****
  • Posts: 3062
    • Enjoy the fun of physics with simulations
Registed user can get files related to this applet for offline access.
Problem viewing java?Add http://www.phy.ntnu.edu.tw/ to exception site list
If java program did not show up, please download and install latest Java RUN TIME


Is it possible to increase the traffic flow by increasing the maximum allowed speed on the road?
The answer is NO. Due to reaction time, we need to keep the car in front of us a minimum distance.
If the reaction time is dt, and the speed of the car is v. You need to keep at least s=v*dt to be safe.
If the car is moving faster, the safety distance need to be increase proportionally.

There are 3 lanes in the following applet. The maximum speed Vmax for each lanes are different.
You can change Vmax, if you click Vmax label in the applet and enter your value into the textfield at the top.
Remember to hit ENTER when you are done (and the applet will accept your new value).
Nmax is the allowed maximum of cars on the road.
N is the current number of cars on the road, and n is the total number of cars pass the right edge.
I hope you can enjoy the related physics!



Related topic: Reaction time measurement , Reaction time and car accident, Traffic Light System


Registed user can get files related to this applet for offline access.
Problem viewing java?Add http://www.phy.ntnu.edu.tw/ to exception site list
If java program did not show up, please download and install latest Java RUN TIME

kidashley25

  • Newbie
  • *
  • Posts: 4
Re: Can we increase traffic flow rate by increasing maximum speed limit?
« Reply #1 on: June 29, 2010, 09:45:03 am »
Speed limits could be reduced or increased. Local speed limits are determined by Roads Service traffic. Make sure the exterior of your car is clean, but also focus on the interior.


-*-

GTRR

  • Newbie
  • *
  • Posts: 1
    • How To Play Guitar
Re: Can we increase traffic flow rate by increasing maximum speed limit?
« Reply #2 on: August 30, 2010, 06:16:48 pm »
hmmm...interesting! I think it is good to study it more.

laramsf

  • Newbie
  • *
  • Posts: 5
plz can u give me source code of traffic light system

Fu-Kwun Hwang

  • Administrator
  • Hero Member
  • *****
  • Posts: 3062
    • Enjoy the fun of physics with simulations
The source code is available as attached file.
It is also listed as following
Quote
import java.awt.*;

public class traffic extends java.applet.Applet implements Runnable{
   int yOffset=40;
   TextField iField;   //record time elapse
   double time=0.0,ts=0.;
   Dimension area;
   int N=3;
   //Rectangle   R[]=new Rectangle[N],L[]=new Rectangle[N];
   //Rectangle   R2[]=new Rectangle[N],L2[]=new Rectangle[N];
   //boolean Rs[]=new boolean[N],Ls[]=new boolean[N];
   Image bgImage,fgImage;
   Graphics gb,g;//background drawing
   Color bgColor=Color.lightGray;
   car c[]=new car[N];
   Label XY;
   String rts,STR[]={"Reset","Time"};
   public void init() {
      setBackground(bgColor);
      for(int i=0;i         if((rts=getParameter(STR))!=null)
            STR=new String(rts);
      }
      Panel p=new Panel();
//      p.add(new Label(STR[1]));
//      p.add(timeField=new TextField("0.0",3));
//      timeField.setEditable(false);
      p.add(new Button(STR[0]));
      p.add(iField=new TextField("",3));
      iField.setEditable(false);
      p.add(XY=new Label("(  X  ,  Y  )"));
      //p.add(new Button("Start"));
      add("North",p);
      area=size();
      area.height-=yOffset;
      reset(true);// false for auto start
   }

   public boolean action(Event ev, Object arg) {
      if (ev.target instanceof Button) {
         String label = (String)arg;
         if(label.equals("Reset")){
            reset(true);
         }/*else if(label.equals("Start")){
            running=true;
            start();
         }*/
      }else if(ev.target==iField&&changed!=null){
         double val=Double.valueOf(iField.getText()).doubleValue();
         if(mode            int dval=5;
            if(val>dval)dval=(int)val;
            if(clickCount==2){
               for(int i=0;i                  car.maxCount=dval;
               }
            }else   car.maxCount[mode]=dval;
         }else{//Vmax
            val=Math.abs(val);
            if(clickCount==2){
               for(int i=0;i                  car.vmax=val;
               }
            }else   car.vmax[mode%N]=val;
         }
         changed=null;
      }
      return true;
   }
   int xx,yy;
   public void reset(boolean status){
      time=0.;
      clear(status);
   }
   String d2String(double value){
      float f=(float)((int)(value*100.)/100.);
      String str=String.valueOf(f);
      if(str.indexOf(".")==-1)str+=".0";
      return str;
   }
   // animation code
   boolean running=true;
   Thread animThread;
   long startTime=0,lastTime;
   long delay=50,delta;
   //  This starts the threads.
   public void start(){
      //Start animating!
      if (animThread == null) {
         animThread = new Thread(this);
         animThread.start();
      }
      //Remember the starting time. of thread
      lastTime=startTime = System.currentTimeMillis();
   }
    public void stop() {
      //Stop the animating thread.
      animThread = null;
      running=false;
   }

   public void run() {
      //Just to be nice, lower this thread's priority
      Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
      //This is the animation loop.
      while (Thread.currentThread() == animThread) {
         //Advance the animation frame. with delta time
         delta=System.currentTimeMillis()-lastTime;
         lastTime+=delta;
         if(running)advanced(delta/1000.);
         startTime+=delay;
         try {
            animThread.sleep(Math.max(0,startTime-System.currentTimeMillis()));
         } catch (InterruptedException e) {
            break;
         }
      }
   }
   void advanced(double dt){
      for(int i=0;i         c.advanced(dt);
      time+=dt;
      ts+=dt;
      if(ts>1.){
         ts-=1.;
         //timeField.setText(String.valueOf(time));
      }
      repaint();
   }
   boolean rightClick=false;
   Color cpass=Color.green,cstop=Color.red;
   int mode;// 0-2:Nmax,3-5:Vmax,6-8:N
   int clickCount;
   int xs,ys;
   public boolean mouseDown(Event e, int x, int y){
      if((y-=yOffset)<0)return false;
      clickCount=e.clickCount;
      if(e.modifiers==Event.META_MASK){//"Right Click, ";
         rightClick=true;
         running=!running;
         car.running=running;
         repaint();
      }else{
         rightClick=false;
         changed=null;
         if(x         for(int i=0;i            if(carNmax.inside(x,y)){
               mode=i;
               changed=carNmax;
               break;
            }else   if(carVmax.inside(x,y)){
               mode=N+i;
               changed=carVmax;
               break;
            //}else   if(carN.inside(x,y)){
            //   mode=2*N+i;
            //   changed=carN;
            //   break;
            }
         }
         if(changed!=null)iField.setEditable(true);//requestFocus();
         else iField.setEditable(false);
      }
      xs=x;
      ys=y;
      return true;
   }
   public boolean mouseMove(Event e, int x, int y){
      if((y-=yOffset)<0||running)return false;
      XY.setText("("+x+", "+y+")");
      return true;
   }

   public boolean mouseDrag(Event e, int x, int y){
      if((y-=yOffset)<0||running)return false;
      XY.setText("("+(xs-x)+", "+(y-ys)+")");
      return true;
   }
   /*public boolean mouseUp(Event e, int x, int y){
      if((y-=yOffset)<0)return false;
      return true;
   }*/
   FontMetrics fm;
   int chy,chy2;
   int w=10,w2=2*w,dy,dx,dy2,xi,xf;
   Rectangle carNmax[]=new Rectangle[N];
   Rectangle carVmax[]=new Rectangle[N];
   //Rectangle carN[]=new Rectangle[N];
   Rectangle changed;
   static int ds=80;
   void clear(boolean status){
      if(g==null){
         bgImage = createImage(area.width, area.height);
         gb = bgImage.getGraphics();
         fgImage = createImage(area.width, area.height);
         g = fgImage.getGraphics();
         fm=gb.getFontMetrics();
         chy=fm.getHeight();
         chy2=chy*2;
         car.init(g,w,area.width,area.height);
         dy=area.height/N;
         dy2=dy-w2;
         dx=area.width-4*w;
         yy=0;
         xi=w+1;
         xf=area.width-w;
         int dd=dy2+xi;
         for(int i=0;i         /*   R=new Rectangle(xf,yy,xi,w);
            R2=new Rectangle(xf,yy+dd,xi,w);
            L=new Rectangle(0,yy+dd,xi,w);
            L2=new Rectangle(0,yy,xi,w);*/
            carNmax=new Rectangle(xx=car.xi2,yy=car.yi2+chy,ds,chy);
            //carN=new Rectangle(xx+ds,yy,ds,chy);
            carVmax=new Rectangle(xx,yy+chy,ds,chy);
         }
      }else if(status)car.init(g,w,area.width,area.height);
      gb.setColor(bgColor);
      gb.fillRect(0, 0, area.width, area.height);
      gb.setColor(Color.black);
      gb.drawLine(0,0,area.width-1,0);
      gb.drawRect(0,area.height-1,area.width-1,area.height-1);
      yy=w;
      for(int i=0;i         gb.drawRect(0,yy,w,dy2);
         gb.drawRect(w2,yy,dx,dy2);
         gb.drawRect(area.width-w,yy,w,dy2);
         c=new car(i,0);
         car.top=c;
         car.loop=false;
      }
      gb.setColor(cstop);
/*      for(int i=0;i         Rs=true;
         Ls=true;
         drawRect(gb,R);
         drawRect(gb,L);
      }*/
      gb.setColor(Color.gray);
      yy-=(dy+w);
      int yy2=yy-dy;
      for(int i=0;i         gb.drawLine(i,yy,i+w,yy);
         gb.drawLine(i,yy2,i+w,yy2);
      }
   }
//   void drawRect(Graphics g,Rectangle r){
//      g.fillOval(r.x,r.y,r.width,r.height);
//   }
   public void paint(Graphics gs){
         update(gs);
   }
   public void update(Graphics gs){
      g.drawImage(bgImage, 0, 0, this);
      g.drawString(STR[1]+d2String(time),area.width/2,25);
      for(int i=0;i.draw();
      if(changed!=null){
         g.setColor(Color.white);
         if(clickCount==2){
            int dh;
            if(mode            for(int i=0;i               g.fillRect(changed.x,carNmax.y+dh,changed.width,changed.height);
            }
         }   else g.fillRect(changed.x,changed.y,changed.width,changed.height);
      }
      g.setColor(Color.gray);
      for(int i=0;i         g.drawString("Nmax="+car.maxCount,xx=carNmax.x,yy=carNmax.y+chy);
         g.drawString("N="+car.count,xx+ds,yy);
         g.drawString("Vmax="+car.vmax,xx,yy+=chy);
         g.drawString("n="+car.passed,xx+ds,yy);
      }
      // drawing work
      gs.drawImage(fgImage, 0, yOffset, this);
   }
}

class car extends rk4{
   static int N=3,size,size2,size3,size0;
   static int xmax,xmin,dy2;
   static double ai=10.,vmax[]={20.,30.,40.};   // reaction time set to 1.0 sec
   static double reactionTime=0.5,dmin[]=new double[N]
      ,dmin2[]=new double[N],dmax[]=new double[N];
   static int xi,xf,yi[]=new int[N],yf[]=new int[N];
   static int xi2,xf2,xi3,xf3,yi2[]=new int[N],yf2[]=new int[N];
   static int maxCount[]={20,20,20},count[]={0,0,0},passed[]={0,0,0};
   static car top[]=new car[3];
   static boolean loop[]={false,false,false};
   static double delta;
   static car tmp=null;
   static Graphics g;
   //static boolean lastTurn=false;
   int mode=0;// right,down,left,up
   boolean turn=false;
   boolean gone=false;
   static boolean debug=false,running=true;
   int X,Y,id;
   double a;
   car next=null;
   double accelerated=1.,sign=1.;
   //static int width=8,height=5;
   car(int idi,int modei){
      init(2,true);// 1D motion
      id=idi;
      mode=modei;
      y[1]=vmax[id]/3.;//*Math.random();
      if(mode==0){
         Y=yi[id];
         y[0]=xmin;
         a=ai;
         sign=1.;
      }else{
         mode=2;
         Y=yf[id];
         y[0]=xmax;
         a=-ai;
         sign=-1.;
         y[1]=-y[1];
      }
      count[id]++;
      gone=false;
   }
   static void init(Graphics gi,int w,int width,int height){
      int y0=(int)(w/4.+0.5);
      xmax=width;
      xmin=0;
      g=gi;
      size=w/2;
      size0=size/2;
      size2=w;
      size3=w*3/2;
      xi=w+size-y0;
      xf=width-w-size-y0;
      xi2=xi+size2;
      xf2=xf-size2;
      xi3=xi2+size2;
      xf3=xf2-size2;
      height/=3;
      int dy=height-w;
      dy2=dy/2;
      running=true;
      for(int i=0;i         yi=y0;
         yf=yi+dy;
         yi2=yi+size;
         yf2=yf-size;
         setRange(i);
         count=0;
         passed=0;
      }
   }
   static void setRange(int i){
      dmin=vmax*reactionTime;
      if(dmin=size2;
      dmin2=dmin/2.;
      if(dmin2=size2;
      dmax=dmin2+size2;
   }
   public void derivs(double x,double y[],double dydx[]){
      dydx[0]=y[1];
      dydx[1]=a; //
   }
   void advanced(double dt){
     //try{
      switch(mode){//??????
      case 0://right
         X=(int)y[0];
         if(gone)break;//??
         //if(X>xf3&&y[0]!=0.)y[1]=-ai;
         //else
         if(y[0]>xf){
            if(this!=top[id]&&next!=null && Math.random()>0.5){//??????????
               gone=true;
               y[1]=vmax[id];//????
               //if(next!=null && next.y[1]==0.)next.a=next.sign*ai;
            }else{//??
               y[0]=yi[id];
               y[1]=y[1]/2.;// ?
               a=ai;
               mode++;
               sign=1.;
               X=xf;
            }
            //if(next!=null )next.turn=true;
            break;
         }else if(y[0]>xf2&&next!=null&&next.mode==3)next.turn=true;
         //if(turn&&X>xf2)y[1]/=2.;//?????????
         if(next!=null&&next.turn){//????
             if(X>xi2){
                next.turn=false;//?????
                if(next.y[1]==0.)next.a=next.sign*ai;
             }else if(y[1]==0. && next.mode==3 && next.Y
               next.y[1]=0.;
               next.a=0.;
            }
         }
         break;
      case 1://down    
         if(y[0]>yf[id]){//?????
            y[0]=xf;
            a=-ai;
            mode++;
            y[1]=-y[1]/2.;
            Y=yf[id];
            sign=-1.;
            //if(next!=null )next.turn=true;
            break;
         }else   {
            Y=(int)y[0];
            if(y[0]>yf2[id]&&next!=null&&next.mode==0)next.turn=true;
         }
         //if(turn && Y>yf2[id])y[1]/=2.;
         if(next!=null&&next.turn){//?????????
            if(Y>yi2[id]){
               next.turn=false;
               if(next.y[1]==0.)next.a=next.sign*ai;
            }else if(y[1]==0. &&next.mode==0&& next.X>xf2){//??????
               next.y[1]=0.;
               next.a=0.;
            }
         }
         break;
      case 2://left
         X=(int)y[0];
         if(gone)break;
         //if(X         //else
         if(y[0]            if(this!=top[id] && next!=null&& Math.random()>0.5){
               gone=true;
               y[1]=-vmax[id];
            //   if(next==null&&top[id].y[0]==0.]top[id].y[1]=top[id].sign*ai;
               //if(next!=null && next.y[1]==0.)next.a=next.sign*ai;
            }else{
               y[0]=yf[id];
               y[1]/=2.;
               a=-ai;
               mode++;
               sign=-1.;
               X=xi;
            }
            if(next==null)top[id].a=top[id].sign*ai;
            //if(next!=null)next.turn=true;
            if(this==top[id])loop[id]=true;//???
            break;
         }else if(y[0]         //if(turn && X         if(next!=null&&next.turn){
            if(X               next.turn=false;
               if(next.y[1]==0.)next.a=next.sign*ai;
            }else if(y[1]==0. &&next.mode==1&& next.Y>yf2[id]){
               next.y[1]=0.;
               next.a=0.;
            }
         }
         break;
      case 3://up
         if(y[0]            y[0]=xi;
            a=ai;
            mode=0;
            sign=1.;
            y[1]=-y[1]/2.;
            Y=yi[id];
            //if(next!=null )next.turn=true;
            break;
         }else{
            Y=(int)y[0];
            if(y[0]         }
         //if(turn && Y         if(next!=null&&next.turn){
            if(Y               next.turn=false;
               if(next.y[1]==0.)next.a=next.sign*ai;
            }else if(y[1]==0. &&next.mode==2 && next.X               next.y[1]=0.;
               next.a=0.;
            }
         }
         if(next==null&&turn&&top[id].y[1]==0.)
            top[id].a=top[id].sign*ai;
         break;
      }
    //} catch (NullPointerException e){ }
/*
    if(gone){
       y[0]+=y[1]*dt;
       if(next!=null){
          next.a=sign*ai;
          next.advanced(dt);
       }else {
          top[id].a=sign*ai;
       }
       return;
      }*/
      //if(y[1]==0.)a=0.;
      //???
      if(count[id]         y[0]=yi2[id]+dmin2[id];
         y[1]=0.;
         a=0.;
      }else if(a!=0.){
         nextmove(dt);
         if(Math.abs(y[1])>vmax[id]){//????????????
            y[1]=sign*vmax[id];
            a=0.;
         }
      }   else y[0]+=y[1]*dt;//?????
      if(y[1]*sign<0.){//???????
         y[1]=0.;
         a=0.;
      }
      
      if(next!=null){//?????
         if(next.gone){//???????
            next.a=sign*ai;
         }else if(next.mode==mode){//????
            delta=sign*(y[0]-next.y[0]);//??
            if(delta>dmax[id])next.accelerated=1.0; // ??
            else if(Math.abs(delta)                  next.y[1]=0.;
                  next.accelerated=0.;
            }else if(sign*(next.y[1]-y[1])>0.)next.accelerated=-1.;
            if(Math.abs(next.y[1])??
               next.a=next.sign*ai*next.accelerated;
               //if(next.a!=0&&next.y[1]==0.)next.y[1]=sign*0.1;
            }else{//????
               next.a=0.;
               //next.y[1]=next.sign*vmax[id];
            }
         }//else {//????
         //   if(next.y[1]==0.&& (mode-next.mode>1. || !next.turn)) next.a=next.sign*ai;
         else if(Math.abs(next.X-X)+Math.abs(next.Y-Y)               next.y[1]=0.;
               next.a=0.;
            }
         //}
         next.advanced(dt);
         if(next.X>xmax || next.X<0.){
            next=next.next;
            count[id]--;
            passed[id]++;
         }
      /*   if(loop[id] && count[id]            if(mode==2 && X               next.a=0.;
               next.y[1]/=2.;
               next.turn=true;
               tmp=new car(id,2);
               tmp.next=next;
               next=tmp;
            //}else if(mode==0 &&X>xi2){
            //   next.a=0.;
            //   next.y[1]/=2.;
            //   next.turn=true;
            //   tmp=new car(id,0);
            //   tmp.next=next;
            //   next=tmp;
            }
         }*/
      }else{ // last car
         if(loop[id]&&top[id].mode==mode){//????? ???
            delta=sign*(y[0]-top[id].y[0]);
            if(delta>dmax[id])top[id].accelerated=1.;
            else if(Math.abs(delta)                  top[id].y[1]=0.;
                  top[id].accelerated=0.;
            }else if(sign*(y[1]-top[id].y[1])>0.)top[id].accelerated=-1.;
            if(Math.abs(top[id].y[1])               top[id].a=top[id].sign*ai*top[id].accelerated;
               //if(top[id].a!=0.&&top[id].y[1]==0.)top[id].y[1]=0.1*sign;
            }
            /*/if(y[1]==0. && top[id].y[1]==0.)top[id].a=sign*ai;/*else{//????
               top[id].a=0.;
               top[id].y[1]=sign*vmax[id];
            }*/
         }else   if(mode!=0 && top[id].y[1]==0.){//????
            //if(mode!=0 || X>xi2)
               top[id].a=top[id].sign*ai;
         }
         if( count[id]            //if( (mode!=0 && top[id].mode>mode)  || X>xi2 && (top[id].mode!=3 || top[id].y[0]==yi2[id]+dmin2[id])&&
            //   (!loop[id] || top[id].mode>mode && top[id].y[0]>yi[id] || top[id].y[1]==0. ) )
            if( top[id].mode>mode ||!loop[id]) {
               if(X>xi2)next=new car(id,0);
            }else if(top[id].mode==mode){
               if(sign*(top[id].y[0]-y[0])>0)next=new car(id,0);
            }
         }else   if(top[id].y[1]==0.){//????
            if(mode!=0 || X>xi2)
               top[id].a=top[id].sign*ai;
         }
      }
   }
   static int xx,yy;
   void draw(){
      //g.drawRect(X,Y,5,5);
      if(a==0.){
         if(y[1]!=0.)g.setColor(Color.green);
         else g.setColor(Color.gray);
      }else if(sign*a>0.)g.setColor(Color.blue);
      else g.setColor(Color.red);
      if(debug&&this==top[id])g.fillRect(X,Y,size,size);
      else g.drawRect(X,Y,size,size);
      if(!running){
         g.setColor(Color.red);
         if(mode%2==0)g.drawLine(xx=X+size0,yy=Y+size0,xx,yy+(int)y[1]);
         else g.drawLine(xx=X+size0,yy=Y+size0,xx-(int)y[1],yy);
      }
      if(next!=null)next.draw();
   }
}



ericaclayton453

  • Newbie
  • *
  • Posts: 0
Re: Can we increase traffic flow rate by increasing maximum speed limit?
« Reply #5 on: September 17, 2015, 02:46:19 pm »
It is interesting. :)

chengfu

  • Newbie
  • *
  • Posts: 0
    • Smoothgraph Connect Co Ltd
Re: Can we increase traffic flow rate by increasing maximum speed limit?
« Reply #6 on: October 26, 2015, 05:02:10 pm »
Thumbs up admin  ;D never should be die the source code.