一般分数规划的解法
不了解分数规划的先看看论文吧,胡伯涛的那篇。
分数规划我自己也看得晕晕的,特别是对于最大化目标函数的那种。
论文中讨论的是最小化目标函数,证明也比较容易明白;但最后说对于g(r)单调性的结论对于最大化目标函数的问题同样成立,这一点我是百思不得其解;如果哪位大牛可以严格证明该结论的话希望回复帮我解答。
简单总结一下解分数规划的一般步骤吧:
1. 对于最小化目标函数r = ax/bx,则构造函数g(r)=min{ax - r*bx}
对于最大化目标函数r = ax/bx,则构造函数g(r)=max{ax - r*bx}
2. 由各种大科学家大神们证明得结论T_T:
(1)g(r)是单调减函数(有些离散情况下也有可能是单调不增加函数),即随r的增加而减小。
(2)若r是最优解,则g(r)==0。。
3. 建立模型二分r求解。
附上一道简单的练习题代码——POJ2976 Dropping tests
#include <iostream> #include <cmath> #include <cstdio> #include <cstring> #include <vector> #include <string> #include <utility> #include <algorithm> using namespace std; const int N = 1005; const double eps = 1e-4; int n, k, a[N], b[N]; double c[N]; int main() { double sum; freopen("data.in", "r", stdin); while(scanf("%d%d", &n, &k) != EOF) { if(n==0 && k==0) break; for(int i = 0; i < n; i++) scanf("%d", &a[i]); for(int i = 0; i < n; i++) scanf("%d", &b[i]); k = n-k; double l = 0.0, r = 1.0, mid; while(r-l > eps) { mid = (l+r) / 2; for(int i = 0; i < n; i++) c[i] = a[i] - mid*b[i]; sort(c, c+n); sum = 0.0; for(int i = 1; i <= k; i++) sum += c[n-i]; if(sum > 0) l = mid; else r = mid; } //cout << mid << endl; int ans = (int)(mid*100+0.5); printf("%d\n", ans); } return 0; }