若在線性規划模型中, 變量限制為整數,則稱為整數線性規划。
- 對於整數線性規划模型大致可分為兩類:變量全限制為整數時,稱純(完全)整數規划。
- 變量部分限制為整數的,稱混合整數規划。
原線性規划有優解,當自變量限制為整數后,其整數規划解會出現:
- 原線性規划優解全是整數,則整數規划優解與線性規划優解一致。
- 整數規划無可行解。
- 有可行解(當然就存在優解),但優解值變差。
求解方法分類:
- 分枝定界法—可求純或混合整數線性規划。
- 割平面法—可求純或混合整數線性規划。
- 隱枚舉法—求解“0-1”整數規划:過濾隱枚舉法;分枝隱枚舉法。
- 匈牙利法—解決指派問題(“0-1”規划特殊情形)。
- 蒙特卡洛法—求解各種類型規划。
蒙特卡洛最經典的應用就是求圓周率。
#include <iostream> #include <stdlib.h> #include <time.h> #define MAX_BASE 10000000 float Rand(float L, float R) { return L + (R - L) * rand() * 1.0 / RAND_MAX; } float GetPi() { srand(time(NULL)); int count = 0; for (int i = 0; i < MAX_BASE; ++i) { float x = Rand(-1, 1); float y = Rand(-1, 1); if (x * x + y * y <= 1) count++; } return count * 4.0 / MAX_BASE; } int main () { for (int i = 0; i < 10; ++i) std::cout << GetPi() << std::endl; return 0; }
蒙特卡洛積分的應用,如求自然常數。
積分:
即求陰影部分的面積。
假設滿足
的點有m個,全部的點有n個,可得到近似公式為:
而用牛頓萊布尼茲公式可得:
兩種方法得到的結果相同,即
#include <iostream> #include <stdlib.h> #include <time.h> #include <math.h> #define MAX_BASE 10000000 struct Point { float x; float y; }; inline float Rand(float L, float R) { return L + (R - L) * rand() * 1.0 / RAND_MAX; } Point GetPoint() { Point t; t.x = Rand(1.0, 2.0); t.y = Rand(0.0, 1.0); return t; } float GetResult() { int m = 0; int n = MAX_BASE; srand(time(NULL)); for (int i = 0; i < n; ++i) { Point t = GetPoint(); float result = t.x * t.y; if (result <= 1.0) m++; } return pow(2.0, 1.0 * n / m); } int main () { for (int i = 0; i < 10; ++i) std::cout << GetResult() << std::endl; return 0; }
參考:ACdreamers的博客。