| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 3304 人关注过本帖
标题:VC++6.0 输出时显示1.#INF是什么原因?如何解决?
取消只看楼主 加入收藏
nuoyan_cfan
Rank: 1
等 级:新手上路
帖 子:7
专家分:0
注 册:2006-6-5
收藏
 问题点数:0 回复次数:6 
VC++6.0 输出时显示1.#INF是什么原因?如何解决?

我写了一个管理运筹学中的单纯形算法程序,大M法计算,数据使用了double型,但在迭代数次后显示出现1.#INF、-1.#INF这样的结果,而不是正确的小数类型,不知道什么原因。

以下是我的完整代码:

#include<iostream.h>
#include<string.h>
#include<iomanip.h>
#include<math.h>

#define LONG 251
#define MM 10000

/************变量声明***************/
int i=0,
j=0,
m=0, //约束条件个数
n=0, //变量个数
ziyou=0, //松弛变量个数
man=0, //人工变量个数
s=0, //主元列号
r=0, //行号
cnt=0, //记录迭代次数
k=0, //记录temp_a的行数
opt[LONG+1] //操作符 0、-1、1 表示等于、小于、大于
={0,-1,1,0};

char ziyoujie[50]="最优解:", //用于显示最优解和最优值
leixing[4]="Min"; //目标函数类型

double z, //目标函数值
yi[LONG+1]={0},
xianshi1[LONG+1][LONG+1]={0}, //用于显示结果
temp_a[LONG+1][LONG+1]={0}, //临时变量,辅助a的调整
temp_b[LONG+1]={0}, //临时变量,辅助b的调整
a[LONG+1][LONG+1] //系数矩阵
={{0},{0,1,-2,1},{0,-4,1,2},{0,-2,0,1}},

b[LONG+1] //不等式值
={0,11,3,1},

c[LONG+1] //原始目标函数
={0,-3,1,1},

temp=0,
d[LONG+1]={0}, //检验数
juece[LONG+1]; //决策变量

bool t=false; //辅助判断变量是否为基变量

/*-------------------------------函数声明--------------------------------*/
bool requirem(void){
int i=0;
for(i=1;i<=m;i++)
if(opt[i]>-1)
return true;
return false;
}

bool panduan_d(void){
/***********对应原理第四步,判断目标函数有无负值**************/
for(j=1;j<=n+ziyou+man;j++)
if(d[j]<0)
return false;
return true;
}

int find_s(void){
/***********找主元列。从行向量中选取最小的数,返回其位置**************/
int l=1;
temp=d[1];
for(i=2;i<=sizeof(d)/sizeof(double);i++){
if(d[i] < temp){
temp=d[i];
l=i;
}
}
return l;
}

bool panduan_r(int s){
/***********判断的r列的元素有无正值**************/
for(i=1;i<=m;i++)
if(a[i][s] > 0)
return true;
return false;
}

int find_r(int s){
/***********找主元行。从主元列中选取比之最小的行,返回其位置**************/
for(i=1;i<=m;i++)
if(a[i][s]>0){ //首先寻求一个正的元素
k=i;
break;
}
temp=b[k]/a[k][s];
for(i=k+1;i<=m;i++)
if(a[i][s]>=0 && b[i]/a[i][s]-temp < 0.00000001){
temp=b[i]/a[i][s];
return i; //找比值最小的行
}
return k;
}

bool nbv(void){
for(i=1;i<=m;i++)
if(juece[i] > n+ziyou)
return true;
return false;
}


void output(void){
cnt==0?cout<<"初始单纯形表为:\n":cout<<"第"<<cnt<<"次迭代,单纯形表为:\n";
cout<<'\t'<<"基变量";
cout<<'\n';
for(i=1;i<=m;i++){
cout<<'\t'<<'X'<<juece[i]<<" ";
for(j=1;j<=n+ziyou+man;j++){
cout<<'\t'<<a[i][j]<<" ";
}
cout<<'\t'<<b[i]<<'\n';
}

cout<<"检验数为:\t";
for(j=1;j<=n+ziyou+man;j++)
cout<<d[j]<<'\t';
cout<<'\n'<<setw(8)<<"Z="<<setprecision(6)<<z;
cout<<'\n';
}

void diedai(void){
/************对应原理第六步,完成迭代变换***********/
//double temp; //保存主元素的值
//double yi[LONG+1]={0}; //临时变量,用于存放每次迭代时每一行的比例因子
juece[r]=s;
temp=a[r][s];
for(j=1;j<=n+ziyou+man;j++)
a[r][j]=a[r][j]/temp;
b[r]=b[r]/temp; //变换主元素行
for(i=1;i<=m;i++){
yi[i]=a[i][s];
if(i!=r){ //变换主行以外的所有行
for(j=1;j<=n+ziyou+man;j++)
a[i][j]=a[i][j]-a[r][j]*yi[i]; //系数据阵的变换
b[i]=b[i]-b[r]*yi[i]; //检验数的变换
}
}
yi[m+1]=d[s]; //借用yi的第m+1行存放主元列所对应的目标函数系数
for(j=1;j<=n+ziyou+man;j++)
d[j]-=a[r][j]*yi[m+1]; //变换目标函数系数
z=z-yi[m+1]*b[r]; //更新目标函数值
for(i=1;i<=m;i++){
if(i==r)
a[i][s]=1;
else
a[i][s]=0; //变换主元素列
}
cnt++;
output();
}

void jisuan_d_z(void){
/******在目标函数中,加入人工变量和大M*******/
if(leixing=="Max")
for(j=n+ziyou+1;j<=n+ziyou+man;j++)
d[j]=-MM; //求最大化问题时人工变量系数取一个非常大的负数
else
for(j=n+ziyou+1;j<=n+ziyou+man;j++)
d[j]=MM; //求最大化问题时人工变量系数取一个非常大的正数

/******对应原理的第二步和第三步*******/
if(!strcmp(leixing,"Min"))
for(j=1;j<=n+ziyou+man;j++)
d[j]=-d[j]; //将最小化问题,转化为最大化问题
for(j=1;j<=n+ziyou+man;j++)
d[j]=-d[j]; //对于最大化问题,检验数为目标函数系数的相反数

z=0;
for(i=1;i<=m;i++){
temp=d[(int)juece[i]]; //临时变量存取比例因子
for(j=1;j<=n+ziyou+man;j++)
d[j]-=temp*a[i][j]; //求取检验数
z-=b[i]*temp; //求目标函数初始值
}
}

void main(){

/*--------------------初始化变量---------------------*/
for(i=1;i<=m;i++) //使右边非负
if(b[i]<0){
opt[i]=-opt[i];
for(j=0;j<=n;j++)
a[i][j]=-a[i][j];
}

/*---------------------变量赋值-----------------------*/
m=3;
n=3;

/*-------------------显示原始目标函数及约束条件----------------------*/
cout<<setw(10)<<"目标函数为:"<<leixing<<" Z=";
for(j=1;j<=n;j++){
c[j]>=0?cout<<"+"<<c[j]<<'x'<<j:cout<<c[j]<<'x'<<j;
}
cout<<'\n';
for(i=1;i<=m;i++){
for(j=1;j<=n;j++){
cout<<setw(4)<<a[i][j]<<" ";
}
cout<<setw(4)<<b[i]<<'\n';
}
//c[n+1]==1?cout<<">=":c[n+1]==0?cout<<"=":cout<<"<=";

cout<<'\n';
/*---------------------运算过程-----------------------*/
for(j=1;j<=n;j++)
d[j]=c[j];
if(requirem()){
cout<<"需要加入人工变量和大M\n\n";
}else{
cout<<"不需要加入大M\n\n";
}

/*--------------------对应原理的第一步,约束变换。加入松弛变量和人工变量,构造
不带目标函数的初始表格,并调整使基变量(juece)的后man行为人工变量---------------------*/

for(i=1;i<=m;i++)
for(j=1;j<=n;j++)
temp_a[i][j]=a[i][j]; //将系数矩阵付给临时变量

/******对于操作符是"<"的处理*******/
for(i=1;i<m;i++)
if(opt[i]==-1){
k++; //已变换的行数的累加
ziyou++; //松弛变量个数累加
for(j=1;j<=n;j++)
temp_a[i][j]=a[i][j]; //交换系数矩阵行
temp_a[k][n+ziyou]=1; //添加松弛变量系数
juece[k]=(n+ziyou); //记录决策变量
temp_b[k]=b[i]; //交换不等式常数项
}

/******对于操作符是">"的初步处理*******/
for(i=1;i<=m;i++)
if(opt[i]==1){
opt[i]=0; //将大于号转化为等于号
ziyou++;
temp_a[i][n+ziyou] = -1;
}

/******对于操作符是等于号,以及由大于号转换而来的情况的处理*******/
for(i=1;i<=m;i++)
if(opt[i]==0){
k++;
man++;
for(j=1;j<=n;j++)
temp_a[k][j]=a[i][j];
temp_a[k][n+ziyou+man]=1;
temp_b[k]=b[i];
juece[k]=(n+ziyou+man);
}

for(i=1;i<=m;i++)
for(j=1;j<=n+ziyou+man;j++)
a[i][j]=temp_a[i][j]; //将调整后的系数矩阵赋给a
for(i=1;i<=m;i++)
b[i]=temp_b[i]; //将调整后的不等式常数项付给b

jisuan_d_z();

//--------------显示初始单纯形表格------------------------------------
output();

//-------------------继续运算------------------------------------------

/******对目标函数系数全为非负值的处理*******/
loop:if(panduan_d()){
if(nbv()){
cout<<"原线性规划没有可行解!\n";
}else{
output();
cout<<'\n'<<ziyoujie<<'\n';
for(i=1;i<=n;i++){
t=false;
for(j=1;j<=m;j++)
if(juece[j]==i){
//strcat(ziyoujie,strcat("\nx",strcat((char*)&i,strcat("=",(char*)&b[j]))));
cout<<"x"<<i<<"="<<b[j]<<"\n";
t=true;
}
if(!t)
//strcat(ziyoujie,strcat(x,str(char*)&i));
cout<<"x"<<i<<"=0\n";
}
if(strcmp(leixing,"Min"))
z=-z;
cout<<"最优值为:Z="<<z<<'\n';
}

/******第一阶段的人工目标函数系数不全为正值的处理*******/
}else{ //存在负值,继续迭代
s=find_s();
if(panduan_r(s)){
r=find_r(s);
diedai();
goto loop;
}else{
output();
cout<<'\n'<<"原线性规划问题具有无界解。";
}
}
}

搜索更多相关主题的帖子: INF 输出 
2006-06-05 13:55
nuoyan_cfan
Rank: 1
等 级:新手上路
帖 子:7
专家分:0
注 册:2006-6-5
收藏
得分:0 

关键的问题应该在diedai()中:

void diedai(void){
/************对应原理第六步,完成迭代变换***********/
//double temp; //保存主元素的值
//double yi[LONG+1]={0}; //临时变量,用于存放每次迭代时每一行的比例因子
juece[r]=s;
temp=a[r][s];
for(j=1;j<=n+ziyou+man;j++)
a[r][j]=a[r][j]/temp;
b[r]=b[r]/temp; //变换主元素行
for(i=1;i<=m;i++){
yi[i]=a[i][s];
if(i!=r){ //变换主行以外的所有行
for(j=1;j<=n+ziyou+man;j++)
a[i][j]=a[i][j]-a[r][j]*yi[i]; //系数据阵的变换
b[i]=b[i]-b[r]*yi[i]; //检验数的变换
}
}
yi[m+1]=d[s]; //借用yi的第m+1行存放主元列所对应的目标函数系数
for(j=1;j<=n+ziyou+man;j++)
d[j]-=a[r][j]*yi[m+1]; //变换目标函数系数
z=z-yi[m+1]*b[r]; //更新目标函数值
for(i=1;i<=m;i++){
if(i==r)
a[i][s]=1;
else
a[i][s]=0; //变换主元素列
}
cnt++;
output();
}

大概是不同类型(int、double)之间运算产生的错误,请大虾帮忙,感激不尽!:)

2006-06-05 13:57
nuoyan_cfan
Rank: 1
等 级:新手上路
帖 子:7
专家分:0
注 册:2006-6-5
收藏
得分:0 
呵呵,C语言新手,风格上不够成熟,因为程序对我来说比较复杂,不得不加了很多注释在里面。不过你复制到VC6.0中看还是可以清晰点的(不知道您的机子上还有没有这个古董):P

int与double之间进行除法运算也会导致错误的结果吗?

我在google上根本搜索不到有关于输出1.#IND这种情况的答案!很郁闷了
2006-06-05 22:55
nuoyan_cfan
Rank: 1
等 级:新手上路
帖 子:7
专家分:0
注 册:2006-6-5
收藏
得分:0 
实在不行就只好换用别的语言重写一遍了,我倒是想用PHP,完全没有类型转换的麻烦.....
2006-06-05 22:57
nuoyan_cfan
Rank: 1
等 级:新手上路
帖 子:7
专家分:0
注 册:2006-6-5
收藏
得分:0 

原始程序是Pascal写的,我把它用C重新“翻译”了一遍,就变成这种效果了:P

2006-06-05 22:58
nuoyan_cfan
Rank: 1
等 级:新手上路
帖 子:7
专家分:0
注 册:2006-6-5
收藏
得分:0 
算法比较复杂,所以程序本身不需要您仔细研究(那是件比较漫长的事情),我所希望知道的就是#IND这种输出是怎样造成的,这样才能有针对的寻找解决途径:)
2006-06-05 23:03
nuoyan_cfan
Rank: 1
等 级:新手上路
帖 子:7
专家分:0
注 册:2006-6-5
收藏
得分:0 

确认是溢出造成的,应该是因为double型除以int型产生无限循环小数,结果导致溢出。

我写了一个求阶乘的程序尝试了一下,无论使用什么类型,结果过大时都会导致#INF这样的输出。

但是有没有办法更改VC++的运算精度呢?

2006-06-06 09:29
快速回复:VC++6.0 输出时显示1.#INF是什么原因?如何解决?
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.025694 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved