日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

运筹学上机实验 - 单纯形方法的两阶段法

發(fā)布時間:2023/12/15 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 运筹学上机实验 - 单纯形方法的两阶段法 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

理論部分不解釋了, 就是粘個實驗課的代碼,按照書上的算法寫的,僅僅是把課本上的樣例過了,有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:

無解

//運行環(huán)境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標(biāo)記進基變量mark = (int *)malloc(sizeof(int)*N);for (int i = 0; i < M; i++) mark[i] = M+i;//使得添加的變量的檢驗數(shù)為0for (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("請輸入自變量的個數(shù)和方程組的個數(shù):");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中保存的是基本解向量對應(yīng)的值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;//輔助問題的gfor (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("該線性規(guī)劃的一個基本可行解為:\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; }

?

轉(zhuǎn)載于:https://www.cnblogs.com/cniwoq/p/9144082.html

總結(jié)

以上是生活随笔為你收集整理的运筹学上机实验 - 单纯形方法的两阶段法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。