Fractional Programming
Fractional programming is used to find the extremum of a fraction. Formally, given \(a_i\) and \(b_i\), find a set of \(w_i\in\{0,1\}\) that minimizes or maximizes
In simpler terms, such problems are similar to: each item has two weights \(a\) and \(b\), select a number of items such that \(\displaystyle\frac{\sum a}{\sum b}\) is minimized or maximized.
Generally, fractional programming problems also have special constraints, such as "the denominator is at least \(W\)".
Solution
Binary Search
The general method for fractional programming problems is binary search on the answer. Suppose the current binary search answer is \(\textit{mid}\), then a set of \(\{w_i\}\) satisfying the condition will make the value greater than or equal to \(\textit{mid}\). Based on this condition, we can formulate an inequality and transform it:
Then we only need to find the maximum value of the expression on the left side of the inequality. If the maximum is greater than \(0\), it means \(mid\) is feasible; otherwise, it is not feasible. The main difficulty in fractional programming lies in how to find the maximum or minimum of \(\displaystyle \sum w_i\times(a_i-mid\times b_i)\).
Dinkelbach Algorithm
The general idea of the Dinkelbach algorithm1 is to use the answer from the previous iteration as the new \(L\) for input, and iterate continuously until the answer converges.
Examples
LOJ 149 Fractional Programming
There are \(n\) items, each with two weights \(a\) and \(b\). Find a set of \(w_i\in\{0,1\}\) such that exactly \(k\) of the \(w_i\) are \(1\), maximizing \(\displaystyle\frac{\sum a_i\times w_i}{\sum b_i\times w_i}\).
Solution
Treat \(a_i-mid\times b_i\) as the weight of the \(i\)-th item, and greedily select the top \(k\) items with the largest weights. If the sum of weights is greater than \(0\), it is feasible; otherwise, it is not.
Reference Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | |
Luogu P4377 Talent Show G
There are \(n\) items, each with two weights \(a\) and \(b\).
You need to determine a set of \(w_i\in\{0,1\}\) such that \(\displaystyle\frac{\sum w_i\times a_i}{\sum w_i\times b_i}\) is maximized.
The constraint is \(\displaystyle\sum w_i\times b_i \geq W\).
Solution
This problem has the additional constraint that the denominator must be at least \(W\), so the greedy algorithm from the previous problem can no longer be used.
Consider 0-1 knapsack. Treat \(b_i\) as the weight of the \(i\)-th item and \(a_i-mid\times b_i\) as the value of the \(i\)-th item, then the problem transforms into a knapsack problem. Thus, \(dp[n][W]\) is the maximum value.
During the DP process, if the total weight of items exceeds \(W\), it can be directly treated as \(W\).
Reference Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | |
POJ2728 Desert King
Each edge has two weights \(a_i\) and \(b_i\). Find a spanning tree \(T\) such that \(\displaystyle\frac{\sum_{e\in T}a_e}{\sum_{e\in T}b_e}\) is minimized.
Solution
Treat \(a_i-mid\times b_i\) as the weight of each edge, then the minimum spanning tree gives the minimum value. This problem requires finding a minimum spanning tree in a complete graph, so Prim's algorithm should be used.
Reference Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | |
[HNOI2009] Minimum Cycle
Each edge has weight \(w\). Find a cycle \(C\) such that \(\displaystyle\frac{\sum_{e\in C}w}{|C|}\) is minimized.
Solution
Treat \(a_i-mid\) as the edge weight, then the cycle with the smallest weight is the minimum value.
Since we only need to check whether the minimum value is less than \(0\), we only need to determine whether there exists a negative cycle in the graph.
Additionally, there exists an algorithm with complexity \(O(nm)\) for this problem. If interested, you can read this article.
Reference Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | |
Exercises
- JSOI2016 Best Group
- SDOI2017 New Dance Party
- UVa1389 Hard Life
- Luogu P2868 [USACO07DEC] Sightseeing Cows G
- AtCoder Beginner Contest 324 F - Beautiful Path
References and Notes
本页面最近更新:,更新历史
发现错误?想一起完善? 在 GitHub 上编辑此页!
本页面贡献者:OI-wiki
本页面的全部内容在 CC BY-SA 4.0 和 SATA 协议之条款下提供,附加条款亦可能应用