算法01串
1. 数学建模选课问题完整解答
这个问题应该算是一个0-1背包问题吧。18个学分算是背包容量,每门课的学分是物体体积,物品收益都相同,是1.
第一问属于背包的最少收益问题,第二问是最大收益问题。
然后这个问题应该就可以用经典背包问题求解算法了。比如动态规划:
对课程1,考虑选择它和不选择它
如果选择它,就只需要再选择13个学分,然后这个问题会简化为要选择13个学分,少了课程1后的课程选择问题,问题还是原先的问题,但是问题的规模小了点,剩下的继续递归。
如果不选择它,就需要选择18个学分,,问题简化为18个学分,但是没有课程1,剩下的也递归下去。
两种选择,哪种优选择哪一个。
当进行递归的时候,如果碰到选择方案不能满足约束条件,即任选课大约1/6小于1/3,则该方案返回0值,如果还有同修要求的,比如限选课6,如果开始选择的是不选课程1,那么对于课程6,就不存在选择和不选择问题了,必然是不选择,如果开始第一步选择了课程1,当递归到课程6的时候才有选择和不选两种选择。
最终会得到一组第一问和第二问的最优解,则第三问结果也有了。
另外,附赠一个思路:可以查一下关键词【演化算法】,不用确定性算法,而是用智能优化算法,将所有的课用一个二进制位进行编码,0表示不选,1表示选择。每一种01串表示一种课程选择策略,对应一个学分,还对应一个对各种约束的满足程度,将对约束的违反当做罚函数。然后进行演化算法的选择交叉变异就开始搞,反正演化算法不能说来话长,如果感兴趣自己看看。
2. 算法怎么学
贪心算法的定义:
贪心算法是指在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,只做出在某种意义上的局部最优解。贪心算法不是对所有问题都能得到整体最优解,关键是贪心策略的选择,选择的贪心策略必须具备无后效性,即某个状态以前的过程不会影响以后的状态,只与当前状态有关。
解题的一般步骤是:
1.建立数学模型来描述问题;
2.把求解的问题分成若干个子问题;
3.对每一子问题求解,得到子问题的局部最优解;
4.把子问题的局部最优解合成原来问题的一个解。
如果大家比较了解动态规划,就会发现它们之间的相似之处。最优解问题大部分都可以拆分成一个个的子问题,把解空间的遍历视作对子问题树的遍历,则以某种形式对树整个的遍历一遍就可以求出最优解,大部分情况下这是不可行的。贪心算法和动态规划本质上是对子问题树的一种修剪,两种算法要求问题都具有的一个性质就是子问题最优性(组成最优解的每一个子问题的解,对于这个子问题本身肯定也是最优的)。动态规划方法代表了这一类问题的一般解法,我们自底向上构造子问题的解,对每一个子树的根,求出下面每一个叶子的值,并且以其中的最优值作为自身的值,其它的值舍弃。而贪心算法是动态规划方法的一个特例,可以证明每一个子树的根的值不取决于下面叶子的值,而只取决于当前问题的状况。换句话说,不需要知道一个节点所有子树的情况,就可以求出这个节点的值。由于贪心算法的这个特性,它对解空间树的遍历不需要自底向上,而只需要自根开始,选择最优的路,一直走到底就可以了。
话不多说,我们来看几个具体的例子慢慢理解它:
1.活动选择问题
这是《算法导论》上的例子,也是一个非常经典的问题。有n个需要在同一天使用同一个教室的活动a1,a2,…,an,教室同一时刻只能由一个活动使用。每个活动ai都有一个开始时间si和结束时间fi 。一旦被选择后,活动ai就占据半开时间区间[si,fi)。如果[si,fi]和[sj,fj]互不重叠,ai和aj两个活动就可以被安排在这一天。该问题就是要安排这些活动使得尽量多的活动能不冲突的举行。例如下图所示的活动集合S,其中各项活动按照结束时间单调递增排序。
关于贪心算法的基础知识就简要介绍到这里,希望能作为大家继续深入学习的基础。
3. C语言问题:输入一个二进制数,输出其对应的十进制数。(包括正数、负数、小数)
11(二进制)=3 (十进制) 对了要加分
4. 密码学的基础问题
这是一个非常经典的密码学问题,即在已知加密算法和相应的密文下,如何破解密钥。这个问题一般被称为线性密码分析。
对于这个特定的加密算法,我们可以选择n个明文,其中每个明文的第i位都是0或1,除了第i位是1,其他位都是0。然后,我们将这n个明文和相应的密文都表示为n维列向量,记为M1、M2、...、Mn和C1、C2、...、Cn。
接下来,我们需要计算n个方程式,每个方程式形如Cj = K*Mj,其中j=1,2,...,n。这n个方程式可以表示为一个矩阵形式:C = KM,其中C、K和M都是n维列向量,而矩阵乘法和加法都是在有限域GF(2)上进行的。
由于K是未知的,我们需要解出这个方程组中的未知数K。这可以通过矩阵的逆运算来实现,即K = C*M^(-1),其中M^(-1)是M的逆矩阵。
然而,在实践中,由于存在噪声和误差,我们不能完全恢复出K。因此,我们需要使用某些统计方法来估计K的值。一种常见的方法是使用相关系数来度量明文和密文之间的关系,然后通过最小化相关系数的平方和来估计K的值。此外,还有其他一些更高级的技术可以用于线性密码分析。
总的来说,需要选择的明文数量取决于加密算法和密钥的复杂性,以及攻击者拥有的计算能力和统计学知识。通常,需要选择的明文数量比密钥长度要大得多,才能成功地破解加密算法。