1. 程式人生 > >建模演算法(二)——整數規劃

建模演算法(二)——整數規劃

一、概述

1、定義:規劃中變數部分或全部定義成整數是,稱為整數規劃。

2、分類:純整數規劃和混合整數規劃。

3、特點:

(1)原線性規劃有最優解,當自變數限制為整數後:

       a、原最優解全是整數,那最優解仍成立

       b、整數規劃沒有可行解

       c、有可行解,但是不是原最優解

4、求解方法分類

(1)分支定界法

(2)割平面法

(3)隱列舉法

(4)匈牙利法

(5)蒙特卡洛法

二、分支定界法

1、演算法如下(求解整數規劃最大化問題)

image

MATLAB實現

複製程式碼
function r=checkint(x)
%判斷x(i)是不是整數了。是的話r(i)返回1,不是的話,返回0

%輸入引數:x   X向量
%輸出引數:r   R向量

for i=1:length(x) if(min(abs(x(i)-floor(x(i))),abs(x(i)-ceil(x(i))))<1e-3) r(i)=1; else r(i)=0; end end
複製程式碼複製程式碼
function val=isrowinmat(arow,mat)
%用來判斷mat中是否包含與arow一樣的向量

%輸入變數:arow    向量
%         mat     矩陣
%輸出變數:val     1表示有,0表示沒有
val=0;
rows=size(mat,1);
for i=1:rows
    temp=(mat(i,:)==arow);
    
if length(find(temp==0))==0 val=1; return; else val=0; end; end
複製程式碼複製程式碼
function [x,fval,exitflag,output,lambda]=linprogdis(ifint,f,A,b,Aeq,beq,lb,ub,x0,options)
% 用法
%    [x,fval,exitflag,output,lambda]=lpint(ifint.f,A,b,Aeq,beq)
%    [x,fval,exitflag,output,lambda]=lpint(ifint,f,A,b,Aeq,beq,lb)
% [x,fval,exitflag,output,lambda]=lpint(ifint,f,A,b,Aeq,beq,lb,ub) % [x,fval,exitflag,output,lambda]=lpint(ifint,f,A,b,Aeq,beq,lb,ub,x0) % [x,fval,exitflag,output,lambda]=lpint(ifint,f,A,b,Aeq,beq,lb,ub,x0,options) if nargin<10, options=[]; end if nargin<9, x0=[]; end if nargin<8, ub=inf*ones(size(f)); end if nargin<7, lb=zeros(size(f)); end [x,fval,exitflag,output,lambda]=linprog(f,A,b,Aeq,beq,lb,ub,x0,options); if exitflag<=0 %表示線性規劃沒有最優解 return end v1=find(ifint==1); %找到需要整數規劃的變數的下標 temp=x(v1);%如果不是要求整數規劃的就可以返回了。 if isempty(temp) return end v2=find(checkint(temp)==0); if isempty(v2) %都是整數,得到最眾解 return end k=v1(v2(1)); temp1=zeros(1,length(f)); temp1(k)=1; low=floor(x(k)); if isrowinmat([temp1,low],[A,b])==1 thisA=A; thisb=b; else thisA=[A;temp1]; thisb=b; thisb(end+1)=low; end [x1,fval1,exitflag1,output1,lambda1]=linprogdis(ifint,f,thisA,thisb,Aeq,beq,lb,ub,x0,options); temp2=zeros(1,length(f)); temp2(k)=-1; high=-ceil(x(k)); if isrowinmat([temp2,high],[A,b])==1 thisA=A; thisb=b; else thisA=[A;temp2]; thisb=b; thisb(end+1)=high; end [x2,fval2,exitflag2,output2,lambda2]=linprogdis(ifint,f,thisA,thisb,Aeq,beq,lb,ub,x0,options); if (isempty(v2) && ((exitflag1>0 && exitflag2<=0 && fval<=fval)||(exitflag2>0 && exitflag1<=0 && fval<=fval2)||(exitflag1>0 && exitflag2>0 && fval<=fval1 && fval<=fval2))) disp('error call'); return ; %表示都是整數 end if exitflag1>0&&exitflag2<=0 x=x1; fval=fval1; exitflag=exitflag1; output=output1; lambda=lambda1; elseif exitflag1<=0&&exitflag2>0 x=x2; fval=fval2; exitflag=exitflag2; output=output2; lambda=lambda2; elseif exitflag1>0 && exitflag2>0 if fval1<fval2 x=x1; fval=fval1; exitflag=exitflag1; output=output1; lambda=lambda1; else x=x2; fval=fval2; exitflag=exitflag2; output=output2; lambda=lambda2; end end
複製程式碼

三、0-1型整數規劃

1、定義:就是變數的取值只能是0-1,這樣的話,其實我們可以將不同的整數規劃轉化成0-1規劃。

2、實際問題:

image

       這裡我們就可以直接列出一個是0-1規劃的方程,設的變數xi,“1”表示被選中,“0”表示沒被選中

3、相互排斥的約束條件可以轉化成同類型的。

image

image

四、求解整數規劃的3種方法

(1)窮舉法,這種比較土= =,但是最有效,而且某些情況只能窮舉。

(2)過渡隱列舉法

a、先試探性求一個可行解X(隨便帶入求值)

b、然後根據是求極大值還是極小值,如果是求極大值,那麼凡是目標值<X的解不必檢驗是否滿足約束條件即可刪除,如果是求極小值,那麼凡是目標值>X不必檢驗是否滿足約束條件就可滿足。

c、改進新的過濾條件

d、然後驗證目標值,最終求得。

PS:怎麼說呢,這個方法就是一種變相的窮舉,如果運氣不好,就會變成全部都窮舉,但是因為是先比較目標值,所以可以減少計算量,因而還是有效的(但是要注意不要犯反覆測驗的錯誤)、

(3)蒙特卡洛法(隨機抽樣法)

就是選擇不窮舉全部點,而是採用隨機的方式來抽取樣本估計整體,如果樣本足夠大,可信度是很大的。

例如求解此題:

image

MATLAB程式設計求解:

複製程式碼
function [ f,g ] = mengte( x )
%MENGTE 鍵入整數線性規劃的目標函式和約束條件
%   f:指的是目標函式      向量
%   g:指的是約束條件      向量


f=x(1)^2+x(2)^2+3*x(3)^2+4*x(4)^2+2*x(5)^2-8*x(1)-2*x(2)-3*x(3)-x(4)-2*x(5);

g=[sum(x)-400
   x(1)+2*x(2)+2*x(3)+x(4)+6*x(5)-800
   2*x(1)+x(2)+6*x(3)-200
   x(3)+x(4)+5*x(5)-200];

end
複製程式碼複製程式碼
rand('state',sum(clock));
p0=0;
tic
for i=1:10^6
    x=99*rand(5,1);
    x1=floor(x);x2=ceil(x);
    [f,g]=mengte(x1);
    if  sum(g<=0)==4
        if  p0<=f
            x0=x1;p0=f;
        end
    end
    [f,g]=mengte(x2);
    if  sum(g<=0)==4
        if  p0<=f
            x0=x2;p0=f;
        end
    end
end
    x0,p0
複製程式碼

五、0-1整數規劃的求解

例如求解這個指派問題。

image

由於MATLAB裡面有封裝好的函式- -,我就不用C++再寫了。。不過這個問題還是很容易寫出來的,一些比賽題目也會出現的。

複製程式碼
c=[3,8,2,10,3;
    8,7,2,9,7;
    6,4,2,7,5;
    8,4,2,3,5;
    9,10,6,9,10]


c=c(:);%就是變成列向量(提取矩陣的方法)
a=zeros(10,25);
for i=1:5
    a(i,(i-1)*5+1:1:5*i)=1;
    a(5+i,i:5:25)=1;
end
b=ones(10,1);
[x,y]=bintprog(c,[],[],a,b);
x=reshape(x,[5,5]),y
複製程式碼

相關推薦

建模演算法——整數規劃

一、概述1、定義:規劃中變數部分或全部定義成整數是,稱為整數規劃。2、分類:純整數規劃和混合整數規劃。3、特點:(1)原線性規劃有最優解,當自變數限制為整數後:       a、原最優解全是整數,那最優解仍成立       b、整數規劃沒有可行解       c、有可行解,但

手把手教用matlab做無人駕駛-路徑規劃A*演算法

對於路徑規劃演算法-A*演算法在matlab中模擬,首先我們在matlab中構建地圖: 先給出matlab主函式程式: % editor: Robert.Cao % 2018.9.1 clc clear all close all disp('A Star

動態規劃演算法---

摘自網路 題目: 國王和金礦 有一個國家發現了5座金礦,每座金礦的黃金儲量不同,需要參與挖掘的工人數也不同。參與挖礦工人的總數是10人。每座金礦要麼全挖,要麼不挖,不能派出一半人挖取一半金礦。要求用程式求解出,要想得到儘可能多的黃金,應該選擇挖取哪幾座金礦?

資料結構與演算法--遞迴

遞迴條件: 1.遞迴條件:每次調自己,然後記錄當時的狀態 2.基準條件:執行到什麼時候結束遞迴,不然遞迴就會無休止的呼叫自己, 遞迴的資料結構:棧(先進先出)和彈夾原理一樣,每一次呼叫自己都記錄了當時的一種狀態,然後把這種狀態的結果返回。 棧相對應的資料結構:佇列(先進後出

演算法之排序

排序演算法很多,常用的排序演算法有:氣泡排序、插入排序、選擇排序、歸併排序、快速排序、計數排序、基數排序、桶排序。 接下來一一介紹幾種排序的時間複雜度及優缺點。 插入排序與氣泡排序的時間複雜度相同O(n^2),開發中我們更傾向插入排序,而不是氣泡排序 排序演算法執行效率: 1.最好、最壞、平均情況時間

圖——基本的圖演算法圖的遍歷

圖——基本的圖演算法(二)圖的遍歷 1. 基本概念 圖的遍歷指的是從圖中的某個頂點出發訪問圖中其餘的頂點,且每個頂點只被訪問一次的這個過程。通常來說,圖的遍歷次序有兩種:深度優先遍歷(Depth first Search, DFS)和廣度優先遍歷(Breadth First Se

吳恩達老師機器學習筆記K-means聚類演算法

運用K-means聚類演算法進行影象壓縮 趁熱打鐵,修改之前的演算法來做第二個練習—影象壓縮 原始圖片如下: 程式碼如下: X =imread('bird.png'); % 讀取圖片 X =im2double(X); % unit8轉成double型別 [m,n,z]=size

深入理解線性迴歸演算法:正則項的詳細分析

前言 當模型的複雜度達到一定程度時,則模型處於過擬合狀態,類似這種意思相信大家看到個很多次了,本文首先討論了怎麼去理解複雜度這一概念,然後回顧貝葉斯思想(原諒我有點囉嗦),並從貝葉斯的角度去理解正則項的含義以及正則項降低模型複雜度的方法,最後總結全文。     &nb

Logistic迴歸之梯度上升優化演算法

Logistic迴歸之梯度上升優化演算法(二) 有了上一篇的知識儲備,這一篇部落格我們就開始Python3實戰 1、資料準備 資料集:資料集下載 資料集內容比較簡單,我們可以簡單理解為第一列X,第二列Y,第三列是分類標籤。根據標籤的不同,對這些資料點進行分類。  

「日常訓練&知識學習」莫隊演算法:樹上莫隊Count on a tree II,SPOJ COT2

題意與分析 題意是這樣的,給定一顆節點有權值的樹,然後給若干個詢問,每次詢問讓你找出一條鏈上有多少個不同權值。 寫這題之前要參看我的三個blog:CFR326D2E、CFR340D2E和HYSBZ-1086,然後再看這幾個Blog—— 參考A:https://blog.sengxian.com/algori

從零開始學演算法選擇排序

從零開始學演算法(二)選擇排序 選擇排序 演算法介紹 演算法原理 演算法簡單記憶說明 演算法複雜度和穩定性 程式碼實現 選擇排序 程式碼是Javascript語言寫的(幾乎是虛擬碼) 演算

決策樹-剪枝演算法

ID3演算法的的原理,它是以資訊熵為度量,用於決策樹節點的屬性選擇,每次優選資訊量最多 的屬性,以構造一顆熵值下降最快的決策樹,到葉子節點處的熵值為0,此時每個葉子節點對應的例項集中的例項屬於同一類。 理想的決策樹有三種: 1.葉子節點數最少 2.葉子加點深度最小 3.葉子節點數最少且葉子

程式設計與演算法第八週測驗 3:棋盤問題

3:棋盤問題 檢視 提交 統計 提問 總時間限制:  1000ms   記憶體限制:  65536kB 描述 在一個給定形狀的棋盤(形狀可能是不規則的)上面擺放棋子,棋子沒有區別。要求擺放時任意的兩個棋子不能放

程式設計與演算法第八週測驗 2:A Knight's Journey

2:A Knight's Journey 檢視 提交 統計 提問 總時間限制:  1000ms   記憶體限制:  65536kB 描述 Background The knight is getting bor

程式設計與演算法第八週測驗 1:紅與黑

1:紅與黑 檢視 提交 統計 提問 總時間限制:  1000ms   記憶體限制:  65536kB 描述 有一間長方形的房子,地上鋪了紅色、黑色兩種顏色的正方形瓷磚。你站在其中一塊黑色的瓷磚上,只能向相鄰的黑

共識演算法—— DPoS股份授權證明、PBFT實用拜占庭容錯

DPoS簡介 DPoS(Delegated-Proof-of-Stake)即股份授權證明,目的是解決PoS和PoW的不足,DPoS是由被社群選取的可信賬戶(受託人,得票數為所有委託人得前101位)來建立區塊,為了成為正式委託人,使用者要去社群拉票,獲得足夠多的使用者信任,使用者根據自己持有的

聚類演算法

密度聚類 密度聚類假設聚類結構能通過樣本分佈的緊密程度確定,通常情況下密度聚類演算法從樣本密度的角度來考察樣本之間的可連線性,並基於可連線樣本不斷擴充套件聚類 簇以獲得最終的聚類結果 DBSCAN 基於一組鄰域引數來刻畫樣本分佈的緊密程度。 事先不用預設聚類簇數

C語言學習_查詢演算法

3 分塊查詢 演算法思想:將待查的元素均勻的分成塊,塊間按大小順序排序,塊內不排序。 具體的,設待查元素有15 個,將其按關鍵字大小分成3塊,這15個數的排列是一個有序序列,也可以給出無序序列,但也是必須得滿足分在第一塊中的任意元素小於第二塊中的所有數,第二塊中的任意元素

“設圖紙”的資料結構和演算法 線性表

線性表的定義:由零個或多個數據元素組成的有限序列(n=0時為空表) 注意:線性關係的條件是如果存在多個元素,則“第一個元素無前驅,而最後一個元素無後繼,其他元素都有且僅有一個前驅和後繼” 資料型別:是指一組性質相同的值的集合及定義在此集合上的一些操作的總稱 線性表有

資料結構與演算法-線性表之單鏈表順序儲存和鏈式儲存

前言:前面已經介紹過資料結構和演算法的基本概念,下面就開始總結一下資料結構中邏輯結構下的分支——線性結構線性表 一、簡介 1、線性表定義   線性表(List):由零個或多個數據元素組成的有限序列;   這裡有需要注意的幾個關鍵地方:     1.首先他是一個序列,也就是說元素之間是有個先來後到的。