百万年薪的算法题解决方法

这个问题的地址是:http://mitibar.com/superdrink.php

我只是解决了这个问题,并无入职那个公司的打算。

 

第一种是:遗传算法

这个问题可以抽象成数学模型是这样的:
我有一个有向图G,他有n个节点,其中任意一个节点a都有到另外n-1个节点的路径!
例如3个节点的图可以这样解释:(图差不进去)

 

 

箭头我没画,太难了,呵呵!每个路径上有一定的费用,我们要经过每个点,然后回到起点(起点是任意的),经过的点可以重复,并且要产生的费用最小。
这个我个人觉得问题有点难,很像哈密顿路径问题,但是又不是太像。我们暂时称我们要寻找的路径为A路径。我用动态规划没有规划出来,贪心算法有没有最优子结构,虽然有重叠字问题!于是我想到了用遗传算法,关于算法的杂交和变异算子(核心函数),我是这样想的:
 
我们肯定要自己生成几个染色体(就是它的A路径),其中一定要加的是顺时针和逆时针的路径!因为我们总共有n!(n的阶乘)条边,其中我们至少选择n-1条边才能连接n个节点,只有顺时针和逆时针满足这种情况!然后我们在随便挑选几个路径。
 
关于杂交:
我是这样想的,假设我们有7个节点,分别是1,2,3,4,5,6,7我们随机挑选这两个染色体,当然我们用赌轮选择法选择,我们把每个路径的费用相加,然后取倒数就可以了!这样,费用越小的我们选择的空间越大,当然,我们是精英选择,也就是只从前5%优秀的基因(就是倒数最大的前5%),其他的不选择。假设我们选择了
 
                染色体A:1,2,3,4,5,6,7,1
                染色体B:1, 4,2, 5, 3, 7,6,1
 
忘了介绍我们的排序方式,1,2,3表示先从1到2,再从2到3,为了简单表示,我们表示成-12,就像高中的向量,向量12加上向量23,等于向量13,所以呢,1,4,2,3表示,-14,-42,-23,也就是从1到2的代价太大了,我们不得不绕道4。好了杂交开始了:
我们先从B中随机的选择4个节点,节点不能重复,红色就是我们选择的节点,我们随机的在我们选择到的节点中选择一个,例如是4,然后在在剩下的三个节点中选择一个,例如7,然后再A中交换4和7的位置,依次类推,只到了我们选中的节点数都被选光。
 
对B则采用相同的方法,只不过我们从B选择,另外,您觉得可能这个没有杂交,毕竟我们接触遗传算法都是A和B估计得互换一部分自己的染色体,但是,我们遗传算法是采用生物学模拟的,我们的染色体表示一个形状,比如比如耳朵大小,这就像我们的A路径一样,我们每次遗传给下一代,都会有我们耳朵的基因,这就像我们每次都会满足A路径的要求,要是不满足,就相当于给了下一代一个不完整的耳朵,你也看出来了,我们A和B并没有互换染色体,这就相当于动物没有交配就形成了下一代,呵呵,我的看法是,我们的遗传算法是要满足A路径的需求,寻找最优解,没必要完全按照生物上的来,这就是计算机的乐趣!
 
基因突变:
突变的概率是很低的,我们假设是0.001,怎么突变,
 
                染色体A:1, 2,3,4,5,6,7  ,1
 
假设红色为不幸突变的基因,那么我们就把这个加上一个路径,删除多余的那个路径,比如变成了
 
                染色体B:1, 4, 2,3,5,6,7,1
 
就相当于-14然后再-42,当然我们每次突变都能完成A路径的需求,而不是产生残次品,浪费宝贵的CPU资源!
然后遗传算法会收缩,知道我们确定了最小的值,但是这个还是有概率的!
 
我们可以建议一个链表,然后再这个链表达到了最大的容量的时候,我们就找到路径费用最大的那条染色体设为A,和要加入链表的染色体B作比较,如果A比B费用高,我们就剔除A,加入B,如果小,直接删除B。
第二种:贪心算法
 

我们还是模拟成数学问题:

我有一个有向图G,他有n个节点,其中任意一个节点a都有到另外n-1个节点的路径!每个路径上有一定的费用,我们要经过每个点,然后回到起点(起点是任意的),经过的点可以重复,并且要产生的费用最小。

如图三个节点的图:

这次,我们是运用贪心算法给出答案:

我们设函数fn)为必须求出n个节点的路径。设函数gnm)是节点n到节点m的路径的大小,某种原料由机器n到机器m所转化所花的机器设备的钱。我们再设集合Bnm)是{g1m),g2m),gnm},他表示是节点1到节点n和节点m的所有路径的集合。设集合Anm)是{gn1),gn2),gnm}的集合,他表示节点n和节点1到节点m的集合。设我们要寻找的路径为A路径,也就是花费最少的钱。

然后我们就可以回顾一下贪心算法的四个步骤:

1,        寻找最优子结构。

2,        递归描述最优子结构。

3,        证明递归式的正确性。

4,        写代码。

首先我们来看第一:寻找最优子结构

我们要寻找fn)的A路径,首先,我们可以想到,要求n个节点的A路径,我们能不能求一个n-1节点的A路径呢?然后再求n-2A路径,然后是n-3A路径,以此类推,知道节点数剩下最后两个。求出这两个节点的A路径,我们就依次的先上走,直到求出了n个节点的A路径。

第二:递归描述最优子结构

根据我们上面的描述,我们可以这样求解我们的递归式:

fn=fn-1+ min Bn-1n))+ min Ann-1))- when X=YgXY

递归式有点复杂,不是吗?好了,我来解释一下,f函数和集合B前面是我们定义过的,那么min是从集合B中选出最小的值。简单点说,第一个min是选出的是n-1个节点到n最小的路径,第二个min是选出的是节点n到已知的n-1个节点的最小的路径,我们就是要找这两个路径。然后加上fn-1)就是n个节点的路径了。好了,该解释什么是gXY)了,我们设X代表从min Bn-1n))中选出的那个值得节点,而Y代表minAnn-1))中选出的节点。我们必须减去这两个节点的路径。

但是我们不要忘了另外一种情况,就是XY相等时的节点,这时,我们回在计算Ann-1)的第二小的边,然后让他和Y加上gn-1,n)比较大小,如果前者大,则选择后者,就是说我们还得加上gX,Y)的大小,如果后者大,则选择前者。所以我在gXY)前面加上了(when X=Y)。(在图中用红色表示如果选择完了,如下图,这说明由AC和由CA是相等的费用)

千万不要忘了结束递归的条件:

If n=2 return

第三:证明递归式的正确性

这个说实话,也很好证明,我们采取数学归纳法,

n=2时,递归式成立。

假设当n=k时成立。

我们让n=k+1,那么:

fk+1=fk+ min Bkk+1))+ min Ak+1k))- when X=YgXY

因为fk)是成立的,这是我们的假设,那么min Bkk+1))和min Ak+1k))会不会按照我们预期的工作呢?我想大家都已经知道了!

第四:写代码

剩下最不起眼的写代码了,这个留给大家吧!

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值