-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathch2_10.java
More file actions
171 lines (163 loc) · 4.67 KB
/
Copy pathch2_10.java
File metadata and controls
171 lines (163 loc) · 4.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
public class ch2_10
{
static final int MaxNum=10; //变量数量的最大值
// static int array[][]={{3,5,-4,0},
// {7,2,6,-4},
// {4,-1,5,-5}}; //输入的增广矩阵
static int array[][]={{1,2,3,1},
{2,4,6,2},
{3,6,9,3}};
static int[] unuse_result=new int[MaxNum]; //判断是否是不确定的变量
static int GaussFun(int equ,int var,int result[]) //高斯消元法算法
{
int i,j,k,col,num1,num2;
int max_r,ta,tb,gcdtemp,lcmtemp;
int temp,unuse_x_num,unuse_index=0;
col=0; //第1列开始处理
for(k=0;k<equ && col<var;k++,col++) //循环处理增广矩阵中的各行
{
max_r=k; //保存绝对值最大的行号
for(i=k+1;i<equ;i++)
{
if(Math.abs(array[i][col])>Math.abs(array[max_r][col]))
{
max_r=i; //保存绝对值最大的行号
}
}
if(max_r!=k) //最大行不是当前行,则与第k行交换
{
for(j=k;j<var+1;j++) //此时当前列左侧全为0,只需交换当前列右侧数据(交换矩阵右上角数据)
{
temp=array[k][j];
array[k][j]=array[max_r][j];
array[max_r][j]=temp;
}
}
if(array[k][col]==0) //说明col列第k行以下全是0,则处理当前行的下一列
{
k--;
continue;
}
for(i=k+1;i<equ;i++) //查找要删除的行
{
if(array[i][col]!=0) //如果左列不为0,进行消元运算
{
num1=Math.abs(array[i][col]);
num2=Math.abs(array[k][col]);
while(num2!= 0)
{
temp=num2;
num2=num1%num2;
num1=temp;
}
gcdtemp=num1; //最大公约数
lcmtemp=(Math.abs(array[i][col]) * Math.abs(array[k][col]))/gcdtemp;//求最小公倍数
ta=lcmtemp/Math.abs(array[i][col]);
tb=lcmtemp/Math.abs(array[k][col]);
if(array[i][col]*array[k][col]<0) //如果两数符号不同
{
tb=-tb; //异号的情况是两个数相加
}
for(j=col;j<var+1;j++)
{
array[i][j]=array[i][j]*ta-array[k][j]*tb;
}
}
}
}
for(i=k;i<equ;i++) //判断最后一行最后一列
{
if(array[i][col]!=0) //若不为0,表示无解
{
return -1; //返回-1,表示无解
}
}
if(k<var) //自由变量有var-k个,即不确定的变量至少有var-k个.
{
for(i=k-1;i>=0;i--)
{
unuse_x_num=0; //判断该行中不确定变量数量,
for(j=0;j<var;j++)
{
if(array[i][j]!=0 && unuse_result[j]!=0)
{
unuse_x_num++;
unuse_index=j;
}
}
if(unuse_x_num>1)
{
continue; //若超过1个,则无法求解
}
temp=array[i][var];
for(j=0;j<var;j++)
{
if(array[i][j]!=0 && j!=unuse_index)
{
temp-=array[i][j]*result[j];
}
}
result[unuse_index]=temp/array[i][unuse_index]; //求出该变量
unuse_result[unuse_index]=0; //该变量是确定的
}
return var-k; //自由变量有var-k个
}
for(i=var-1;i>=0;i--) //求解
{
temp=array[i][var]; //当前行最后一个元素
for(j=i+1;j<var;j++) //循环处理当前行表达式
{
if(array[i][j]!=0)
{
temp-=array[i][j]*result[j]; //每次减去前一项系数及解的积
}
}
if(temp % array[i][i]!=0) //若不能整除
{
return -2; //返回有浮点数解,但无整数解
}
result[i]=temp/array[i][i]; //表达式剩最后两项,直接相除得解,存储起来
}
return 0;
}
public static void main(String[] args)
{
int i, type;
int equnum, varnum;
int[] result=new int[MaxNum]; //保存方程的解
equnum=3;
varnum=3;
type=GaussFun(equnum,varnum,result); //调用高斯方法
if(type==-1) //无解
{
System.out.printf("该方程无解!\n");
}
else if(type==-2) //只有浮点数解
{
System.out.printf("该方程有浮点数解,无整数解!\n");
}
else if(type>0) //无穷多个解
{
System.out.printf("该方程有无穷多解! 自由变量数量为%d\n",type);
for(i=0;i<varnum;i++)
{
if(unuse_result[i]!=0)
{
System.out.printf("x%d 是不确定的\n",i+1);
}
else
{
System.out.printf("x%d: %d\n",i+1,result[i]);
}
}
}
else
{
System.out.printf("该方程组的解为:\n");
for(i=0;i<varnum;i++) //输出解
{
System.out.printf("x%d=%d\n",i+1,result[i]);
}
}
}
}