博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
运筹学上机实验 - 单纯形方法的两阶段法
阅读量:6578 次
发布时间:2019-06-24

本文共 3760 字,大约阅读时间需要 12 分钟。

理论部分不解释了, 就是粘个实验课的代码,按照书上的算法写的,仅仅是把课本上的样例过了,有bug可能难免,欢迎指出。

Sample 1.

$$ \left\{

\begin{aligned}
min z = 5x_1+21x_3\\
s.t.\,\,x_1-x_2+6x_3-x_4=2 \\
x_1+x_2+2x_3-x_5=1\\
x_j\geq 0,\,j=1,\dots,5 \\
\end{aligned}
\right.
$$

input:

5 2

1 -1 6 -1 0
1 1 2 0 -1
5 0 21 0 0
2 1

answer:

63/8

Sample 2.

$$ \left\{
\begin{aligned}
min z = 3x_1+2x_2+x_3\\
s.t.\,\,x_1+2x_2+x_3=15 \\
2x_1+5x_3=18\\
2x_1+4x_2+x_3+x_4=10\\
x_j\geq 0,\,j=1,2,3,4 \\
\end{aligned}
\right.
$$

input:

4 3

1 2 1 0
2 0 5 0
2 4 1 1
3 2 1 0
15 18 10

output:

无解

//运行环境GCC6.4.0 C++11  非VC++//实验一 单纯性方法#include "cmath"#include "cstdio"#include "vector"#include "algorithm"#include "iostream"using namespace std;int N, M;double **A;int *mark;bool Simplex(int ROW, int COL) {
//两阶段法 //mark标记进基变量 mark = (int *)malloc(sizeof(int)*N); for (int i = 0; i < M; i++) mark[i] = M+i; //使得添加的变量的检验数为0 for (int i = 2; i < N+2; i++) { for (int j = 0; j < COL; j++) { A[1][j] += A[i][j]; } } //按照单纯形方法进行迭代 double maxx = -1; int pos = 0; for (int i = 0; i < N+M; i++) { if (A[1][i] > maxx) { maxx = A[1][i]; pos = i; } } while (maxx > 0) { double minn = -1; int pos1 = 0; for (int i = 0; i < N; i++) { if (A[i+2][pos] > 0) { if (minn < 0) { pos1 = i+2; minn = A[i+2][M+N]/A[i+2][pos];} else if (A[i+2][M+N]/A[i+2][pos] < minn) { pos1 = i+2; minn = A[i+2][N+M]/A[i+2][pos]; } } } if (minn == -1.0) return false; double s = A[pos1][pos]; for (int i = 0; i < COL; i++) { A[pos1][i] /= s; } mark[pos1-2] = pos; for (int i = 0; i < ROW; i++) { if (i == pos1) continue; s = A[i][pos]; for (int j = 0; j < COL; j++) { A[i][j] -= s*A[pos1][j]; } } maxx = -1; pos = 0; for (int i = 0; i < N+M; i++) { if (A[1][i] > maxx) { maxx = A[1][i]; pos = i; } } } return true;}int main(int argc, char const *argv[]){ printf("请输入自变量的个数和方程组的个数:"); scanf("%d%d", &M, &N); A = (double **)malloc(sizeof(double *)*(N+3)); //A为单纯形表 for (int i = 0; i < N+3; i++) { *(A+i) = (double *)malloc(sizeof(double)*(M+N+2)); } printf("请输入约束矩阵:\n"); for (int i = 0; i < N; i++) { for (int j = 0; j < M; j++) { scanf("%lf", &A[i+2][j]); } } for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { if (i == j) A[i+2][j+M] = 1.0; else A[i+2][j+M] = 0.0; } } printf("请输入价值向量:\n"); for (int i = 0; i < M; i++) { double t; scanf("%lf", &t); A[0][i] = -t; } for (int i = 0; i < N + M; i++) { if (i < M) A[1][i] = 0.0; else A[1][i] = -1.0; } printf("请输入右端向量:\n"); A[0][N+M] = A[1][N+M] = 0.0; for (int i = 0; i < N; i++) { scanf("%lf", &A[i+2][N+M]); } //向量R中保存的是基本解向量对应的值 int *R = (int *)malloc(sizeof(int)*(N+M)); for (int i = 0; i < N+M; i++) R[i] = -1; if (Simplex(N+2, M+N+1)) { double g = 0.0;//辅助问题的g for (int i = 0; i < N; i++) { R[mark[i]] = i; if (mark[i] >= M) g += A[i][M+N]; } // 如果min g != 0 方程无解 if (g > 0) printf("该线性方程无解!\n"); else { printf("利用单纯形方法得到的解为%.6lf\n", A[0][M+N]); printf("该线性规划的一个基本可行解为:\n"); for (int i = 0; i < M; i++) { if (R[i] != -1) printf("%lf\n", A[R[i]+2][M+N]); else printf("%lf\n", 0.0); } } } else printf("该线性方程无解!\n"); return 0;}

 

转载于:https://www.cnblogs.com/cniwoq/p/9144082.html

你可能感兴趣的文章
Kotlin 知识梳理(1) Kotlin 基础
查看>>
js正则表达式
查看>>
iOS socket通信,编解码,浮点型数据解析
查看>>
手把手教你如何新建scrapy爬虫框架的第一个项目(下)
查看>>
前端基础15:JS作用域基础
查看>>
Linux系统相关命令
查看>>
BATJ面试必会之 Spring 篇(一)
查看>>
表驱动法
查看>>
什么是企业内训
查看>>
firefox无法显示java插件plugin
查看>>
H3C设备之OSPF DR选举
查看>>
List grantee right in oracle
查看>>
Activity生命周期
查看>>
通过VBS编写自动输入账号和密码、自动登录程序的脚本
查看>>
MTK APSoC SDK MT7621编译固件的快速开始
查看>>
深度解析Istio系列之安全模块篇
查看>>
Linux 系统 审计
查看>>
JS -------------------设置弹出框位置屏幕的中间
查看>>
性能测试 vbs使用(一)
查看>>
1.2 linux哲学思想
查看>>