Exemple #1
0
// Helper function that writes down the train car IDs into a vector,
// to allow faster calculation of link/unlink/shift costs
std::vector<int> RecordIDs(TrainCar* t1) {
  std::vector<int> answer;
  TrainCar* tmp = t1;
  // loop over all the train cars and store the car IDs in a vector
  while (tmp != NULL) {
    answer.push_back(tmp->getID());
    tmp = tmp->next;
  }    
  return answer;
}
Exemple #2
0
// Returns a pointer to the final car of a given type in a train.
// Returns NULL if there is no car of given type.
TrainCar* Train::getFinalCarOfType(TrainCar::cType type){
	TrainCar* nodeOn = m_head;
	TrainCar* lastOfType = NULL;
	while(nodeOn->m_next != NULL) {
		if(nodeOn->getType() == type) {
			lastOfType = nodeOn;
		}
		nodeOn = nodeOn->m_next;
	}
	return lastOfType;
}
Exemple #3
0
// Returns a pointer to the Nth car of a given type in the train.
// Returns NULL if no car of that type or number appears in the train.
// Count starts at 1.
TrainCar* Train::getNthCarOfType(TrainCar::cType type, int n) {
	TrainCar* nodeOn = m_head;
	TrainCar* nthCar = NULL;
	// The number of cars of a given type found.
	int foundSoFar = 0;
	while(nodeOn->m_next != NULL && nthCar == NULL) {
		if(nodeOn->getType() == type) {
			foundSoFar++;
		}

		if(foundSoFar == n) {
			nthCar = nodeOn;
		}

		nodeOn = nodeOn->m_next;
	}
	return nthCar;
}
Exemple #4
0
void SimpleTrainTest() {
  std::cout << "============================================================================" << std::endl;
  std::cout << "SIMPLE TRAIN TEST" << std::endl;

  // create a train with 6 dynamically-allocated cars in a doubly-linked list structure
  TrainCar* simple = NULL;
  PushBack(simple, TrainCar::MakeEngine()); 
  PushBack(simple, TrainCar::MakePassengerCar());
  PushBack(simple, TrainCar::MakePassengerCar());
  PushBack(simple, TrainCar::MakeDiningCar());
  PushBack(simple, TrainCar::MakePassengerCar());
  PushBack(simple, TrainCar::MakeSleepingCar());

  // inspect the cars, the links, the links, and sequential IDs...
  assert (simple->isEngine());
  assert (simple->prev == NULL);
  assert (simple->next->isPassengerCar());
  assert (simple->next->prev->isEngine());
  assert (simple->next->next->isPassengerCar());
  assert (simple->next->next->next->isDiningCar());
  assert (simple->next->next->next->next->isPassengerCar());
  assert (simple->next->next->next->next->next->isSleepingCar());
  assert (simple->next->next->next->next->next->next == NULL);
  assert (simple->next->getID() == simple->getID()+1);
  assert (simple->next->next->getID() == simple->next->getID()+1);
  assert (simple->next->next->next->getID() == simple->next->next->getID()+1);
  assert (simple->next->next->next->next->getID() == simple->next->next->next->getID()+1);
  assert (simple->next->next->next->next->next->getID() == simple->next->next->next->next->getID()+1);

  // helper routine sanity check & print the results
  SanityCheck(simple);
  PrintTrain(simple);

  // fully delete all TrainCar nodes to prevent a memory leak
  DeleteAllCars(simple);
}
void Separate(TrainCar* &train1,TrainCar* &train2,TrainCar* &train3){
    int num = Calculate_numcars_apart_from_engines(train1);
    int num_of_engine = Calculate_num_of_engines(train1);
    int num_trains = 2;
    int ideal_engine_first_car = num_of_engine / num_trains;
    assert(ideal_engine_first_car != 0);
    float temp_num_of_engine = num_of_engine;
    //---------------------------------------------------------------------------
    // Rounded to the closest integer:
    int num_nonengine_cars = num * (ideal_engine_first_car / temp_num_of_engine);
    float temp_stata = num * (ideal_engine_first_car / temp_num_of_engine);
    if ((temp_stata - num_nonengine_cars) > 0.5 ) {
        num_nonengine_cars += 1;
    }
    assert(num_nonengine_cars != 0);
    // Try to find the optimal situation, if this situation exists, we just need to cut one time
    // in the middle.
    //---------------------------------------------------------------------------------------
    int alternative_noengine_cars = num - num_nonengine_cars;
    int alternative_engines = num_of_engine - ideal_engine_first_car;
    bool found_optimal_solution = false;
    int count_cars = 0;
    int count_engines = 0;
    while (train1->next != NULL) {
        if (train1->isEngine()) {
            count_engines++;
        } else {
            count_cars ++;
        }
        
        if ((count_engines == ideal_engine_first_car && count_cars == num_nonengine_cars)
            || (count_engines == alternative_engines && count_cars == alternative_noengine_cars)) {
            // If the optimal conditions meet, we can just break one time in the middle:
            train2 = train1;
            train3 = train1->next;
            train2->next = NULL;
            train3->prev = NULL;
            while (train2->prev != NULL) {
                train2 = train2->prev;
            }
            found_optimal_solution = true;
        }
        if (!found_optimal_solution) {
            train1 = train1->next;
        }
    }
    if (found_optimal_solution) {
        train1 = train1->next;
    } else {
        while (train1 ->prev != NULL) {
            train1 = train1->prev;
        }
    }
    //------------------------------------------------------------------------------------
    // If we didn' t find the optimal situation: then use normal way:
    if (! found_optimal_solution) {
    //---------------------------------------------------------------------------
    // Generally, I use the nonengine car number to calculate.
    // Since there are only two trains, we just need to separate engines and cars into two trains.
    // If they are not equal, I just try to get one more car in one side.
    // My logic is first calculate the optimal number of engines. When the nonengine car number hits
    // the ideal number, the engine number may be bigger, equal or smaller
    // 1) if it is equal, just break in the middle
    // 2) if it is smaller, just go to the other side, everytime I hits an engine, remove it and insert
    // to the previous train.
    // 3) if it is bigger, reverse
    // Since I have consider the optimal situation before, I don't need to consider here.
        int count = 0;
        int count_engine = 0;
        while (train1 != NULL) {
            if (! train1->isEngine()) {
                count ++;
            } else {
                count_engine++;
            }
            
            if (count == num_nonengine_cars) {
                // There are three situations:
                // If the number of engines of the first train is equal to the ideal engines number:
                //---------------------------------------------------------------------------------
                if (count_engine == ideal_engine_first_car) {
                    train2 = train1;
                    train3 = train1->next;
                    train3->prev = NULL;
                    train2->next = NULL;
                    // Go back to the head
                    while (train2->prev!= NULL) {
                        train2 = train2->prev;
                    }
                    
                    while (train1->next != NULL) {
                        train1 = train1->next;
                    }
                } else if (count_engine < ideal_engine_first_car){
                    // count_engine > ideal_engine_first_car
                    //--------------------------------------------
                    train2 = train1;
                    // Go back to the head
                    while (train2->prev!= NULL) {
                        train2 = train2->prev;
                    }
                    //-----------------------------------
                    int needed_engines = ideal_engine_first_car - count_engine;
                    int specialcounter = 0;
                    int i =0;
                    TrainCar* temp = train1;
                    while (i < needed_engines) {
                        temp = temp->next;
                        if (temp->isEngine()) {i ++;}
                        specialcounter++;
                    }
                    //------------------------------------
                    if (i == specialcounter) { // Special case
                        train3 = temp->next;
                        temp->next = NULL;
                        train3->prev = NULL;
                        
                    } else {
                        TrainCar* p = train1->next;
                        train1->next = NULL;// train1 keep track of the ending car of the first train
                        p->prev = NULL;
                        train3 = p;
                        // Make train3 to the first nonengine car
                        while (train3->isEngine()) {
                            train3 = train3->next;
                        }
                        TrainCar* q = p;
                        i = 0;
                        while (i < needed_engines) {
                            q = p->next;
                            if (p->isEngine()) {
                                remove_cars(p);
                                insert_cars_prev(train1, p);
                                train1 = train1->next;
                                i ++;
                            }
                            p = q;
                        }
                        while (train3->prev != NULL) {
                            train3 = train3->prev;
                        }
                    }
                    while (train1->next != NULL) {
                        train1 = train1->next;
                    }
                } else {
                    // count_engine > ideal_engine_first_car
                    //------------------------------------------------------------------------
                    train2 = train1;
                    // Go back to the head
                    while (train2->prev!= NULL) {
                        train2 = train2->prev;
                    }
                    //-----------------------------------
                    train1 = train1->next;
                    TrainCar* temp = train1;
                    int needed_engines = count_engine - ideal_engine_first_car;
                    int specialcounter = 0;
                    int i =0;
                    while (i < needed_engines) {
                        temp = temp->prev;
                        if (temp->isEngine()) {i ++;}
                        specialcounter++;
                    }
                    //------------------------------------------
                    if (i == specialcounter) { // Special case
                        train3 = temp;
                        TrainCar* temp1 = temp->prev;
                        train3->prev = NULL;
                        temp1->next = NULL;
                    } else {
                        train3 = temp;
                        TrainCar* p =train1->prev;
                        train1->prev = NULL;
                        p->next = NULL;
                        TrainCar* q = p;
                        i = 0;
                        while (i < needed_engines) {
                            q = p->prev;
                            if (p->isEngine()) {
                                remove_cars(p);
                                insert_cars_next(train1, p);
                                train1 = train1->prev;
                                i ++;
                            }
                            p = q;
                        }
                        while (train3->prev != NULL) {
                            train3 = train3->prev;
                        }
                    }
                    while (train1->next != NULL) {
                        train1 = train1->next;
                    }
                }
            }
            train1 = train1->next;
        }
    }
}