2012-03-28 103 views
0

嗨我有一个家庭作业,我需要在两个小时内实现两条单线道的交叉口。我需要调整阶段,以便每个队列理想地少于5辆车,9也是可以接受的。实现与链接列表堆栈的交集。

除了一些事情,所有的作品都是我的阶段实施的方式不对,我似乎无法解决问题。我能得到的绝对最好是一个队列是0或1,另一个队列是40+。我似乎无法将他们两人都置于9以下。我已将问题归结于阶段检查,但无法想出解决问题的方法。我知道我希望稍微倾向Q1,因为汽车的到达速度比Q2快一点。

在此先感谢您的帮助。

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

using namespace std; 

struct Node { 
    int data; 
    Node *next; 
}; 

class Queue { 
private:       
    Node *listpointer; 
public:       
    Queue(); 
    ~Queue(); 
    void push(int newthing); 
    void pop(); 
    int top(); 
    bool isEmpty(); 
    int queueCount(); 
    void Queue::popTwo(); 
    bool Queue::twoOrMore(); 
}; 

Queue::Queue() { 
//constructor 
    listpointer = NULL; 
} 

Queue::~Queue() { 
//destructor 

} 

void Queue::push(int newthing) { 
//place the new thing on top of the Queue 
    Node *temp; 
    temp = new Node;    
    temp->data = newthing; 
    temp->next = listpointer; 
    listpointer = temp; 
} 

void Queue::pop() { 
//remove top item from the Queue 
    Node *p; 
    p = listpointer; 
    if (listpointer != NULL) { 
     listpointer = listpointer->next; 
     delete p; 
    } 
} 

int Queue::top() { 
//return the value of the top item 
    return listpointer->data; 
} 

bool Queue::isEmpty() { 
//returns true if the Queue is empty 
    if (listpointer == NULL) { 
     return true; 
    } 
    return false; 
} 

int Queue::queueCount() { 
    Node *temp; 
    int count = 0; 
    temp = listpointer; 
    while (temp != NULL) { 
     ++count; 
     temp = temp->next; 
    } 
    return count; 
    delete temp; 
} 

void Queue::popTwo() { 
// remove the 2 top items from the stack 
    Node *p; 
    p = listpointer; 
    if (listpointer != NULL) { 
     listpointer = listpointer->next; 
     delete p; 
    } 
    p = listpointer; 
    if (listpointer != NULL) { 
     listpointer = listpointer->next; 
     delete p;     
    } 
} 

bool Queue::twoOrMore() { 
// return true if the stack has at least two items 
    if(listpointer==NULL || listpointer->next==NULL) return false; 
    else return true; 
} 

//implement/copy your queue structure and functions above 
//then, declare two instances: 
//Queue Q1, Q2; 
//if you want, make a separate function to change the 
//signals between the queues (either green or red) 
//When the signal changes, one queue only is allowed to delete elements 

Queue Q1, Q2; 

int Q1phase = 30; //initial attempt 
int Q2phase = 60; //initial attempt 
const int Q1arrive = 18; //fixed 
const int Q2arrive = 22; //fixed 
const int leave_rate = 10; //fixed, one car leaves either queue every 10 seconds 

int car_id=0; 
int clock=0; 
bool Q1_green, Q2_green; //indicates which queue is opened, only one at a time 

int main(int argc, char **argv) { 
    //if(argc!=3) {printf("needs: Q1phase Q2phase\n"); exit(0); } 
    //Q1phase=atoi(argv[1]); 
    //Q2phase=atoi(argv[2]); 
    if(Q1phase < 30 || Q2phase < 30) {printf("Minimum time for each queue to be closed is 30 seconds\n"); exit(0);} 
    clock = 0; 
    car_id = 0; 
    Q1_green = true; 
    Q2_green = false; 
    int length_Q1, length_Q2; 
    length_Q1 = 0; 
    length_Q2 = 0; 

    while (clock < 7200) { 
     clock++; 
     if (clock % Q1arrive == 0) { 
      car_id++; 
      //car_id join Q1 
      Q1.push(car_id); 
      length_Q1 = Q1.queueCount(); 
     } 
     if (clock % Q2arrive == 0) { 
      car_id++; 
      //or car_id join Q2 
      Q2.push(car_id); 
      length_Q2 = Q2.queueCount(); 
     } 

     if ((clock % Q1phase == 0) || (clock % Q2phase == 0)) { 
      if (Q1_green == true) { 
       Q1_green = false; 
       Q2_green = true; 
      } else { 
       Q1_green = true; 
       Q2_green = false; 
      } 
     } 

     if (clock % leave_rate == 0) { 
      if (Q1_green == true) { 
       Q1.pop(); 
       length_Q1 = Q1.queueCount(); 
      } 

      if (Q2_green == true) { 
       Q2.pop(); 
       length_Q2 = Q2.queueCount(); 
      } 
     } 

    //ChangeSignal();//every second, check if it is time to change signals (phasing is important!) 
    //After the signal change: 
    //verify which queue is opened 
    //either Q1 or Q2 will have the chance to delete one element (Q.Leave()) 
    // 
    printf("at time %d:\nthe current length of Q1 is %d\n",clock,length_Q1); 
    printf("the current length of Q2 is %d\n", length_Q2); 
    //at the end of the simulation, both queues should have few cars 
    } 
} 
+0

你有跟踪如何队列随时间变化,以及如何灯随时间而变化?如果不一定如何解决问题,这可能会给出线索。 – 2012-03-28 00:21:31

+1

您的程序中有一大块代码是重新创建已经使用C++语言的数据结构。这是作业的必要部分吗?即是模拟交叉点,还是制作队列数据结构,还是两者的作业?重新设计这个轮子会让程序的主要目的分散注意力,同时也会使您浪费时间来调试队列数据结构,而不是模拟逻辑。家庭作业是一个阻力,所以不要花费不必要的时间。 – Kaz 2012-03-28 00:24:40

+0

我追踪了灯光随着时间的推移如何变化,但它仍然让我感到困惑。它真的是模拟真正简单的交集并创建队列数据结构。所以大部分都是必要的,但它也是由讲师作为模板给出的。我认为这两个阶段是不必要的,但我很确定他们是必需的。 – RedFred 2012-03-28 00:30:03

回答

0

您的总抵达率超过了休假率,所以汽车将不得不积压。

总抵达率是1/22 + 1/18 =~ 0.1010汽车/秒。这超过了每秒0.1汽车的休假率。

灯光每30秒更换一次(Q1phase),因为Q2phaseQ1phase的倍数。所以基本上这些队列有相同的工作周期。

汽车从每个队列中排出总费用的一半:一个队列为0.05,另一队列为0.05(1/20)。

请注意,休假率为1/20小于1/18。所以1/18到来的队列将会积压。 1/20的离开率大于1/22,所以具有1/22到达率的队列不会积压。

这个微小的差异并不是很微小!到达率超过休假率或不超过休假率的情况存在差异。


哦,这里是如何计算汽车在拖后队列:

到达率:1/18。 退出率:1/20(1/10的一半) 总时间:7200秒:

7200 *(1/18) - 7200 *(1/20)== ????

:)

+0

好吧,我明白这一点,但我可以改变的唯一变量是Q1phase和Q2phase。 – RedFred 2012-03-28 00:54:13

+0

排队有时是违反直觉的。 **整体**抵达率和休假率并不能预测40辆汽车的积压。但是你必须了解它的方式是,一个队列中的快速处理不会给你一个**信用额**,可以用于其他队列中的待办事项。当一个队列没有汽车在等待时,这对另一个队列没有任何帮助。 – Kaz 2012-03-28 01:03:23

+0

换句话说,这个问题可能会导致积压只有7辆车。为什么?因为这是* system * arrrival和leave rate的差异乘以7200.所以我理解你的任务:操纵阶段,试图让队列降低到接近整个系统的速率预测值。祝你好运! – Kaz 2012-03-28 01:04:36