2024-09-05 13:31:02 +08:00

238 lines
8.2 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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, &currentPosition, &totalSeekCount, outputArray, &processedCount);
// 处理第二个队列
processQueue(requestArray2, requestLength2, &currentPosition, &totalSeekCount, outputArray + requestLength1, &processedCount);
// 计算平均寻道数
return (double)totalSeekCount / (requestLength1 + requestLength2);
}