c语言实现移动电话系统
问题的提出:
现在你是JEJ移动通信公司负责规划的副经理。你刚刚得到频率执照允许在Flat Sport 市及其郊区,Burbville和Mosquito Lakes地区基本没有自己的工业,每天从这两个地区到Flat Spot市都有大量的人员流动。白天,Flat Spot市区的工作人员主要在市内活动;到了晚上,大量人群离开Flat Spot前往Burbville和Mosquito Lakes地区;而在深夜和周末,3个地区内及彼此间的人员流量一般,与人们日间工作时相仿。
你所在的移动通讯公司计划用微波发射器传送通话信号,为了以最优信号建立一个蜂窝通信网络需要考虑诸多因素:如地形,通信模式,无线电噪音源等。由于计划服务的3个地区主要为平原,基本没有干扰源,所以考虑的重点是通信模式。投资方为你提供的资源可以建造10个发射器用于通信,每个发射器可以同时处理200个呼叫信号并能可靠地覆盖一平方英里的范围。你还有关于3个地区每5*5英里的市场统计数据可以利用,这些数据预示了3个重要时段的通信需求:
工作日的上午8:30,此时进入Flat Spot市的人流达到高峰。
工作日的上午11:00,此时业务通话达到高峰。
星期六的中午,郊区通信达到高峰。
由于只有10个发射器无法覆盖整个地区,所以你需要编写程序对呼叫需求数据进行分析,以便发射器的配置能够为最大数量的潜在客户提供服务。
为了找到一个“折衷方案”,程序必须根据各数据项对于问题最终求解的重要性对现有数据进行评估。比如,若通勤者的通话模式每天仅有15分钟对顾客的满意程度有多重要?在我们的解决方案中,应该对3类数据加权计算,从而反映出各个数据集合的相对重要性。之后我们要探讨一下解决方案随权值的不同如何改变。
我们将图8.5所示的数据输入到三个5*5矩阵中,每个对应于一个数据集合。数据输入文件将为三个矩阵的每一个单元赋以3个值之一——0,1或2——以标识在各单元所对应的地点,在该矩阵所表示的时间观测到的通信密度的级别。扫描数据文件后,我们允许用户输入各数据集的相对权重,然后根据加权后的数据将10个发射器放置到10个通信最繁忙的单元。
数据要求
问题中的常量
GRID_SIZE 5/* 所讨论地区的长和宽英里数 */
NUM_TRANSMITTERS 10/* 放置的发射器的数量 */
SELECTED -1/* 以负值标识选中单元 */
问题输入
int commuters [GRID_SIZE] [GRID_SIZE]/*8:30 A.M.通信数据预测*/
int salesofrce [GIRD_SIZE] [GRID_SIZE]/*11 A.M. 通信数据预测*/
int weekend [GIRD_SIZE] [GRID_SIZE]/*周末通信数据预测*/
int commuter_weight /*通勤人员的权重因子*/
int salesforce_weight /*营销人员的权重因子*/
int weekend_weight /*周末数据的权重因子*/
问题输出
int summed_data [GRID_SIZE] [GRID_SIZE]/*加权后数据的输出*/
int location_i,location_j /*每个发射器的坐标*/
程序中的变量
int current_max /*到当前为止找到的最繁忙的通信点*/
C语言程序设计分析
程序首先从数据文件中读取通勤人员,销售人员和周末的有关数据填入三个矩阵,接着用户必须提供以衡量数据权重的整数。把每个矩阵中的数据乘以相应的权值,再将三个带权的矩阵对应元素相加,显示计算后的和矩阵。最后,和矩阵中NUM_TRANSMITTERS个最高值坐标将作为发射器的安放位置显示出来。
初始算法
1. 从数据文件中读取3个时段的交通数据。
2. 读入用户输入的权。
3. 各矩阵中的数据项与各自的权值相乘,把对应各数据项之和存入summed_data。
4. 找出矩阵summed_data中前NUM_TRANSMITTERS个最大量元素,将其下标逐一存储到location_i和location_j,并成队显示。
步骤4的细化
重复NUM_TRANSMITTERS次。
4.2 求出summed_data中的最大值的坐标(location-i,location-j)。
4.3 把求得的坐标作为发射器的位置显示。
4.4 将summed_data[location-i][location-j]标记为SELECTED。
C语言实现
步骤1 利用函数get-traffic-data实现。在图8.6所示的程序中我们首次见到程序所需要的数据来自两个输入源——文件和键盘。处理文件输入所用的函数是fopen,fscanf和fclose,与图5.12的考试分数中用法相同,而键盘输入则是调用scanf获得。
测试
测试时,为了便于手工验证,权值取1运行程序。权值为1时程序的运行情况如图8.7所示,交通数据如图8.5。由此可知发射器的确发放在了TRANSMITTERS个最大单元中。再次测试,前个权值取0,第三个取1,验证一下求和后的数据与权值取1的矩阵中原始的数据是否吻合。
/*
*利用交通高峰时的有关数据和用户提供的权重,确定移动通信网络的
*NUM-TRANSMITTERS个微波发射器的安放位置
*/
#include <stdio.h>
#define GRID-SIZE 5
#define SELECTED -1 /*低于矩阵中所有元素*/
#define TRAFFIC-FILE “traffic.dat”/*关于交通数据的文件*/
#define NUM-TRANSMITTERS 10 /*可用的发射器数量*/
void get-traffic-data(int commuters[GRID-SIZE][GRID-SIZE],
int salesforce[GRID-SIZE][GRID-SIZE],
int weekends [GRID-SIZE][GRID-SIZE];
voide print-matrix[GRID-SIZE][GRID-SIZE];
int
main(void)
{
int commuters[GRID-SIZE][GRID-SIZE];/*上午8:30的交通数据*/
int salesforce[GRID-SIZE][GRID-SIZE]; /*上午11:00的交通数据*/
int weekend[GRID-SIZE][GRID-SIZE];/*周末交通数据*/
int commuter-weight, /*通勤人员数据的权重因子*/
sale-weight,/*营销人员数据的权重因子*/
weekend-weight; /*周末数据的权重因子*/
int location-i, /*每个发射器的位置*/
location-j;
int current-max; /*和数据中当前的最大值*/
int i,j, /*矩阵的循环计数器*/
tr; /*发射器的循环计数器*/
/*填入并显示交通数据*/
Get-traffic-data (commuters,salesforce,weekend);
Printf(“8:30 A.M.WEEKDAY TRAFFIC DATA 、\n\n”)
print-matrix(commuters);
printf(“\n\n WEEKEND TRAFFIC DATA\n\n”);
print-matrix(salesforce);
printf(“\n\n WEEKEND TRAFFIC DATA\n\n”);
printf_matrix(weekeng);
/*请用户输入权重因子*/
printf(“\n\nPlease input the following value:\n”);
printf(“Weight (an interger>=0) for the 8:30 A.M.commuter data>”)
scanf(“%d”,&commuter_weight);
printf(“weight(an integer>=0) for the weekeng data>”);
scanf(“%d”,&weekend_weight);
scanf(“%d”,&weekend_weight);
/*计算并显示加权后求和的数据*/
for (i=0;i<GRID_SIZE;++i)
for (j=0;j<GRID_SIZE;++j)
summed_data[i][j]=commuter_weight*commuter[i][j]+
salesforce_weight*salesforce[i][j]+
weekend_weight*weekend[i][j];
printf(“\n\nThe weighted,summed data is :\n\n”);
printf_matrix(summed_data);
/*在summed_data矩阵中找出NUM_TRANSMITTERS个最大值,将坐标临时存储在location_i和location_j中,然后把最后的结果坐标输出*/
printf(“\n\nLocations of the %d transmitters:\n\n”,NUM_TRANSMITTERS);
for (tr=1;tr<=NUM_TRANSMITTERS;++tr){
current_max=SELECTED;/*以一个过低的值为起点开始查找*/
for (i=0;i<GRID_SIZE;++i){
for(j=0;j<GRID_SIZE;++j){
if(current_max<summed_data[i][j]){
current_max=summed_data[i][j]){
location_i=i;
location_j=j;
}
}
}
/*将选中的单元赋一较低的值以避免下次再选中这一元素,显示查找结果*/
summed_data[location_i][location_j]=SELECTED;
printf(“Transmitter %3d:at location %3d %3d\n”,
tr,location_i,location_j);
}
return (0);
}
/*
*把 TRAFFIC_FILE中的交通数据填充到3个GRID_SIZE×GRID_SIZE数组中
*/
void
get_traffic_data(int commuters[GRID_SIZE],/*输出*/
int salesforce[GRID_SIZE][GRID_SIZE],/*输出*/
int weekend[GRID_SIZE][GRID_SIZE],/*输出*/
{
int i,j; /*循环计数器*/
FILE *fp; /*文件指针*/
fq=fopen(TRAFFIC_FILE,“r”);
for(i=0;i<GRID_SIZE;++i)
for(j=0;j<GRID_SIZE;++j)
fscanf(fp,“%d”,&commnters[i][j];
for(i=0;i<GRID_SIZE;++j)
for(j=0;j<GRID_SIZE;++j)
fscanf(fq,“%d”,&weekend[i][j]);
fclose(fq);
}
/*
*显示一个GRID_SIZE×GRID_SIZE整数矩阵的内容
*/
void
print_matrix(int matrix[GRID_SIZE][GRID_SIZE])
{
int i,j; /*循环计数器*/
for(i=0;i<GRID_SIZE;++j)
{ for(j=0;j<GRID_SIZE;++J)
printf(“%3d”,matrix[i][j]);
printf(“\n”);
}
}
现在你是JEJ移动通信公司负责规划的副经理。你刚刚得到频率执照允许在Flat Sport 市及其郊区,Burbville和Mosquito Lakes地区基本没有自己的工业,每天从这两个地区到Flat Spot市都有大量的人员流动。白天,Flat Spot市区的工作人员主要在市内活动;到了晚上,大量人群离开Flat Spot前往Burbville和Mosquito Lakes地区;而在深夜和周末,3个地区内及彼此间的人员流量一般,与人们日间工作时相仿。
你所在的移动通讯公司计划用微波发射器传送通话信号,为了以最优信号建立一个蜂窝通信网络需要考虑诸多因素:如地形,通信模式,无线电噪音源等。由于计划服务的3个地区主要为平原,基本没有干扰源,所以考虑的重点是通信模式。投资方为你提供的资源可以建造10个发射器用于通信,每个发射器可以同时处理200个呼叫信号并能可靠地覆盖一平方英里的范围。你还有关于3个地区每5*5英里的市场统计数据可以利用,这些数据预示了3个重要时段的通信需求:
工作日的上午8:30,此时进入Flat Spot市的人流达到高峰。
工作日的上午11:00,此时业务通话达到高峰。
星期六的中午,郊区通信达到高峰。
由于只有10个发射器无法覆盖整个地区,所以你需要编写程序对呼叫需求数据进行分析,以便发射器的配置能够为最大数量的潜在客户提供服务。
为了找到一个“折衷方案”,程序必须根据各数据项对于问题最终求解的重要性对现有数据进行评估。比如,若通勤者的通话模式每天仅有15分钟对顾客的满意程度有多重要?在我们的解决方案中,应该对3类数据加权计算,从而反映出各个数据集合的相对重要性。之后我们要探讨一下解决方案随权值的不同如何改变。
我们将图8.5所示的数据输入到三个5*5矩阵中,每个对应于一个数据集合。数据输入文件将为三个矩阵的每一个单元赋以3个值之一——0,1或2——以标识在各单元所对应的地点,在该矩阵所表示的时间观测到的通信密度的级别。扫描数据文件后,我们允许用户输入各数据集的相对权重,然后根据加权后的数据将10个发射器放置到10个通信最繁忙的单元。
数据要求
问题中的常量
GRID_SIZE 5/* 所讨论地区的长和宽英里数 */
NUM_TRANSMITTERS 10/* 放置的发射器的数量 */
SELECTED -1/* 以负值标识选中单元 */
问题输入
int commuters [GRID_SIZE] [GRID_SIZE]/*8:30 A.M.通信数据预测*/
int salesofrce [GIRD_SIZE] [GRID_SIZE]/*11 A.M. 通信数据预测*/
int weekend [GIRD_SIZE] [GRID_SIZE]/*周末通信数据预测*/
int commuter_weight /*通勤人员的权重因子*/
int salesforce_weight /*营销人员的权重因子*/
int weekend_weight /*周末数据的权重因子*/
问题输出
int summed_data [GRID_SIZE] [GRID_SIZE]/*加权后数据的输出*/
int location_i,location_j /*每个发射器的坐标*/
程序中的变量
int current_max /*到当前为止找到的最繁忙的通信点*/
C语言程序设计分析
程序首先从数据文件中读取通勤人员,销售人员和周末的有关数据填入三个矩阵,接着用户必须提供以衡量数据权重的整数。把每个矩阵中的数据乘以相应的权值,再将三个带权的矩阵对应元素相加,显示计算后的和矩阵。最后,和矩阵中NUM_TRANSMITTERS个最高值坐标将作为发射器的安放位置显示出来。
初始算法
1. 从数据文件中读取3个时段的交通数据。
2. 读入用户输入的权。
3. 各矩阵中的数据项与各自的权值相乘,把对应各数据项之和存入summed_data。
4. 找出矩阵summed_data中前NUM_TRANSMITTERS个最大量元素,将其下标逐一存储到location_i和location_j,并成队显示。
步骤4的细化
重复NUM_TRANSMITTERS次。
4.2 求出summed_data中的最大值的坐标(location-i,location-j)。
4.3 把求得的坐标作为发射器的位置显示。
4.4 将summed_data[location-i][location-j]标记为SELECTED。
C语言实现
步骤1 利用函数get-traffic-data实现。在图8.6所示的程序中我们首次见到程序所需要的数据来自两个输入源——文件和键盘。处理文件输入所用的函数是fopen,fscanf和fclose,与图5.12的考试分数中用法相同,而键盘输入则是调用scanf获得。
测试
测试时,为了便于手工验证,权值取1运行程序。权值为1时程序的运行情况如图8.7所示,交通数据如图8.5。由此可知发射器的确发放在了TRANSMITTERS个最大单元中。再次测试,前个权值取0,第三个取1,验证一下求和后的数据与权值取1的矩阵中原始的数据是否吻合。
/*
*利用交通高峰时的有关数据和用户提供的权重,确定移动通信网络的
*NUM-TRANSMITTERS个微波发射器的安放位置
*/
#include <stdio.h>
#define GRID-SIZE 5
#define SELECTED -1 /*低于矩阵中所有元素*/
#define TRAFFIC-FILE “traffic.dat”/*关于交通数据的文件*/
#define NUM-TRANSMITTERS 10 /*可用的发射器数量*/
void get-traffic-data(int commuters[GRID-SIZE][GRID-SIZE],
int salesforce[GRID-SIZE][GRID-SIZE],
int weekends [GRID-SIZE][GRID-SIZE];
voide print-matrix[GRID-SIZE][GRID-SIZE];
int
main(void)
{
int commuters[GRID-SIZE][GRID-SIZE];/*上午8:30的交通数据*/
int salesforce[GRID-SIZE][GRID-SIZE]; /*上午11:00的交通数据*/
int weekend[GRID-SIZE][GRID-SIZE];/*周末交通数据*/
int commuter-weight, /*通勤人员数据的权重因子*/
sale-weight,/*营销人员数据的权重因子*/
weekend-weight; /*周末数据的权重因子*/
int location-i, /*每个发射器的位置*/
location-j;
int current-max; /*和数据中当前的最大值*/
int i,j, /*矩阵的循环计数器*/
tr; /*发射器的循环计数器*/
/*填入并显示交通数据*/
Get-traffic-data (commuters,salesforce,weekend);
Printf(“8:30 A.M.WEEKDAY TRAFFIC DATA 、\n\n”)
print-matrix(commuters);
printf(“\n\n WEEKEND TRAFFIC DATA\n\n”);
print-matrix(salesforce);
printf(“\n\n WEEKEND TRAFFIC DATA\n\n”);
printf_matrix(weekeng);
/*请用户输入权重因子*/
printf(“\n\nPlease input the following value:\n”);
printf(“Weight (an interger>=0) for the 8:30 A.M.commuter data>”)
scanf(“%d”,&commuter_weight);
printf(“weight(an integer>=0) for the weekeng data>”);
scanf(“%d”,&weekend_weight);
scanf(“%d”,&weekend_weight);
/*计算并显示加权后求和的数据*/
for (i=0;i<GRID_SIZE;++i)
for (j=0;j<GRID_SIZE;++j)
summed_data[i][j]=commuter_weight*commuter[i][j]+
salesforce_weight*salesforce[i][j]+
weekend_weight*weekend[i][j];
printf(“\n\nThe weighted,summed data is :\n\n”);
printf_matrix(summed_data);
/*在summed_data矩阵中找出NUM_TRANSMITTERS个最大值,将坐标临时存储在location_i和location_j中,然后把最后的结果坐标输出*/
printf(“\n\nLocations of the %d transmitters:\n\n”,NUM_TRANSMITTERS);
for (tr=1;tr<=NUM_TRANSMITTERS;++tr){
current_max=SELECTED;/*以一个过低的值为起点开始查找*/
for (i=0;i<GRID_SIZE;++i){
for(j=0;j<GRID_SIZE;++j){
if(current_max<summed_data[i][j]){
current_max=summed_data[i][j]){
location_i=i;
location_j=j;
}
}
}
/*将选中的单元赋一较低的值以避免下次再选中这一元素,显示查找结果*/
summed_data[location_i][location_j]=SELECTED;
printf(“Transmitter %3d:at location %3d %3d\n”,
tr,location_i,location_j);
}
return (0);
}
/*
*把 TRAFFIC_FILE中的交通数据填充到3个GRID_SIZE×GRID_SIZE数组中
*/
void
get_traffic_data(int commuters[GRID_SIZE],/*输出*/
int salesforce[GRID_SIZE][GRID_SIZE],/*输出*/
int weekend[GRID_SIZE][GRID_SIZE],/*输出*/
{
int i,j; /*循环计数器*/
FILE *fp; /*文件指针*/
fq=fopen(TRAFFIC_FILE,“r”);
for(i=0;i<GRID_SIZE;++i)
for(j=0;j<GRID_SIZE;++j)
fscanf(fp,“%d”,&commnters[i][j];
for(i=0;i<GRID_SIZE;++j)
for(j=0;j<GRID_SIZE;++j)
fscanf(fq,“%d”,&weekend[i][j]);
fclose(fq);
}
/*
*显示一个GRID_SIZE×GRID_SIZE整数矩阵的内容
*/
void
print_matrix(int matrix[GRID_SIZE][GRID_SIZE])
{
int i,j; /*循环计数器*/
for(i=0;i<GRID_SIZE;++j)
{ for(j=0;j<GRID_SIZE;++J)
printf(“%3d”,matrix[i][j]);
printf(“\n”);
}
}