整數規划(蒙特卡洛)


若在線性規划模型中, 變量限制為整數,則稱為整數線性規划。

  • 對於整數線性規划模型大致可分為兩類:變量全限制為整數時,稱純(完全)整數規划。
  • 變量部分限制為整數的,稱混合整數規划。

原線性規划有優解,當自變量限制為整數后,其整數規划解會出現:

  • 原線性規划優解全是整數,則整數規划優解與線性規划優解一致。
  • 整數規划無可行解。
  • 有可行解(當然就存在優解),但優解值變差。

求解方法分類:

  • 分枝定界法—可求純或混合整數線性規划。
  • 割平面法—可求純或混合整數線性規划。
  • 隱枚舉法—求解“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的博客

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM