数模论坛

 找回密码
 注-册-帐-号
搜索
热搜: 活动 交友 discuz
查看: 25163|回复: 34

公交调度的仿真模拟程序

[复制链接]
发表于 2003-8-5 06:59:48 | 显示全部楼层 |阅读模式
用时间步长搜索最佳时间间隔,给出一个小时段的搜索程序(语言c#)
无法上传流程度,抱歉!
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.IO;
namespace ConsoleApplication1
{
        /// <summary>
        /// Class1 的摘要说明。
        /// </summary>
        class Class1
        {
                /// <summary>
                /// 应用程序的主入口点。
                /// </summary>
                [STAThread]
                static void Main()
                {
                        Queue Cars=new Queue();//创建汽车队列
                        Queue Save=new Queue();//保存副本
                        Car [] RunCar=new Car[1150];//保存运行中车辆
                        Car [] SaveCar=new Car[1150];//用于保存副本
                        int listlong=0;//纪录队列长度,总车次
                        Queue SumWait=new Queue();//记录总的乘客总的等待时间
                        ArrayList nexttime=new ArrayList();//末状态保存时间数组
                        int Car_num=0;//用于记录车辆数
                        Station [] Stations=new Station[14];
                        int time;//模拟时钟
                        int Carlong=0;//用于记录上个时间段所发的车辆数
                        int Savelistlong=0;
                        for(int t=0;t<=13;t++)
                        {
                                Stations[t]=new Station(t);
                        }//创建车站队列
                        StreamWriter Input=File.CreateText("Car.txt");
                        Input.Close();
                        StreamWriter SumFile=File.CreateText("Sum.txt");
                        SumFile.Close();
                        int [] Persons=new int[14];//存放各站人数的副本
                        int [] Personsdown=new int[14];//存放各站下车人数的副本
                        int [] personsmin=new int[14];
                        int [] personsdown=new int[14];
                        int Atime=0;
                        int AT=1;
                        double [] Down_Fifty_raito=new double[12];
                        double [] Persons_In_Ave=new double[12];
                        double [] Wait_Ave=new double[12];
                        double [] Charge=new double[12];
                        //int Car_num;//记录各个时间间隔发车所需的车辆数
                        //*********************************************************************

                        //这里会加入一些代码,用于分时间段处理

                        //*********************************************************************
#region  time1       
                        Stations[0].Persons=371;Stations[0].ToAnother=1.6;Stations[0].Persons_Down=0;
                        Stations[1].Persons=60;Stations[1].ToAnother=0.5;Stations[1].Persons_Down=8;
                        Stations[2].Persons=52;Stations[2].ToAnother=1;Stations[2].Persons_Down=9;
                        Stations[3].Persons=43;Stations[3].ToAnother=0.73;Stations[3].Persons_Down=13;
                        Stations[4].Persons=76;Stations[4].ToAnother=2.04;Stations[4].Persons_Down=20;
                        Stations[5].Persons=90;Stations[5].ToAnother=1.26;Stations[5].Persons_Down=48;
                        Stations[6].Persons=48;Stations[6].ToAnother=2.29;Stations[6].Persons_Down=45;
                        Stations[7].Persons=83;Stations[7].ToAnother=1;Stations[7].Persons_Down=81;
                        Stations[8].Persons=85;Stations[8].ToAnother=1.2;Stations[8].Persons_Down=32;
                        Stations[9].Persons=26;Stations[9].ToAnother=0.4;Stations[9].Persons_Down=18;
                        Stations[10].Persons=45;Stations[10].ToAnother=1;Stations[10].Persons_Down=24;
                        Stations[11].Persons=45;Stations[11].ToAnother=1.03;Stations[11].Persons_Down=25;
                        Stations[12].Persons=11;Stations[12].ToAnother=0.53;Stations[12].Persons_Down=85;
                        Stations[13].Persons=0;                             Stations[13].Persons_Down=57;//将每个站点在这个时间段的上车人数指定
//---------------------------------------------------------------------------------------------------------------------//
                        //主循环开始

                        for(int t=10;t<=10;t++)
                        {
                                Console.WriteLine("start:"+t);

                                for(int i=0;i<=13;i++)
                                {
                                        if(Stations.Persons>60)
                                                personsmin=Stations.Persons/60;
                                        else
                                                personsmin=0;
                                        if(Stations.Persons_Down>60)
                                                personsdown=Stations.Persons_Down/60;
                                        else
                                                personsdown=0;
                                        Persons=Stations.Persons;
                                        Personsdown=Stations.Persons_Down;
                                        Stations.Persons_wait=0;
                                        Stations.Person_Wait.Clear();
                                }
//------------------确定一个时间步长后的流程模拟-------------------------------------------------------------------------------------------------------------//
                               
                                for(time=0;time<=60;time++)//发车
                                {
              //^^^^^^^各站各种情况每隔一分钟变化^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^//
                                       
                                        for(int j=0;j<=13;j++)
                                        {                                       
                                                if(!(Persons[j]>0))                                               
                                                {
                                                        Stations[j].Persons_min=0;
                                                }
                                                if(time<Stations[j].Persons%60)
                                                        Stations[j].Persons_min=personsmin[j]+1;
                                                else
                                                        Stations[j].Persons_min=personsmin[j];
                                                        for(int p=Stations[j].Persons_wait;p<Stations[j].Persons_min+Stations[j].Persons_wait;p++)
                                                    {
                                                                Person newperson=new Person();
                                                            newperson.Iswait=true;
                                                                newperson.Waittime=0;
                                                            Stations[j].Person_Wait.Insert(p,newperson);
                                                    }
                                                    int length=Stations[j].Person_Wait.Count;
                                                    for(int per=0;per<length;per++)
                                                    {
                                                        Person anotherper=(Person)Stations[j].Person_Wait[per];
                                                        Stations[j].Person_Wait.RemoveAt(per);
                                                        anotherper.Waittime+=1;
                                                        Stations[j].Person_Wait.Insert(per,anotherper);
                                                    }//分配乘客人数,对乘客属性进行修改
                                                        Stations[j].Persons_wait+=Stations[j].Persons_min;
                                                        Persons[j]-=Stations[j].Persons_min;
                                                if(!(Personsdown[j]>0))
                                                        Stations[j].Persons_per_down=0;       
                                                if(time<Stations[j].Persons_Down%60)
                                                        Stations[j].Persons_per_down=personsdown[j]+1;
                                                else
                                                        Stations[j].Persons_per_down=personsdown[j];
                                                Stations[j].Persons_down+=Stations[j].Persons_per_down;
                                                    Personsdown[j]-=Stations[j].Persons_per_down;                                               
                                        }//各站乘客子程序
//_______________________开始发车_____________________________
                                       
                                        if(time%t==0)
                                        {
                                                listlong+=1;//发一次车
                                                if(!(Cars.Count>0))
                                                {
                                                        Car anewcar=new Car(Car_num+1);
                                                        Cars.Enqueue(anewcar);//车站加入新车
                                                        Car_num+=1;
                                                }                                               
                                                        RunCar[listlong-1]=new Car(0);
                                                    Car copycar=(Car)Cars.Dequeue();
                                                        RunCar[listlong-1].Car_num=copycar.Car_num;//
                                                    //for(int dd=0;dd<=13;dd++)
                                                        //        RunCar[listlong-1].Persons_At_EachStation[dd]=0;
                                                        RunCar[listlong-1].Isruning=true;//修改车的属性为运行中
                                                       
                                                   int length;
                                                   length=Stations[0].Person_Wait.Count;//记录首站点乘客等待人数,用于循环判断

                                                        if(Stations[0].Persons_wait>120)//考虑了满载率的问题,不允许超过120%
                                                        {                                                               
                                                                for(int s=0;s<120;s++)
                                                                {                                                                       
                                                                        Person Wait=(Person)Stations[0].Person_Wait[0];                                                                       
                                                                        SumWait.Enqueue(Wait.Waittime);//将上车后的人的等待时间入队列                                                                       
                                                                        Stations[0].Person_Wait.RemoveAt(0);                                                                       
                                                                }
                                                                RunCar[listlong-1].Persons_In=120;
                                                                Stations[0].Persons_wait-=120;
                                                        }
                                                        else
                                                        {
                                                                for(int q=0;q<length;q++)
                                                                {
                                                                        Person Wait=(Person)Stations[0].Person_Wait[q];                                                                       
                                                                        SumWait.Enqueue(Wait.Waittime);//将上车后的人的等待时间入队列
                                                                }
                                                                Stations[0].Person_Wait.Clear();
                                                                RunCar[listlong-1].Persons_In=Stations[0].Persons_wait;
                                                                Stations[0].Persons_wait=0;
                                                        }//首站上车人数}
                                                    RunCar[listlong-1].Persons_At_EachStation[0]=RunCar[listlong-1].Persons_In;//计算首站的载客量
                                                        //Console.WriteLine("error too");
                                                        RunCar[listlong-1].NextStation=1;
                                                        RunCar[listlong-1].NextTime=(int)(time+0+1.6*3);
                                                                                       
                                        }
//_____________________发车程序结束______________________________________________________

//_____________________到站车辆上下车程序段___________________________________________________________________________________________________________________//
                                                int d=0;int Persons_down;
                                        for(int dd=0;dd<listlong;dd++)//判断是否有车到站,dd是车的辆数
                                                {
                                                        if(time==RunCar[dd].NextTime&&RunCar[dd].Isruning==true)
                                                                                                                                                                                       
                                                                if(RunCar[dd].NextStation!=13)
                                                                {
                                                                        d=RunCar[dd].NextStation;
                                                                Stations[d].lasttime=RunCar[dd].NextTime;
                                                                        int length=Stations[d].Person_Wait.Count;//该时刻该站点的等车人数                                                                       
                                                                        if(RunCar[dd].Persons_In<Stations[d].Persons_down)
                                                                                Persons_down=RunCar[dd].Persons_In;//记录该站实际下车人数
                                                                        else
                                                                        Persons_down=Stations[d].Persons_down;
                                                                        if((RunCar[dd].Persons_In+Stations[d].Persons_wait-Persons_down)>120)
                                                                        {                                                                       
                                                                                int UpPerson=120-(RunCar[dd].Persons_In-Persons_down);
                                                                                for(int s=0;s<UpPerson;s++)
                                                                                {                                                                       
                                                                                        Person Wait=(Person)Stations[d].Person_Wait[0];                                                                       
                                                                                        SumWait.Enqueue(Wait.Waittime);//将上车后的人的等待时间入队列
                                                                                        Stations[d].Person_Wait.RemoveAt(0);//删除上车后的人
                                                                                }                                                                               
                                                                                Stations[d].Persons_wait=Stations[d].Person_Wait.Count;
                                                                                RunCar[dd].Persons_In=120;                                                                               
                                                                        }
                                                                        else
                                                                        {
                                                                                for(int q=0;q<length;q++)
                                                                                {
                                                                                        Person Wait=(Person)Stations[d].Person_Wait[q];                                                                       
                                                                                        SumWait.Enqueue(Wait.Waittime);//将上车后的人的等待时间入队列
                                                                                }
                                                                                Stations[d].Person_Wait.Clear();
                                                                                RunCar[dd].Persons_In+=(Stations[d].Persons_wait-Persons_down);
                                                                                Stations[d].Persons_wait=0;
                                                                        }
                                                                        Stations[d].Persons_down-=Persons_down;//该站的以后将要下车人数减去该站已下车人数后的部分
                                                                        RunCar[dd].Persons_At_EachStation[d]=RunCar[dd].Persons_In;//计算经过一个站点后的载客量
                                                                        if((Stations[d].ToAnother*3+1)-(int)(Stations[d].ToAnother*3+1)>0.5)
                                                                        RunCar[dd].NextTime+=(int)(Stations[d].ToAnother*3+1)+1;
                                                                        else
                                                                                RunCar[dd].NextTime+=(int)(Stations[d].ToAnother*3+1);
                                                                        RunCar[dd].NextStation+=1;
                                                                       
                                                                }
                                                                else
                                                                {                                                                       
                                                                        RunCar[dd].Isruning=false;//车辆运行到底站,属性改为非运行
                                                                        Cars.Enqueue(RunCar[dd]);                                                                       
                                                                }
                                                }//判断是否有车到站       
//________________________上下车程序段结束___________________________________________________________________________________________________________
                                }
//___一个步长模拟结束___________________________________________________________________________________
                        MessageBox.Show(t+":"+listlong.ToString());
                                Console.WriteLine("About Stations");
                                for(int x=0;x<=13;x++)
                                {
                                        Console.Write(Stations[x].Persons_wait+"\t");
                                        Console.WriteLine(Stations[x].lasttime);
                                }
                                Console.WriteLine("About RunCar");
                                Input=File.AppendText("Car.txt");                               
                                int Down_Fifty=0;//记录小于50的车辆数
                                int Sum_Persons_In=0;//记录总的载客量;
                                int In_num=0;//记录总的载客次数                               
                                for(int y=0;y<listlong;y++)
                                {
                                        Console.WriteLine(RunCar[y].Car_num+":");
                                        Input.Write(RunCar[y].Car_num.ToString()+":"+"\t");
                                        for(int v=0;v<=13;v++)                                       
                                        {
                                                Console.Write(RunCar[y].Persons_At_EachStation[v]+";");                                               
                                                Input.Write(RunCar[y].Persons_At_EachStation[v].ToString()+"\t");
                                               
                                                if(RunCar[y].Persons_At_EachStation[v]!=0)
                                                {In_num+=1;if(RunCar[y].Persons_At_EachStation[v]<50)
                                                                           Down_Fifty+=1;}
                                                Sum_Persons_In+=RunCar[y].Persons_At_EachStation[v];
                                        }Input.WriteLine("");
                                       
                                        Console.WriteLine("");
                                }
                                Down_Fifty_raito[t-1]=(double)Down_Fifty/In_num;//少于50%载客比率
                                Persons_In_Ave[t-1]=(double)Sum_Persons_In/In_num/100;//平均满载率
                                Input.WriteLine("<50:"+Down_Fifty+"\t"+"总载客量:"+Sum_Persons_In+"\t"+"总载客次数"+In_num+"平均满载率"+Persons_In_Ave[t-1]+"<50%比率"+Down_Fifty_raito[t-1]);
                                Input.WriteLine("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
                               
                       
                                int count=SumWait.Count;
                                int [] Sum=new int[count];
                                SumWait.CopyTo(Sum,0);
                                SumFile=File.AppendText("Sum.txt");
                                int Upten=0;
                                for(int w=1;w<count;w++)
                                {
                                        SumFile.Write(Sum[w]+"\t");
                                        if(Sum[w]>10)
                                                Upten+=1;
                                        if(w%100==0)
                                                SumFile.WriteLine("");
                                }
                                Upten=Upten+1035-count;
                                Wait_Ave[t-1]=(double)Upten/1035;//等待时间超时率
                                Charge[t-1]=Persons_In_Ave[t-1]-Down_Fifty_raito[t-1]-Wait_Ave[t-1];
                                Input.WriteLine("");
                                Input.WriteLine("目标函数值:"+Charge[t-1]);
                                Input.Close();
                                SumFile.WriteLine("-----");SumFile.WriteLine("_________________"+Upten.ToString()+"________________"+count+"________"+Wait_Ave[t-1]+"______");
                                SumWait.Clear();
                                SumFile.Close();
                               
                                for(int i=0;i<listlong;i++)
                                {SaveCar=new Car(0);
                                        SaveCar.NextStation=RunCar.NextStation;
                                        SaveCar.NextTime=RunCar.NextTime;
                                        SaveCar.Persons_In=RunCar.Persons_In;
                                        SaveCar.Isruning=RunCar.Isruning;
                                        SaveCar.Car_num=RunCar.Car_num;
                                }
                                Save=Cars;       
                                RunCar.Initialize();
                                Cars.Clear();
                                Carlong=Car_num;
                                Savelistlong=listlong;
                                listlong=0;
                                Car_num=0;                               
                        }
                        /*for(int num=0;num<11;num++)
                        {
                                if(Charge[num]<Charge[num+1])
                                        AT=num+2;
                        }
                        Console.WriteLine("时间间隔为:"+AT);*/
//_主循环结束________________________________________________________________________
                        #endregion

                }
        }

        public class Car
        {
                public bool Isruning;//判断是否在运行,true为运行中
                public int Atstation;//运行在哪个站点
                public int Runtime;//运行时间
                public int NextStation;//下个站点
                public int NextTime;//到达下站的时间
                public int Persons_In;//车上乘客人数
                public int [] Persons_At_EachStation=new int[14];//车辆在到达各个站点时的载客量
                public int Car_num;//车次
                public Car(int i)
                {
                        Isruning=false;
                        Persons_In=0;
                        Car_num=i;//创建车辆是赋予在队列中的位置
                }
        }
        public class Person
        {
                public bool Iswait;//盘算是否在等车,true为等待状态
                public int Waittime;//等车时间
                public Person()
                {
                        Iswait=true;//一个乘客到来时让其处于等待状态
                }
        }
        public class Station
        {
                public int Persons_wait;//车站等车人数
                public int Up_wait;//上个时间段位上车人数
                public int Persons;//单个时间段上车总人数
                public int Persons_min;//每分钟时刻车站乘客总数
                public int Station_num;//车站号
                public double ToAnother;//到达下个站点的距离
                public int Persons_Down;//下车人数
                public int Persons_per_down;//每分钟欲下车人数
                public int Persons_down;//各站点某时刻需下车人数
                public bool Isup;//true表示上行方向
                public ArrayList Person_Wait=new ArrayList();//每个车站某时刻等待的乘客
                public ArrayList Up_Wait=new ArrayList();//上个时间段的等车人数
                public int lasttime;//记录一个时间段最后一班车的到来时间
                public Station(int i)
                {
                        Station_num=i;
                        Persons_wait=0;
                }

        }
}
 楼主| 发表于 2003-8-5 07:01:32 | 显示全部楼层
在建模中写这么长的程序,从投入时间和精力上,自我感觉……不值!
不只各位意见如何?
发表于 2003-8-5 07:49:13 | 显示全部楼层
这没关系,写长的程序无所谓,去年的彩票我写模拟程序写了400多行,花了一整天时间,但是最后没有在文章中体现出来,仅仅是为了验证自己的模型是否正确,但原来是想去求解的,后来想到了更好的模型可以求解的时候,就不用仿真了。
而你写01年的这题,实际上除了仿真外应该没有更好的方法了,所以仿真很有必要,因此还是值得的。
 楼主| 发表于 2003-8-5 08:41:09 | 显示全部楼层
谢谢楼上的支持。在做完这个题目,自我评价是老是因为这个程序患得患失。
听楼上这翻话,总算踏实一点。
发表于 2003-8-5 08:44:35 | 显示全部楼层
哈哈
你还没睡呀?
 楼主| 发表于 2003-8-5 09:06:12 | 显示全部楼层
是啊,在研究tsp中的遗传算法。
有点看不懂!
发表于 2003-8-23 20:04:36 | 显示全部楼层
用c#编是不是太麻烦了,那么长看的头都大了。
不过我很佩服你的能力。
 楼主| 发表于 2003-8-6 09:36:02 | 显示全部楼层
如果能上传图片就不用看这些垃圾了。
发表于 2003-8-7 19:36:29 | 显示全部楼层
确实,没有流程图,这些符号看起来非常废劲。
发表于 2003-8-7 19:37:07 | 显示全部楼层
确实,没有流程图,这些符号看起来非常废劲。
您需要登录后才可以回帖 登录 | 注-册-帐-号

本版积分规则

小黑屋|手机版|Archiver|数学建模网 ( 湘ICP备11011602号 )

GMT+8, 2024-11-27 05:37 , Processed in 0.081677 second(s), 18 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表