最優比例生成樹(0 1分數規劃)

2022-05-05 21:45:13 字數 2218 閱讀 7007

首先這是要解決什麼問題:乙個帶權完全圖,每條邊都有自己的花費值cost[i]和收益值benifit[i],如果用x[i]來代表一條邊取或不取,那麼求乙個生成樹。要求:r=(∑cost[i]*x[i] ) / (∑benifit[i]*x[i] )最小。

經典題目:poj2728 - desert king

如何來求解:這裡用到了0-1分數規劃思想,對於上式可以變形為 z(r)=∑cost[i]*x[i] -r*∑benifit[i]*x[i]。而z(r)=0為我們所求。

這裡有個非常重要的結論:z(r)為單調遞減函式,因此是線性的。於是"我們可以興高采烈地把z(r)看做以 cost[i]-r*benifit[i] 為邊權的最小生成樹的總權值"。顯然,我們所求即為z(max(r))=0。這裡max(r)是由z=0確定的。

於是有了兩種演算法:

1、dinkelbanch演算法,即迭代法。取r的乙個初值,一般為0,得到乙個生成樹之後,令r=(∑benifit[i]*x[i] ) / (∑cost[i]*x[i] ),哐哐迭代之後……r是趨於最大值的,而z趨於0。

2、二分法,z(r)=0是我們所求,而它又是單調函式,那麼二分r即可。據說二分比迭代慢了很多。

模板dinkelbach poj 2728:

#include #include 

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define cl(arr, val) memset(arr, val, sizeof(arr))

#define rep(i, n) for((i) = 0; (i) < (n); ++(i))

#define for(i, l, h) for((i) = (l); (i) <= (h); ++(i))

#define ford(i, h, l) for((i) = (h); (i) >= (l); --(i))

#define l(x) (x) << 1

#define r(x) (x) << 1 | 1

#define mid(l, r) (l + r) >> 1

#define min(x, y) x < y ? x : y

#define max(x, y) x < y ? y : x

#define e(x) (1 << (x))

const

double eps = 1e-6

;typedef

long

long

ll;using

namespace

std;

const

int n = 1

<<10

;const

int inf = ~0u>>2

;struct

node point[n];

double

cost[n][n];

double

benifit[n][n];

double

mi[n];

intpre[n];

bool

vis[n];

double

c, d;

intn;

double prim(double

ans)

mi[0] = 0

; vis[

0] = true

;

for(i = 0; i < n - 1; ++i)

}c +=cost[pre[f]][f];

d +=benifit[pre[f]][f];

vis[f] = true

;

for(j = 1; j < n; ++j) }}

return c/d;

}int iabs(int

x) void

init()

}}void

solve()

printf(

"%.3f\n

", ans);

}int

main()

init();

solve();

}return0;

}

0 1分數規劃

題目鏈結 中文鏈結 附一篇大佬部落格感覺講的不錯 0 1分數規劃,不妨設 l a i b i 題目要求要讓結果最大,那麼就是l最大最終移相化簡可得 a i l b i 0,因為a 和b都是已知所以我們可以直接列舉l,當我們所求的值大於零說明l還有更優解當小於零時l沒有最優解。直接二分即可 inclu...

01分數規劃

01分數規劃,就是這樣乙個東西 max frac 其中 xi in 簡而言之,就是在n個物品中選出任意幾個 或者可以有限制選多少個 使得其兩種權值a,b的比值最大 這樣的問題可以二分解決 假如有這樣一道裸題 poj2976,選n k個物品使得比值最大 我們二分出r,若存在 frac r 則r可行 變...

01分數規劃

已經接觸過01分數規劃但是只知道二分寫法 實際求解略慢 dinkelbach演算法還是值得一學的。上一道裸的01分數規劃吧。poj x陣列代表我們選或者不選 0,1構成 r sigma a i x i sigma b i x i 變形 設f v 為 sigma a i x i sigma b i x...