[Algorithm] Meeting hour optimization (Kanpsack problem) and Dynamic programming
For example we have array of meeting objects:
const data = [
{ name: "m1", hours: },
{ name: "m2", hours: },
{ name: "m3", hours: },
{ name: "m4", hours: },
{ name: "m5", hours: }
];
For a day, 8 hours, we want to take as any meetings as possible:
const res = optimizeMeetings(data, );
You should write function 'optimizeMeetings', get the results of selected meetings to attend.
This problem is the same as Knapack problem, we can construct a table:
hours / total | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
2 | 0 | 2 | 2 | 2 | 2 | 2 | 2 | 2 |
4 | 0 | 2 | 2 | 4 | 4 | 6 | 6 | 6 |
3 | 0 | 2 | 3 | 4 | 5 | 6 | 7 | 7 |
3 | 0 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
1 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
The max hours we can take is the last row & col value, which in the end should be 8.
Then we should trace back the table to find which items should be included.
Final Code:
/**@description
* When we have our result for Knapsack problem, we want to back trace to get the selected items.
*
* What we need to do is trace form last item of the memo, moving up
*/
const backTrace = (hours, totalHours, memo) => {
function helper(memo, row, col) {
let current = memo[row][col];
let selected = [];
while (current >= && row >= && col >= ) {
// If we reach the first row, then check whether we have the remaining?
// If yes then we need to add this row item into final result
if (row === && current !== ) {
selected.push(row);
break;
} let sameRowPrevCol = memo[row][col - ];
let prevRowSameCol = memo[row - ][col]; if (current !== sameRowPrevCol && prevRowSameCol !== current) {
// Item should be selected if the value with sibling values are differnet
selected.push(row);
// calcuate the remaining
col = current - hours[row] - ;
row = row - ;
} else if (prevRowSameCol === current && current !== sameRowPrevCol) {
// current is coming from previous row with the same column, reset row
row = row - ;
} else if (current === sameRowPrevCol && prevRowSameCol !== current) {
// current is coming from previous column with the same row, reset column
col = col - ;
}
// Update current with new row and new column
current = memo[row][col];
}
return selected;
} return helper(memo, hours.length - , totalHours.length - );
}; const getMaxHours = (hours, totalHours) => {
let memo = [...new Array(hours.length)].map(
x => new Array(totalHours.length)
);
function helper(hours, totalHours, memo) {
for (let row in hours) {
const value = hours[row];
for (let col in totalHours) {
// Fill in the first row
if (!memo[row - ]) {
memo[row][col] = value <= totalHours[col] ? value : ;
continue;
} // if the current value is larger than constrain, we use previous value
const prevRowSameCol = memo[row - ][col];
if (value > totalHours[col]) {
memo[row][col] = prevRowSameCol;
continue;
} // if the current value is equal to constrain, then Max{value, prevRowSameCol}
if (value === totalHours[col]) {
memo[row][col] = Math.max(value, prevRowSameCol);
} // if the current value is smaller than constrain
// Math {value + memo[row - 1][diff]: where diff is constrain-value, prevRowSameCol}
if (value < totalHours[col]) {
const diff = totalHours[col] - value - ;
memo[row][col] = Math.max(
prevRowSameCol,
value + memo[row - ][diff]
);
}
}
}
return memo;
}
memo = helper(hours, totalHours, memo);
const selectedIndex = backTrace(hours, totalHours, memo); return {
memo,
selectedIndex
};
}; function* genearteNumberAry(start, num) {
let i = start;
while (i <= num) {
yield i;
i++;
}
} /**
* Main
*/
/**
* @param meetings: [{name: string, hours: number}]
* @param haveHours: number
*
* @returns [meetings]
*/
function optimizeMeetings(meetings, haveHours) {
const hours = meetings.map(m => m.hours);
const haveHoursAry = Array.from(genearteNumberAry(, haveHours));
const { selectedIndex } = getMaxHours(hours, haveHoursAry);
return selectedIndex.map(i => meetings[i]);
} const data = [
{ name: "m1", hours: },
{ name: "m2", hours: },
{ name: "m3", hours: },
{ name: "m4", hours: },
{ name: "m5", hours: }
]; const res = optimizeMeetings(data, );
console.log(JSON.stringify(res)); // [{"name":"m4","hours":3},{"name":"m3","hours":3},{"name":"m1","hours":2}]
[Algorithm] Meeting hour optimization (Kanpsack problem) and Dynamic programming的更多相关文章
- Codeforces 1503C Travelling Salesman Problem(Dynamic Programming)
题意 大家都是优秀生,这点英文还是看得懂的:点此看题 题解 由于旅行路线成一个环,所以从哪里出发不重要,我们把景点按照 a i a_i ai 排序,不妨就从左边最小的出发.基础的旅行费用 c i c ...
- hdu 4223 Dynamic Programming?
Dynamic Programming? Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Oth ...
- hdu 4972 A simple dynamic programming problem(高效)
pid=4972" target="_blank" style="">题目链接:hdu 4972 A simple dynamic progra ...
- [Optimization] Dynamic programming
“就是迭代,被众人说得这么玄乎" “之所以归为优化,是因为动态规划本质是一个systemetic bruce force" “因为systemetic,所以比穷举好了许多,就认为是 ...
- [Optimization] Advanced Dynamic programming
这里主要是较为详细地理解动态规划的思想,思考一些高质量的案例,同时也响应如下这么一句口号: “迭代(regression)是人,递归(recursion)是神!” Video series for D ...
- HDU-4972 A simple dynamic programming problem
http://acm.hdu.edu.cn/showproblem.php?pid=4972 ++和+1还是有区别的,不可大意. A simple dynamic programming proble ...
- 以计算斐波那契数列为例说说动态规划算法(Dynamic Programming Algorithm Overlapping subproblems Optimal substructure Memoization Tabulation)
动态规划(Dynamic Programming)是求解决策过程(decision process)最优化的数学方法.它的名字和动态没有关系,是Richard Bellman为了唬人而取的. 动态规划 ...
- 最优化问题 Optimization Problems & 动态规划 Dynamic Programming
2018-01-12 22:50:06 一.优化问题 优化问题用数学的角度来分析就是去求一个函数或者说方程的极大值或者极小值,通常这种优化问题是有约束条件的,所以也被称为约束优化问题. 约束优化问题( ...
- [Algorithms] Using Dynamic Programming to Solve longest common subsequence problem
Let's say we have two strings: str1 = 'ACDEB' str2 = 'AEBC' We need to find the longest common subse ...
随机推荐
- SDOI 2017 Round2 滚粗了
没进省队qwq 技不如人,甘拜下风
- 【推导】Codeforces Round #478 (Div. 2) D. Ghosts
题意:给你一条直线以及初始时刻这条直线上的一些人的坐标,以及他们的速度矢量.让你对每个人计算他在过去无限远到将来无限远的时间内会与多少人处于同一个点,然后对每个人的这个值求和. 列方程组:两个人i,j ...
- hdu 4545 贪心 *
题意:小明和他的好朋友小西在玩一个新的游戏,由小西给出一个由小写字母构成的字符串,小明给出另一个比小西更长的字符串,也由小写字母组成,如果能通过魔法转 换使小明的串和小西的变成同一个,那么他们两个人都 ...
- 【洛谷】4180:【模板】严格次小生成树[BJWC2010]【链剖】【线段树维护最大、严格次大值】
P4180 [模板]严格次小生成树[BJWC2010] 题目描述 小C最近学了很多最小生成树的算法,Prim算法.Kurskal算法.消圈算法等等.正当小C洋洋得意之时,小P又来泼小C冷水了.小P说, ...
- HDU 5690 All X 数学
All X 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5690 Description F(x,m) 代表一个全是由数字x组成的m位数字.请计算, ...
- Java_如何等待子线程执行结束
工作中往往会遇到异步去执行某段逻辑, 然后先处理其他事情, 处理完后再把那段逻辑的处理结果进行汇总的产景, 这时候就需要使用线程了. 一个线程启动之后, 是异步的去执行需要执行的内容的, 不会影响主线 ...
- PostgreSQL高可用集群方案收集/主从切换/一主多从(待实践)
对于业内来说,基本都在围绕主从切换的高可用方案: http://www.10tiao.com/html/175/201509/210974337/1.html https://www.jianshu. ...
- fragment和fragmentactivity解析
一.为什么要使用Fragment 1.当我们须要动态的多界面切换的时候,就须要将UI元素和Activity融合成一个模块.在2.3中我们一般通过各种Activity中进行跳转来实现多界面的跳转和单个 ...
- GCC 对C语言的扩展
http://www.cnblogs.com/emituofo/archive/2012/07/20/2600995.html http://blog.csdn.net/andyhuabing/art ...
- Spring Boot整合RabbitMQ详细教程
原文:https://blog.csdn.net/qq_38455201/article/details/80308771 1.首先我们简单了解一下消息中间件的应用场景 异步处理 场景说明:用户注册后 ...