【高階演算法】單純形法求解線性規劃問題(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 5305】Friends 多校第二場(雙向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
【leetcode】11.Container With Most Water(c語言)
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()語法