// header files #include #include "StandardConstants.h" #include "File_Input_Utility.h" #include "BasicUtilities.h" #include "CourseUtilities.h" #include "RoomUtilities.h" // local constants const int MAX_NUM_ROOMS = 25; const int MAX_NUM_COURSES = 25; const int NO_CLASS = -1; // local prototypes bool fitClassRooms( CourseArrayType *courseData, RoomArrayType *roomData, int initialRoomLevel, bool verboseFlag ); bool uploadData( const char *fileName, CourseArrayType *courseData, RoomArrayType *roomData ); // main function int main( int argc, char **argv ) { int initialRoomLevel = 0; RoomArrayType *rooms; CourseArrayType *courses; bool verboseSetting = true; printf( "\nCourse/Classroom Fit Program\n" ); printf( "============================\n" ); rooms = createRoomArray( MAX_NUM_ROOMS ); courses = createCourseArray( MAX_NUM_COURSES ); if( uploadData( "InputFiles/in_6.txt", courses, rooms ) ) { printf( "Start Solution Search\n" ); if( fitClassRooms( courses, rooms, initialRoomLevel, verboseSetting ) ) { printf( "\nFit Classroom Success: Solution Found.\n"); displayList( courses, rooms ); } else { printf( "\nFit Classroom Failure: Solution not found.\n"); } } else { printf( "Upload failure\n" ); } // end program // clear data rooms = clearRoomArray( rooms ); courses = clearCourseArray( courses ); // show program end printf( "\nEnd Course/Classroom Fit Program\n" ); // return success return 0; } /* Name: fitClassRooms Process: implements brute force recursive backtracking strategy to fit specified courses with their specified student size into classrooms with their specified capacity Function input/parameters: pointer to a courses array type (CourseArrayType *), pointer to a room array type (RoomArrayType *), room level shows which room is seeking a course and indicates the recursion level (int), verbose flag that specifies whether to display the recursive backtracking process (bool) Function output/parameters: updated courses file (CourseArrayType *), updated rooms file (RoomArrayType *) Function output/returned: Boolean result of the process (bool) Device input/---: none Device output/---: none Dependencies: available tools as needed */ bool fitClassRooms( CourseArrayType *courses, RoomArrayType *rooms, int roomLevel, bool verboseFlag ) { int arrayIterator; RoomDataType tempClassRoom; CourseDataType tempCourse; char buildingString[STD_STR_LEN]; char courseString[STD_STR_LEN]; // If all courses have been placed // return true if(roomLevel == rooms->size) { return true; } // setup for current classroom deepCopyRoom(&tempClassRoom, rooms->array[roomLevel]); deepCopyCourse(&tempCourse, courses->array[roomLevel]); setRoomDataString(buildingString, tempClassRoom); if(verboseFlag) { printf("\nRecursion Level %d: Seeking a fit for %s\n", roomLevel, buildingString); } for(arrayIterator = 0; arrayIterator < courses->size; arrayIterator++) { if(verboseFlag) { printSpaces(2); } // For Loop (Increments through courses) if(courses->array[arrayIterator].available && tempClassRoom.roomCapacity > courses->array[arrayIterator].size) { // Test to find classroom // If open and less than course size // Set classroom associated index to course rooms->array[roomLevel].associatedIndex = arrayIterator; // Set course as unavailable courses->array[arrayIterator].available = false; setCourseDataString(courseString, courses->array[arrayIterator]); if(verboseFlag) { printSpaces(2); printf("Trying Course Name: %s, Course Size: %d - Success!\n", courses->array[arrayIterator].courseName, courses->array[arrayIterator].size); printSpaces(6); printf("Course Name: %s, Course Size: %d will fit in %s\n", tempCourse.courseName, tempCourse.size, buildingString); } // Call and check next recursion if(fitClassRooms(courses, rooms, roomLevel + 1, verboseFlag)) { return true; } // Unset classroom associated index to course tempClassRoom.associatedIndex = NO_CLASS; // Set course as available courses->array[arrayIterator].available = true; } if(verboseFlag) { printf(" Trying Course Name: %s, Course Size: %d - Failed!\n", courses->array[arrayIterator].courseName, courses->array[arrayIterator].size); } // end for loop } if(verboseFlag) { printf("\nCourse Name: %s, Course Size: %d - recursion fell back to Recursion Level %d\n", tempCourse.courseName, tempCourse.size, roomLevel - 1); printSpaces(2); } return false; } /* Name: uploadData Process: uploads data file containing rooms available and courses to be fitted, has internal flag to show uploaded data or not Function input/parameters: file name (const char *), pointer to course array type (CourseArrayType*), pointer to room array type (RoomArrayType *) Function output/parameters: updated courses file (CourseArrayType *), updated rooms file (RoomArrayType *) Function output/returned: Boolean result of the process (bool) Device input/---: none Device output/---: none Dependencies: as needed, including File Input Utilities, and strcmp */ bool uploadData( const char *fileName, CourseArrayType *courseData, RoomArrayType *roomData ) { char tempStr[ STD_STR_LEN ]; int tempRoomNum, tempRoomCapacity, tempRoomAssociation = NO_CLASS; int tempClassSize, tempClassAvailable = true; bool verboseFlag = true; roomData->size = 0; if( openInputFile( fileName ) ) { if( verboseFlag ) { printf( "\n==========Upload start\n" ); } // ignore first line readStringToLineEndFromFile( tempStr ); // capture first room line - prime loop readStringToDelimiterFromFile( COMMA, tempStr ); // loop to end of room data while( strcmp( tempStr, "End Room Data" ) != 0 && roomData->size < roomData->capacity ) { tempRoomNum = readIntegerFromFile(); readCharacterFromFile(); tempRoomCapacity = readIntegerFromFile(); if( verboseFlag ) { printf( "Nm: %s, Num: %d, cap: %d\n", tempStr, tempRoomNum, tempRoomCapacity ); } addRoomWithData( roomData, tempStr, tempRoomNum, tempRoomCapacity, tempRoomAssociation ); // reprime - capture next building name, or end of data string readStringToDelimiterFromFile( COMMA, tempStr ); } // initialize class size courseData->size = 0; // ignore first line readStringToLineEndFromFile( tempStr ); // capture first course line - prime loop readStringToDelimiterFromFile( COMMA, tempStr ); // loop to end of course data while( strcmp( tempStr, "End Class Data" ) != 0 && courseData->size < courseData->capacity ) { // get class size tempClassSize = readIntegerFromFile(); if( verboseFlag ) { printf( "Nm: %s, sz: %d\n", tempStr, tempClassSize ); } addCourseWithData( courseData, tempStr, tempClassSize, tempClassAvailable ); // reprime - get next building name, or end of data string readStringToDelimiterFromFile( COMMA, tempStr ); } if( verboseFlag ) { printf( "==========Upload end\n\n" ); } return true; } return false; }