以前學運籌學寫的作業,單純形法(純C實現)
#include <stdio.h>
#define N 5
#define M 3
int max(int x, int y)
{
if(x>y)
return(x);
else
return(y);
}
int min(int x, int y)
{
if(x<y)
return(x);
else
return(y);
}
int main()
{
inti, j, p, m, n, k, l, r, u, v, t, X[M];
float z = 0, d[N], f[M], s[N], g[M];
for(i = 0; i < M; i++)
X[i] = i + 1 + N - M;
floatc[N] = { 2, 3, 0, 0, 0}, e[M] = { 12, 16, 15 },
a[M][N] =
{ { 2, 2, 1, 0, 0 },
{ 4, 0, 0, 1, 0 },
{ 0, 5, 0, 0, 1 } };
for(i = 0; i < M; i++)
g[i] = c[N - M + i];
for(j = 0; j < N; j++)
{
p = 0;
for (i = 0; i < M; i++)
{
f[i] = g[i] * a[i][j];
s[j] = p + f[i];
}
}
for(j = 0; j < N; j++)
{
d[j] = c[j] - s[j];
}
for(j = 0, k = d[0], n = 0; j <= N - 1; j++)
{
if (max(k, d[j])>k)
{
k = max(k, d[j]);
n = j;
}
}
for(i = 0, m = a[0][n], p = 0; i < M; i++)
{
if (max(a[i][n], m)>m)
{
m = max(a[i][n], m);
p = i;
}
}
while((d[n] > 0) && (a[p][n] > 0))
{
for (i = 1, l = e[0] / a[0][n], m = 0; i < M; i++)
{
if (a[i][n] == 0)
continue;
else if (min(l, (e[i] / a[i][n])) < l)
{
l = min(l, e[i] / a[i][n]);
m = i;
}
}
printf("X%d出,X%d進\n", m + N - M + 1, n + 1);
X[m] = n + 1;
g[m] = c[n];
for (i = 0; i < m; i++)
{
e[i] = e[i] - e[m] * a[i][n] / a[m][n];
for (j = 0; j < n; j++)
{
a[i][j] = a[i][j] - a[m][j] *a[i][n] / a[m][n];
d[j] = d[j] - a[m][j] * d[n] /a[m][n];
}
for (j = n + 1; j < N; j++)
{
a[i][j] = a[i][j] - a[m][j] *a[i][n] / a[m][n];
d[j] = d[j] - a[m][j] * d[n] /a[m][n];
}
a[i][n] == 0;
}
for (i = m + 1; i < M; i++)
{
e[i] = e[i] - e[m] * a[i][n] / a[m][n];
for (j = 0; j < n; j++)
{
d[j] = d[j] - a[m][j] * d[n] /a[m][n];
a[i][j] = a[i][j] - a[m][j] *a[i][n] / a[m][n];
}
for (j = n + 1; j < N; j++)
{
a[i][j] = a[i][j] - a[m][j] *a[i][n] / a[m][n];
d[j] = d[j] - a[m][j] * d[n] /a[m][n];
}
a[i][n] == 0;
}
e[m] = e[m] / a[m][n];
for (j = 0; j < n; j++)
a[m][j] = a[m][j] / a[m][n];
for (j = n + 1; j < N; j++)
a[m][j] = a[m][j] / a[m][n];
a[m][n] == 1;
d[n] = 0;
for (i = 0; i < M; i++)
{
for (j = 0; j < N; j++)
printf("%.2f ", a[i][j]);
printf("\n");
}
for (i = 0; i < M; i++)
{
printf("%.2f ", e[i]);
}
printf("\n");
for (j = 0, k = d[0], n = 0; j <N; j++)
{
if (max(k, d[j])>k)
{
k = max(k, d[j]);
n = j;
}
}
for (i = 0, m = a[0][n], p = 0; i <M; i++)
{
if (max(a[i][n], m)>m)
{
m = max(a[i][n], m);
p= i;
}
}
}
//找出基變數中元素最大的下標
for(i = 0, u = X[0], v = 0; i < M; i++)
{
if (max(u, X[i])>u)
{
u = max(u, X[i]);
v = i;
}
}
//找出最大的檢驗數,及其下標
for(j = N - M - 1, k = d[N - M], t = 0; j<N - 1; j++)
{
if (max(k, d[j])>k)
{
k = max(k, d[j]);
t = j;
}
}
for(i = 0; i < M; i++)
{
if (X[i] == t)break;
}
for(i = 0; i < M; i++)
{
printf("%.2f ", e[i]);
}
printf("\n");
if(k>0 && a[p][n] <= 0)
{
printf("無界解");
}
elseif ((u>(N - M - 1)) &&(c[u] > 0))
{
printf("無可行解");
}
elseif ((k = 0) &&(i >= M))
{
printf("無窮多解\n");
for (i = 0; i < M; i++)
printf("第%d變數係數是%.2f 取值是%.2f\n", X[i], g[i], e[i]);
for (i = 0; i < M; i++)
z = z + g[i] * e[i];
printf("解為z=%d", z);
}
else
{
printf("唯一最優解\n");
for (i = 0; i < M; i++)
printf("第%d變數係數是%.2f 取值是%.2f\n", X[i], g[i], e[i]);
for (i = 0; i < M; i++)
z = z + g[i] * e[i];
printf("唯一最優解z=%.2f\n", z);
}
return0;
}