一个工作中的问题

需求如下:

用户在前台界面输入若干个专业编号S和人数N,后台根据下述规则返回给前台N个专家。每个专家在数据库中都存有其基础信息,其中包含专业编号(以逗号隔开的字符串)、等级(高中低)、资质是否有效(Y|N)等信息。

规则:

1.每个专家拥有的专业编号都至少对应S中的一个
2.N个专家所包含的所有专业编号要包含S中的任意一个
3.N个专家中至少有一个等级是高级,且低级占比不超过40%
4.N个专家中资质无效的占比不超过50%

思路:

1.首先根据规则 1 来查找数据库中的所有专家,得到专家集合 M1,使得M1中任意一个专家的专家编号都至少有一个属于S;
2.根据所需人数N,计算出所有从M1中取N个的所有可能的情况R。循环R次,每次循环都对从M1中取出的N个专家进行专业判断,若这N个专家所含专业编号集合>S,则添加到集合M2中;
3. M2中的任意一个元素(N个专家的集合)都满足规则2;
4.对M2进行遍历,每次循环都对M2每个元素中的所有专家的等级、资质是否有效进行计算,如果计算出的满足条件3、4,则表明此次循环的元素符合所有条件,添加到M3中;
5.对M3随机取一条即为结果。

进一步需求

用户看到推荐的专家组后,希望对某个专家进行置换,更换后的结果仍然满足所有规则。用户更换过的专家不会被再次更换出来。

思路:
1.每次点击置换按钮,都把该组专家的所有Id和要被更换的这个专家的Id传到后台,更换的专家的Id使用静态成员变量临时存储(更换池),且在用户第一次点击搜索得到结果后进行清空处理,在每次点击置换按钮后对该静态变量进行添加的操作;
2.将上述M3作为静态成员变量处理,遍历M3,根据另外N-1个不被操作的专家的Id筛选每次循环中包含这N-1个专家的元素,将其添加到M4中;
3.将M4与更换池中的专家Id对比,将不在更换池中的专家作为集合M5;
4.任取M5中的一条。

问题:

对于M1而言,如果其数量过大,且N多于五个的时候,无论使用递归还是非递归,都将因为过大的组合数,而出现OOM异常,此时应该想办法减小集合M1。

思路:对集合M1进行遍历,对于每个专业条件与S都相同,且等级和资质也一样的专家进行随机去重。
缺点:当用户输入的专业条件S较大的时候,去重效果一般。

贪心算法

如果用户不需要随机性很强的推荐专业的话,可以使用贪心算法来实现该问题,这样可以最大程度上减小程序的运算量。
策略:对每个符合当前专业和资质等级条件的专家打分,每次都选取分数最高的一个,直到得到目标集合。
具体思路:每次先对符合条件的专家进行打分排序,然后选出最高分的某一个,根据该已选择的专家的条件之外的条件对其余专家再次打分排序,再次选出排分高的专家,当所有条件已经被排除完之后,所获得的集合即为所求。
缺点:最坏情况下,没有任何一组专家符合条件的话,将很难判断是否存在这样的组合;如果某次出现的结果不在边界上,程序所需的计算仍然很大;随机性不够,分数高的专家很难被更换。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值