238 lines
8.2 KiB
C
238 lines
8.2 KiB
C
#include <stdio.h>
|
||
#include <stdlib.h>
|
||
#include <string.h>
|
||
#include <time.h>
|
||
|
||
#define REQUEST_LENGTH 100
|
||
#define DISK_TRACKS 200
|
||
|
||
double fcfs(int* requestArray, int requestLength, int headStart, int* outputArray);
|
||
double sstf(int* requestArray, int requestLength, int headStart, int* outputArray);
|
||
double scan(int* requestArray, int requestLength, int headStart, int* outputArray);
|
||
double cscan(int* requestArray, int requestLength, int headStart, int* outputArray);
|
||
double fscan(int* requestArray1, int requestLength1, int* requestArray2, int requestLength2, int headStart, int *outputArray);
|
||
|
||
|
||
// 生成随机磁道访问序列
|
||
void generateRandomSequence(int* sequence, int length) {
|
||
for (int i = 0; i < length; i++) {
|
||
sequence[i] = rand() % DISK_TRACKS;
|
||
}
|
||
}
|
||
|
||
// 打印磁道访问顺序及平均寻道数
|
||
void printResults(const char* algorithmName, int* accessSequence, int length, double avgSeek) {
|
||
printf("%s Algorithm:\n", algorithmName);
|
||
printf("Visit Order: ");
|
||
for (int i = 0; i < length; i++) {
|
||
printf("%d ", accessSequence[i]);
|
||
}
|
||
printf("\nAvg Seek Times: %.2f\n\n", avgSeek);
|
||
}
|
||
|
||
int main() {
|
||
int requestSequence[REQUEST_LENGTH];
|
||
int *outputSequence[REQUEST_LENGTH];
|
||
int tempSequence[REQUEST_LENGTH];
|
||
double avgSeek;
|
||
int headStart = 50; // 假设的起始磁头位置
|
||
|
||
// 生成随机磁道访问序列
|
||
srand((unsigned)time(NULL));
|
||
generateRandomSequence(requestSequence, REQUEST_LENGTH);
|
||
|
||
// 测试 FCFS 算法
|
||
memcpy(tempSequence, requestSequence, sizeof(requestSequence));
|
||
avgSeek = fcfs(tempSequence, REQUEST_LENGTH, headStart, outputSequence);
|
||
printResults("FCFS", outputSequence, REQUEST_LENGTH, avgSeek);
|
||
|
||
// 测试 SSTF 算法
|
||
memcpy(tempSequence, requestSequence, sizeof(requestSequence));
|
||
avgSeek = sstf(tempSequence, REQUEST_LENGTH, headStart, outputSequence);
|
||
printResults("SSTF", outputSequence, REQUEST_LENGTH, avgSeek);
|
||
|
||
// 测试 SCAN 算法
|
||
memcpy(tempSequence, requestSequence, sizeof(requestSequence));
|
||
avgSeek = scan(tempSequence, REQUEST_LENGTH, headStart, outputSequence);
|
||
printResults("SCAN", outputSequence, REQUEST_LENGTH, avgSeek);
|
||
|
||
// 测试 CSCAN 算法
|
||
memcpy(tempSequence, requestSequence, sizeof(requestSequence));
|
||
avgSeek = cscan(tempSequence, REQUEST_LENGTH, headStart, outputSequence);
|
||
printResults("CSCAN", outputSequence, REQUEST_LENGTH, avgSeek);
|
||
|
||
// 测试 FSCAN 算法
|
||
// 注意:FSCAN需要两个队列,但为简化,在这里使用相同的队列两次
|
||
memcpy(tempSequence, requestSequence, sizeof(requestSequence));
|
||
avgSeek = fscan(requestSequence, REQUEST_LENGTH / 2, requestSequence + REQUEST_LENGTH / 2, REQUEST_LENGTH / 2, headStart, outputSequence);
|
||
printResults("FSCAN", outputSequence, REQUEST_LENGTH, avgSeek);
|
||
|
||
return 0;
|
||
}
|
||
|
||
|
||
double fcfs(int* requestArray, int requestLength, int headStart, int* outputArray) {
|
||
int totalMovement = 0;
|
||
int currentPosition = headStart;
|
||
|
||
for (int i = 0; i < requestLength; i++) {
|
||
// 计算当前请求和磁头位置之间的距离
|
||
totalMovement += abs(requestArray[i] - currentPosition);
|
||
// 移动磁头到当前请求位置
|
||
currentPosition = requestArray[i];
|
||
// 记录移动过程
|
||
outputArray[i] = currentPosition;
|
||
}
|
||
|
||
// 计算平均寻道数
|
||
return (double)totalMovement / requestLength;
|
||
}
|
||
|
||
double sstf(int* requestArray, int requestLength, int headStart, int* outputArray) {
|
||
int totalSeekCount = 0;
|
||
int processedCount = 0;
|
||
int currentPosition = headStart;
|
||
int minDistance, closestIndex;
|
||
|
||
// 初始化一个数组来标记已处理的请求
|
||
int processed[REQUEST_LENGTH] = {0};
|
||
for (int i = 0; i < requestLength; i++) processed[i] = 0;
|
||
|
||
while (processedCount < requestLength) {
|
||
minDistance = 2147483647;
|
||
|
||
// 找到最近的请求
|
||
for (int i = 0; i < requestLength; i++) {
|
||
if (!processed[i] && abs(requestArray[i] - currentPosition) < minDistance) {
|
||
minDistance = abs(requestArray[i] - currentPosition);
|
||
closestIndex = i;
|
||
}
|
||
}
|
||
|
||
// 处理这个请求
|
||
totalSeekCount += minDistance;
|
||
currentPosition = requestArray[closestIndex];
|
||
processed[closestIndex] = 1;
|
||
outputArray[processedCount++] = currentPosition;
|
||
}
|
||
|
||
// 计算平均寻道数
|
||
return (double)totalSeekCount / requestLength;
|
||
}
|
||
|
||
int compare(const void *a, const void *b) {
|
||
return (*(int*)a - *(int*)b);
|
||
}
|
||
|
||
double scan(int* requestArray, int requestLength, int headStart, int* outputArray) {
|
||
int totalSeekCount = 0;
|
||
int processedCount = 0;
|
||
int currentPosition = headStart;
|
||
|
||
// 使用qsort进行排序
|
||
qsort(requestArray, requestLength, sizeof(int), compare);
|
||
|
||
// 找到起始位置最近的请求
|
||
int startIndex;
|
||
for (startIndex = 0; startIndex < requestLength; startIndex++) {
|
||
if (requestArray[startIndex] >= headStart) break;
|
||
}
|
||
|
||
// 先向上移动
|
||
for (int i = startIndex; i < requestLength; i++) {
|
||
totalSeekCount += abs(currentPosition - requestArray[i]);
|
||
currentPosition = requestArray[i];
|
||
outputArray[processedCount++] = currentPosition;
|
||
}
|
||
|
||
// 然后向下移动
|
||
for (int i = startIndex - 1; i >= 0; i--) {
|
||
totalSeekCount += abs(currentPosition - requestArray[i]);
|
||
currentPosition = requestArray[i];
|
||
outputArray[processedCount++] = currentPosition;
|
||
}
|
||
|
||
// 计算平均寻道数
|
||
return (double)totalSeekCount / requestLength;
|
||
}
|
||
|
||
double cscan(int* requestArray, int requestLength, int headStart, int* outputArray) {
|
||
int totalSeekCount = 0;
|
||
int processedCount = 0;
|
||
int currentPosition = headStart;
|
||
|
||
// 使用 qsort 进行排序
|
||
qsort(requestArray, requestLength, sizeof(int), compare);
|
||
|
||
// 找到起始位置最近的请求索引
|
||
int startIndex;
|
||
for (startIndex = 0; startIndex < requestLength; startIndex++) {
|
||
if (requestArray[startIndex] >= headStart) break;
|
||
}
|
||
|
||
// 先处理磁头上方的请求
|
||
for (int i = startIndex; i < requestLength; i++) {
|
||
totalSeekCount += abs(currentPosition - requestArray[i]);
|
||
currentPosition = requestArray[i];
|
||
outputArray[processedCount++] = currentPosition;
|
||
}
|
||
|
||
// 如果有必要,跳转到最低请求
|
||
if (startIndex != 0) {
|
||
totalSeekCount += abs(currentPosition - requestArray[0]);
|
||
currentPosition = requestArray[0];
|
||
}
|
||
|
||
// 然后处理磁头下方的请求
|
||
for (int i = 0; i < startIndex; i++) {
|
||
totalSeekCount += abs(currentPosition - requestArray[i]);
|
||
currentPosition = requestArray[i];
|
||
outputArray[processedCount++] = currentPosition;
|
||
}
|
||
|
||
// 计算平均寻道数
|
||
return (double)totalSeekCount / requestLength;
|
||
}
|
||
|
||
void processQueue(int* queue, int length, int* currentPosition, int* totalSeekCount, int* outputArray, int* processedCount) {
|
||
// 对队列进行排序
|
||
qsort(queue, length, sizeof(int), compare);
|
||
|
||
// 找到最接近当前磁头位置的请求
|
||
int i = 0;
|
||
while (i < length && queue[i] < *currentPosition) {
|
||
i++;
|
||
}
|
||
|
||
// 先处理磁头位置之后(更高磁道号)的请求
|
||
for (int j = i; j < length; j++) {
|
||
*totalSeekCount += abs(*currentPosition - queue[j]);
|
||
*currentPosition = queue[j];
|
||
outputArray[(*processedCount)++] = queue[j];
|
||
}
|
||
|
||
// 再处理磁头位置之前(更低磁道号)的请求
|
||
for (int j = i - 1; j >= 0; j--) {
|
||
*totalSeekCount += abs(*currentPosition - queue[j]);
|
||
*currentPosition = queue[j];
|
||
outputArray[(*processedCount)++] = queue[j];
|
||
}
|
||
}
|
||
|
||
double fscan(int* requestArray1, int requestLength1, int* requestArray2, int requestLength2, int headStart, int* outputArray) {
|
||
int totalSeekCount = 0;
|
||
int currentPosition = headStart;
|
||
int processedCount = 0;
|
||
|
||
// 处理第一个队列
|
||
processQueue(requestArray1, requestLength1, ¤tPosition, &totalSeekCount, outputArray, &processedCount);
|
||
|
||
// 处理第二个队列
|
||
processQueue(requestArray2, requestLength2, ¤tPosition, &totalSeekCount, outputArray + requestLength1, &processedCount);
|
||
|
||
// 计算平均寻道数
|
||
return (double)totalSeekCount / (requestLength1 + requestLength2);
|
||
}
|
||
|
||
|