1. 程式人生 > >【高階演算法】單純形法求解線性規劃問題(C++實現)

【高階演算法】單純形法求解線性規劃問題(C++實現)

1 單純形法

(1) 單純形法是解線性規劃問題的一個重要方法。
其原理的基本框架為:
第一步:將LP線性規劃變標準型,確定一個初始可行解(頂點)。
第二步:對初始基可行解最優性判別,若最優,停止;否則轉下一步。
第三步:從初始基可行解向相鄰的基可行解(頂點)轉換,且使目標值有所改善—目標函式值增加,重複第二和第三步直到找到最優解。
(2) 用程式進行運算前,要將目標函式及約束方程變成標準形式。
這裡寫圖片描述
於非標準形式須作如下變換:
a) 目標函式為極小值min z=CX時,轉換為max z=-CX形式;
b) 在約束方程中有 “≤”時,在加上一個鬆弛變數;
c) 在約束方程中有 “≥”時,採用減去一個鬆弛變數,再加上一個人工變數;
d) 在約束方程中有 “=”時,加上一個人工變數;
e) 所有的人工變數,鬆弛變數的目標函式係數置為0。
(3) 對於標準形式的線性規劃問題。用單純形法計算步驟的框圖。

2 程式測試及結果:

線性規劃問題如下:
max z=2*x1-3*x2+3x3;
x1+ x2 -x3<=7;
x1- x2 +x3<=-7;
x1-2*x2 +2*x3<=4;
x1,x2,x3>=0;

這裡寫圖片描述

3 C++實現程式碼

// Simplex.cpp : 定義控制檯應用程式的入口點。
//
//
/********************************* 
----------------------------------- 
單純形法求解線性規劃問題(C++實現程式碼)
----------------------------------- 
Author:牧之丶  Date:2014年
Email:
[email protected]
**********************************/
#include "stdafx.h" #include<iostream> #include<math.h> using namespace std; #define M 10000 //全域性變數大M float juzhen[11][31];//核心矩陣表 int m=0,n=0,t=0;//m:結構向量的個數 //n:約束不等式個數 //t:目標函式型別:-1代表求求最小值,1代表求最大值 void input() //輸入介面函式
{ int i,j; cout<<"----------單純形法的參 數 輸 入-----------"<<endl; cout<<"請按提示輸入下列引數:"<<endl<<endl; cout<<" 結構向量數m: "<<" m= "; cin>>m; cout<<endl<<" 約束不等式數n:"<<" n= "; cin>>n; for (i=0;i<=n+1;i++) for (j=0;j<=m+n+n;j++) juzhen [i][j]=0; //初始化矩陣,所有元素均為0 //讀入約束條件 cout<<endl<<" 約束方程矩陣的係數及不等式方向(1代表<=,-1代表>=):"<<endl<<endl<<" "; for (i=1;i<=m;i++) cout<<" x"<<i; cout<<" 不等式方向 "<<" 常數項"<<endl; for (i=1;i<=n;i++) { cout<<" 不等式"<<i<<" "; for (j=1;j<=m+2;j++) cin>>juzhen [i][j]; } for (i=1;i<=n;i++) { juzhen [i][0]=juzhen [i][m+2]; juzhen [i][m+2]=0; } //讀入目標條件 cout<<endl<<endl<<" 目標函式的係數及型別(求最小值:1;求最大值:-1):"<<endl<<endl<<" "; for(i=1;i<=m;i++) cout<<"x"<<i<<" "; cout<<"型別"<<endl<<" "; cout<<" 目標函式: "; for (i=1;i<=m;i++) cin>>juzhen [0][i]; cin>>t; //矩陣調整 if(t==-1) for(i=1;i<=m;i++) juzhen [0][i]=(-1)*juzhen [0][i]; for(i=1;i<=n;i++) { juzhen [i][m+i]=juzhen [i][m+1]; if(i!=1) juzhen [i][m+1]=0; } } //演算法函式 void comput() { int i,j,flag,temp1,temp2,h,k=0,temp3[10]; float a,b[11],temp,temp4[11],temp5[11],f=0,aa,d,c; //初始化 for(i=1;i<=n;i++) temp3[i]=0; for(i=0;i<11;i++) { temp4[i]=0; temp5[i]=0; } for(i=1;i<=n;i++) { if(juzhen [i][m+i]==-1) { juzhen [i][m+n+i]=1; juzhen [0][m+n+i]=M; temp3[i]=m+n+i; } else temp3[i]=m+i; } for(i=1;i<=n;i++) temp4[i]=juzhen [0][temp3[i]]; //迴圈求解 do{ for(i=1;i<=m+n+n;i++) { a=0; for(j=1;j<=n;j++) a+=juzhen [j][i]*temp4[j]; juzhen [n+1][i]=juzhen [0][i]-a; } for(i=1;i<=m+n+n;i++) { if(juzhen [n+1][i]>=0) flag=1; else { flag=-1; break; } } if(flag==1) { for(i=1;i<=n;i++) { if(temp3[i]<=m+n) temp1=1; else { temp1=-1; break; } } //輸出結果 cout<<endl<<endl; cout<<"----------結 果 輸 出-----------"<<endl<<endl; if(temp1==1) { cout<<" 此線性規劃的最優解存在!"<<endl<<endl<<" 最優解為:"<<endl<<endl<<" "; for(i=1;i<=n;i++) temp5[temp3[i]]=juzhen [i][0]; for(i=1;i<=m;i++) f+=t*juzhen [0][i]*temp5[i]; for(i=1;i<=m;i++) { cout<<"x"<<i<<" = "<<temp5[i]; if(i!=m) cout<<", "; } cout<<" ;"<<endl<<endl<<" 最優目標函式值f= "<<f<<endl<<endl; return ; } else { cout<<" 此線性規劃無解"<<endl<<endl; return ; } } if(flag==-1) { temp=100000; for(i=1;i<=m+n+n;i++) if(juzhen [n+1][i]<temp) { temp=juzhen [n+1][i]; h=i; } for(i=1;i<=n;i++) { if(juzhen [i][h]<=0) temp2=1; else { temp2=-1; break; } } } if(temp2==1) { cout<<"此線性規劃無約束"; return ; } if(temp2==-1) { c=100000; for(i=1;i<=n;i++) { if(juzhen [i][h]!=0) b[i]=juzhen [i][0]/juzhen [i][h]; if(juzhen [i][h]==0) b[i]=100000; if(b[i]<0) b[i]=100000; if(b[i]<c) { c=b[i]; k=i; } } temp3[k]=h; temp4[k]=juzhen[0][h]; d=juzhen [k][h]; for(i=0;i<=m+n+n;i++) juzhen [k][i]=juzhen [k][i]/d; for(i=1;i<=n;i++) { if(i==k) continue; aa=juzhen [i][h]; for(j=0;j<=m+n+n;j++) juzhen [i][j]=juzhen [i][j]-aa*juzhen [k][j]; } } } while(1); return ; } int _tmain(int argc, _TCHAR* argv[]) { cout<<"-------------------單純形演算法程式----------------------"<<endl<<endl; input(); comput(); system("pause"); return 0; }

相關推薦

高階演算法單純求解線性規劃問題C++實現

1 單純形法 (1) 單純形法是解線性規劃問題的一個重要方法。 其原理的基本框架為: 第一步:將LP線性規劃變標準型,確定一個初始可行解(頂點)。 第二步:對初始基可行解最優性判別,若最優,停止;否則轉下一步。 第三步:從初始基可行解向相鄰的

單純 -- 求解線性規劃

目前,運用最廣的線性規劃方法就是著名的單純形方法。這種方法是G.B.Dantzig在1947年提出的。幾十年的實踐證明,單純形方法的確是一種使用方便、行之有效的重要演算法。如今,它已經成為線性規劃的中心內容。 單純形法的基本思路是有選擇地取(而不是列舉所有的)

雅克比迭代與高斯塞德爾迭代求解方程組C語言

分別用雅可比 迭代法與高斯塞德爾迭代法解下列方程組: 雅可比迭代法: #include<stdio.h> #include<math.h> #define eps 1

追趕求解方程組C語言

編寫用追趕法解三對角線方程組的程式,並解下列方程組: #include<stdio.h> #include<math.h> void main() { int

列主元消去求解方程組C語言

用列主元消去法解下列方程組: #include<stdio.h> #include<math.h> void main() { void zhu(float *,int

Shapley演算法解決舞伴問題過程詳解C++實現

舞伴問題是這樣的:有 n 個男孩與 n 個女孩參加舞會,每個男孩和女孩均交給主持一個名單,寫上他(她)中意的舞伴名字。無論男孩還是女孩,提交給主持人的名單都是按照偏愛程度排序的,排在前面的都是他們最中意的舞伴。試問主持人在收到名單後,是否可以將他們分成 n 對,使每個人都能和他們中意的舞伴結對跳舞?為了避免舞

單純求解最函式極值問題 matlab程式碼

最近整理以前的程式碼,將以前老師上課的作業程式碼重新整理,分享出來,作業的內容是編寫單純形法,對測試函式進行尋優(極大值或者極小值)。 首先介紹一下單純形法:將上課的ppt轉化為圖片。ppt藍色背景,眼睛快看瞎了 按照ppt的

高階演算法遺傳演算法解決3SAT問題C++實現

1 SAT問題描述 命題邏輯中合取正規化 (CNF) 的可滿足性問題 (SAT)是當代理論電腦科學的核心問題, 是一典型的NP 完全問題.在定義可滿足性問題SAT之前,先引進一些邏輯符號。 一個 SAT 問題是指: 對於給定的 CNF 是否存在一

資料結構與演算法 棧——棧的應用舉例3例

根據“後進先出”特性,生活中的例子比比皆是。 1數制轉換 假設要講十進位制轉換為二進位制。以 52 為例,如圖: 在上述計算過程中,第一次求出的X值為最低位,最後一次求出的X值為最高位。而列印時

Coding用篩求素數的C++實現附100000以內素數表

#include <cstdio> #include <cstring> using namespace std; #define MAXN 1000000+100 bool arr[MAXN]; void findPrime(int

資料結構演算法約瑟夫環問題線性表

據說著名猶太曆史學家 Josephus有過以下的故事:在羅馬人佔領喬塔帕特後,39 個猶太人與Josephus及他的朋友躲到一個洞中,39個猶太人決定寧願死也不要被敵人抓到,於是決定了一個自殺方式,41個人排成一個圓圈,由第1個人開始報數,每報數到第3人該人就必須自殺,然後再由下一個重新報數,直到所有人都自殺

演算法二叉樹遍歷層序

1.問題描述:    層序遍歷二叉樹; 2.分析:    用佇列實現,首先將頭節點加入佇列;如果佇列不為空,則執行如下操作:從佇列中取出元素輸出,若該元素的子節點不為空,則將其加入佇列。 3.程式碼實現:  void levelSort(TreeNode * pHead)

HDU 5305Friends 多校第二場雙向DFS

tor typedef type clu name article using ring eof 依據題意的話最多32條邊,直接暴力的話 2 ^ 32肯定超時了。我們能夠分兩次搜索時間復雜度降低為 2 * 2 ^ 16 唯一須要註意的就是對眼下狀態的哈希處理。 我採用

蘿蔔學院產品經理實戰訓練營課程67課完整版

產品經理 註意 pan 百度網盤 思考 洞察力 職場 修煉 為什麽 課程大致目錄:第1課時 產品經理入門自我修煉必備第2課時 產品6問第3課時 產品要關註的用戶體驗設計原則和能力第4課時 敏銳的洞察力及碎片時間的利用第5課時 日常生活的思考及分享從自己開始第6課時 市場分析

敏捷開發經驗構件庫-Java版exp-libs

完整原文(含原始碼):http://exp-blog.com/2018/09/22/pid-2382/ (轉載請註明出處,僅供分享學習,嚴禁用於商業用途) 環境 簡介 此構件庫為本人多年程式設計總結提煉而成,把常用的功能模組作為原子API

遊戲開發directx遊戲專案——第一部分未完

目的: 編寫啟動渲染系統的程式碼,用於初始化Direct3D,將螢幕清屏為指定的顏色以及關閉系統。 main.h標頭檔案 //main.h #ifndef _UGP_MAIN_H_ #define _UGP_MAIN_H_ #include "StrandedE

leetcode11.Container With Most Waterc語言

Description: Given n non-negative integers a1, a2, …, an , where each represents a point at coordinate (i, ai). n vertical lines a

程式設計3二叉樹遍歷LeetCode.102

文章目錄 一、二叉樹的層次遍歷 1、題目描述——LeetCode.102 2、分析 3、實現 二、二叉樹(Binary Tree) 1、相關概念

程式設計2單鏈表+單鏈表反轉LeetCode. 206

文章目錄 一、連結串列 二、單鏈表 1、基本概念 (1)單鏈表 (2)頭指標——必有元素 (3)頭結點——非必需元素 (4)尾結點 2、查詢操作

CSS筆記— 使用calc()計算寬高vm/vh

【CSS筆記】— 使用calc()計算寬高(vm/vh) calc()是什麼? 簡單來說就是CSS3中新增的一個函式,calculate(計算)的縮寫。用於動態計算寬/高,你可以使用calc()給元素的各個屬性設定值【margin、border、padding、font-size】等, calc()語法