Список работ

Построение диаграммы прихода пассажиров на остановку

Бартеньев О. В., Ефремова Н. Г.

Содержание

Введение

Создается C#-приложение, которое генерирует диаграмму прихода пассажиров на остановку трамвая, например, на остановку Авиамоторная.
На практике такая диаграмма создается в результате сбора статистических данных о прибытии пассажиров на остановку в разные промежутки времени. Для каждого временного интервала на диаграмме указывается математическое ожидание числа пассажиров, приходящих на остановку.
Такие диаграммы создаются для каждой остановки маршрута.
В программе диаграмма генерируется автоматически по следующим данным:

Определение числа приходящих пассажиров (pasCome) для каждого временного интервала следующий:

Если интервал входит в часы пик, то
    pasCome = случайное число из "диапазона пик";
иначе
    pasCome = случайное число из "диапазона прочий";

Это число определяется для каждого интервала диаграммы и заносится в массив arrPasCome; начало временного интервала записывается в массив arrTimeInt.
Эти массивы используются для построения диаграммы и определения числа пассажиров, приходящих в заданный временной промежуток.
В частности, таким промежутком может быть интервал между прибытием на остановку трамваев j и j + 1. В этом случае вычисленное число – это количество пассажиров, которые хотели бы сесть в трамвай j + 1.
Они сядут в этот трамвай, если позволит его вместимость.
Форма, обеспечивающая задание входных данных, выбор типа диаграммы и отображение результата, показана на рис. 1.

Ступенчатая или столбцовая диаграмма

Рис. 1. Диаграмма прихода пассажиров на остановку трамвая

Доступные типы диаграмм:

Тип проекта - Windows Form Application.
При нажатии на кнопку Генерировать создаются диаграммы для каждой остановки, сохраняемые в файлах stop*.txt.
Число файлов равно числу остановок.
Замечание. Аналогичным образом формируется и диаграмма выхода пассажиров на остановке из транспортного средства.

Реализация

using System;
using System.IO; // StreamWriter
using System.Drawing;
using System.Windows.Forms;

namespace WindowsFormsApplicationChart
{
    public partial class FormDiag : Form
    {
        const string fileParams = "params.txt"; // Пишем в файл интервал, число интервалов диаграммы прихода и диапазоны часов пик
        const string fileStop = "stop"; // Файлы диаграмм остановок (stop*)
        const int tStart = 5 * 3600 + 20 * 60; // Время начала движения первого трамвая, с
        const int tEnd = 25 * 3600 + 20 * 60; // Время начала движения последнего трамвая, с
        const int tGoLast = 1 * 3600 + 40 * 60; // Время в пути (задается для последнего трамвая), с

        int nStops = 24; // Число остановок
        int nPas = 13000; // Число перевозимых пассажиров
        // Начало и конец утреннего и вечернего интервалов часов пик (в мин при показе и в секундах при генерации)
        int morn, morn2, ev, ev2;
        // Диапазоны пассажиров, приходящих в часы пик и прочие часы
        int pasPeak, pasPeak2, pasOth, pasOth2;
        int[][] arrDiags; // Массив диаграмм прихода пасссажиров на остановки
        private Random rnd = new Random();
        StreamWriter sW;

        public FormDiag()
        {
            InitializeComponent();
            // Параметры диаграммы
            chartIn.ChartAreas[0].AxisX.Title = "Временной интервал, мин";
            chartIn.ChartAreas[0].AxisY.Title = "Число пассажиров";
            // Шрифт для координатных осей диаграммы
            Font fnt = new System.Drawing.Font("Microsoft Sans Serif", 10.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
            chartIn.ChartAreas[0].AxisX.TitleFont = fnt;
            chartIn.ChartAreas[0].AxisY.TitleFont = fnt;
            chartIn.ChartAreas[0].BackColor = Color.WhiteSmoke; // Фон диаграммы
            chartIn.Series[0].LegendText = "Пассажиры";
            chartIn.Series[0].IsVisibleInLegend = false;
            chartIn.Series[0].Color = Color.Red; // Цвет диаграммы
            chartIn.Series[0].BorderWidth = 2; // Ширина линий диаграммы
            numericUpDownPasPeak.Value = 20;
            numericUpDownPasPeak2.Value = 25;
            numericUpDownPasOth.Value = 3;
            numericUpDownPasOth2.Value = 7;
            numericUpDownNPas.Value = nPas;
            numericUpDownNPas.Value = nStops;
            arrDiags = new int[nStops][]; // Массив диаграмм прихода пасссажиров на остановки
            ShowDiag(); // Показываем диаграмму
        }
        private void buttonClose_Click(object sender, EventArgs e)
        {
            this.Close();
        }
        // Показывает диаграмму
        private void readParams(int coef) // 60 или 3600
        {
            // Начало и конец утреннего интервала часов пик (единица измерения зависиит от coef)
            morn = (int)numericUpDownMorn.Value * coef;
            morn2 = (int)numericUpDownMorn2.Value * coef;
            if (morn2 <= morn) morn2 = morn + 3600; // Проверка
            // Начало и конец вечернего интервала часов пик (единица измерения зависиит от coef)
            ev = (int)numericUpDownEv.Value * coef;
            ev2 = (int)numericUpDownEv2.Value * coef;
            if (ev2 <= ev) ev2 = ev + 3600; // Проверка
            // Диапазон пассажиров, приходящих в часы пик
            pasPeak = (int)numericUpDownPasPeak.Value;
            pasPeak2 = (int)numericUpDownPasPeak2.Value;
            if (pasPeak2 <= pasPeak) pasPeak2 = pasPeak + 1; // Проверка
            // Диапазон пассажиров, приходящих в прочие часы
            pasOth = (int)numericUpDownPasOth.Value;
            pasOth2 = (int)numericUpDownPasOth2.Value;
            if (pasOth2 <= pasOth) pasOth2 = pasOth + 1; // Проверка
        }
        // Показывает диаграмму
        private void ShowDiag()
        {
            // Очищаем диаграмму (серию 0)
            chartIn.Series[0].Points.Clear();
            // Тип диаграммы
            if (radioButtonStepLine.Checked)
                // Столбцы
                chartIn.Series[0].ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.StepLine;
            else
                // Столбцы
                chartIn.Series[0].ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Column;
            // Начало и конец движения (в мин)
            int moveStart = (int)numericUpDownMove.Value * 60;
            int moveEnd = (int)numericUpDownMove2.Value * 60;
            int intLen = (int)numericUpDownInt.Value; // Длина интервала диаграммы прихода, с
            int N = (moveEnd - moveStart) / intLen + 1; // Число интервалов
            readParams(60);
            // Массив приходящих пассажиров
            int[] arrPasCome = new int[N];
            // Массив временных интервалов диаграммы
            int[] arrTimeInt = new int[N];
            int t = moveStart, pasCome;
            for (int k = 0; k < N; k++)
            {
                if (checkBoxWeekEnd.Checked)
                {
                    if (t >= morn && t <= morn2 || t >= ev && t <= ev2)
                        pasCome = rnd.Next(pasPeak, pasPeak2);
                    else if (t > morn2 && t < ev)
                        pasCome = (pasOth2 + pasPeak2) / 2;
                    else
                        pasCome = rnd.Next(pasOth, pasOth2);
                }
                else
                {
                    // Время может быть в одном из трех интервалов: утреннем, вечернем и прочем
                    if (t >= morn && t <= morn2 || t >= ev && t <= ev2)
                        // Пассажиры, пришедшие в часы пик
                        pasCome = rnd.Next(pasPeak, pasPeak2);
                    else
                        // Пассажиры, пришедшие в прочие часы
                        pasCome = rnd.Next(pasOth, pasOth2);
                }
                arrPasCome[k] = pasCome;
                arrTimeInt[k] = t;
                t += intLen; // Время текущего интервала
            }
            for (int k = 0; k < N; k++) chartIn.Series[0].Points.AddXY(arrTimeInt[k], arrPasCome[k]);
            // Корректировка после проверки
            numericUpDownMorn2.Value = Convert.ToDecimal(morn2 / 60);
            numericUpDownEv2.Value = Convert.ToDecimal(ev2 / 60);
            numericUpDownPasPeak2.Value = Convert.ToDecimal(pasPeak2);
            numericUpDownPasOth2.Value = Convert.ToDecimal(pasOth2);
        }
        private void buttonShow_Click(object sender, EventArgs e)
        {
            ShowDiag(); // Показываем диаграмму
        }
        private void radioButtonDiagType_CheckedChanged(object sender, EventArgs e)
        {
            ShowDiag(); // Показываем диаграмму
        }
        private void checkBoxLegend_CheckedChanged(object sender, EventArgs e)
        {
            chartIn.Series[0].IsVisibleInLegend = checkBoxLegend.Checked;
            ShowDiag(); // Показываем диаграмму
        }
        private void numericUpDown_ValueChanged(object sender, EventArgs e)
        {
            nStops = (int)numericUpDownNPas.Value;
            arrDiags = new int[nStops][]; // Массив диаграмм прихода пасссажиров на остановки
            ShowDiag(); // Показываем диаграмму
        }
        private void buttonGen_Click(object sender, EventArgs e)
        {
            GenDiags(); // Генерируем диаграммы и сохраняем их в файлы
            MessageBox.Show("Готово");
        }
        private void GenDiags()
        {
            int intLen = (int)numericUpDownInt.Value * 60; // Длина интервала диаграммы прихода, с
            int N = (tEnd + tGoLast - tStart) / intLen + 1; // Число интервалов
            int t, pasCome, nPas2 = 0; // Текущее время, число пассажиров, приходящих на остановку и общее число пассажиров
            int[] arrDiag;
            string fileSt;
            nPas = (int)numericUpDownNPas.Value;
            readParams(3600);
            sW = new StreamWriter(fileParams);
            sW.WriteLine(intLen); // Итервал диаграммы прихода
            sW.WriteLine(N); // Число интервалов
            // Начало и конец утреннего и вечернего интервалов часов пик, c
            sW.WriteLine(morn);
            sW.WriteLine(morn2);
            sW.WriteLine(ev);
            sW.WriteLine(ev2);
            sW.Close();
            for (int k = 0; k < nStops; k++)
            {
                arrDiag = new int[N];
                t = tStart;
                for (int k2 = 0; k2 < N; k2++)
                {
                    if (checkBoxWeekEnd.Checked)
                    {
                        if (t >= morn && t <= morn2 || t >= ev && t <= ev2)
                            pasCome = rnd.Next(pasPeak, pasPeak2);
                        else if (t > morn2 && t < ev)
                            pasCome = (pasOth2 + pasPeak2) / 2;
                        else
                            pasCome = rnd.Next(pasOth, pasOth2);
                    }
                    else
                    {
                        if (t >= morn && t <= morn2 || t >= ev && t <= ev2)
                            // Пассажиры, пришедшие в часы пик
                            pasCome = rnd.Next(pasPeak, pasPeak2);
                        else
                            // Пассажиры, пришедшие в прочие часы
                            pasCome = rnd.Next(pasOth, pasOth2);
                    }
                    arrDiag[k2] = pasCome;
                    nPas2 += pasCome;
                    t += intLen; // Время текущего интервала
                }
                arrDiags[k] = arrDiag;
            }
            //MessageBox.Show("" + nPas2);
            int d = (nPas2 < nPas ? 1 : -1);
            while (nPas2 != nPas)
            {
                for (int k = 0; k < nStops; k++)
                {
                    arrDiag = arrDiags[k];
                    for (int k2 = 0; k2 < N; k2++)
                    {
                        if (arrDiag[k2] > 3)
                        {
                            arrDiag[k2] += d;
                            nPas2 += d;
                            if (nPas2 == nPas)
                            {
                                arrDiags[k] = arrDiag;
                                break;
                            }
                        }
                    }
                    arrDiags[k] = arrDiag;
                    if (nPas2 == nPas) break;
                }
            }
            // Пишем диаграммы в файлы
            for (int k = 0; k < nStops; k++)
            {
                fileSt = fileStop + k + ".txt";
                sW = new StreamWriter(fileSt);
                arrDiag = arrDiags[k];
                for (int k2 = 0; k2 < N; k2++)
                {
                    sW.WriteLine(arrDiag[k2]);
                }
                Console.WriteLine("Сооздан файл " + fileSt);
                sW.Close();
            }
        }

        private void checkBoxWeekEnd_CheckedChanged(object sender, EventArgs e)
        {
            if(checkBoxWeekEnd.Checked)
            {
                numericUpDownPasPeak.Value = 30;
                numericUpDownPasPeak2.Value = 31;
                numericUpDownPasOth.Value = 10;
                numericUpDownPasOth2.Value = 11;
                numericUpDownMorn.Value = 8;
                numericUpDownMorn2.Value = numericUpDownMorn2.Maximum;
                numericUpDownEv.Value = 17;
                numericUpDownEv2.Value = numericUpDownEv2.Maximum;
            }
            else
            {
                numericUpDownPasPeak.Value = 20;
                numericUpDownPasPeak2.Value = 25;
                numericUpDownPasOth.Value = 5;
                numericUpDownPasOth2.Value = 15;
                numericUpDownMorn2.Value = 9;
                numericUpDownEv.Value = 17;
                numericUpDownEv.Value = 19;
            }
            ShowDiag();
        }
    }
}

Список работ

Рейтинг@Mail.ru