设为首页 - 加入收藏
广告 1000x90
您的当前位置:E乐彩票app下载 > 博弈树搜索 > 正文

最小-最大搜索和Alpha-beta剪枝搜索

来源:未知 编辑:admin 时间:2019-04-20

  在国际象棋里,双方棋手都知道每个棋子在哪里,他们轮流走并且可以走任何合理的着法。下棋的目的就是将死对方,或者避免被将死,或者有时争取和棋是最好的选择。

  国际象棋程序通过使用“搜索”函数来寻找着法。搜索函数获得棋局信息,然后寻找对于程序一方来说最好的着法。

  一个浅显的搜索函数用“树状搜索”(Tree-Searching)来实现。一个国际象棋棋局通常可以看作一个很大的

  叉树”意思是树的每个结点有任意多个分枝通向其他结点),棋盘上目前的局面就是“根局面”(Root Position)或“根结点”(Root Node)。从根局面走一步棋,局面就到达根局面的“分枝”(Branch),这些局面称为“后续局面”(Successor Position)或“后续结点”(Successor Nodes)。每个后续局面后面还有一系列分枝,每个分枝就是这个局面的一个合理的着法。

  叉树,如果能通过树状搜索找到棋局中对双方来说都最好的着法就好了。这个浅显的算法在这里称为“最小-最大搜索”(Min-max Search)。

  用最小-最大搜索来解诸如井字棋的简单棋局是可行的(即完全了解每一种变化)。井字棋的博弈树既不烦琐也不深,所以整个树可以遍历,棋局的所有变化都可以知道,任何局面都可以保证找到一步最佳着法。

  数学上用这种方法处理国际象棋也是可以的,但是目前和不久的将来用计算机去实现,却是不可行的。即便如此,我们仍然可以用基于最小-最大搜索的程序来下国际象棋。相比最小-最大地搜索整个树,在一个给定的局面下搜索前几步则是可能的。由于叶子结点的局面没能搜索出杀棋或和棋,所以要用一个称为“评价”(Evaluate)的启发函数给这些局面赋值。尽管程序设计师希望这些值能够通过知识来得到,但它们确实都是猜的。

  我不打算在这里谈很多关于评价函数的细节。这里我只说明它是怎样确定的,在以后的章节中会详细展开。评价函数首先应该返回局面的准确值,在没办法得到准确值的情况下,如果可能的话启发值也可以。它可以由两种方法来决定:

  (1) 如果黑方被将死了,那么评价函数返回一个充分大的正数;如果白方被将死了,那么返回一个充分大的负数;如果棋局是和棋(例如某一方逼和,或者双方都只有王),那么返回一个常数,通常是零或接近零。如果不是棋局结束局面,那么它返回一个启发值。我将不详细介绍这个启发值是如何确定的,但是我有把握说子力平衡是首先要考虑的(如果白方盘面上多子的话,这个值就大),而其他位置上的考虑(兵型、王的安全性、重要的子力等等)也需要加上。如果白方是赢棋或者很有希望赢,那么启发函数通常会返回正数;如果黑方是赢棋或者很有希望赢,那么返回负数;如果棋局是均势或者是和棋,那么返回在零左右的数值。

  (2) 这个函数的工作原理跟第一个一样,只是如果当前局面要走子的一方优势,那么它返回正数,反之是负数。

  最小-最大搜索是一对几乎一样的函数,或者说两个逻辑上重复的函数。我写了很少的代码,用一个更好的函数来完成同一件事,但是写出来时却收到一些意见,因此我首先写出纯粹的(不完美的)最小-最大函数,代码如下:

  if (SideToMove() == WHITE) {// 白方是“最大”者

  int best = INFINITY;// 注意这里不同于“最大”算法

  if (val best) { // 注意这里不同于“最大”算法

  这里的“评价”函数用的是我上面所说第一种定义,它总是返回对于白方来说的局面。

  我简要描述一下这个函数是如何运作的。假设根局面(棋盘上当前局面)是白方走,那么调用的是“Max”函数,它产生白方所有合理着法。在每个后续局面中,调用的是“Min”函数,它对局面作出评价并返回。由于现在是白走,因此白方需要让评价尽可能地大,能得到最大值的那个着法被认为是最好的,因此返回这个着法的评价。

  “Min”函数正好相反,当黑方走时调用“Min”函数,而黑方需要尽可能地小,因此选择能得到最小值的那个着法。

  这两个函数是互相递归的,即它们互相调用,直到达到所需要的深度为止。当函数到达最底层时,它们就返回“Evaluate”函数的值。

  如果在深度为1时调用“MinMax”函数,那么“Evaluate”函数在走完每个合理着法之后就调用,选择一个能达到最佳值的那个着法导致的局面。如果层数大于1,那么另一方有权选择局面,并找一个最好的。

  负值最大只是对最小-最大的优化,“评价”函数返回我所说的第二种定义,对于当前结点上要走的一方,占优的情况返回正值,其他结点也是对于要走的一方而言的。这个值返回后要加上负号,因为返回以后就是对另一方而言了。代码如下:

  val = -NegaMax(depth - 1); // 注意这里有个负号。

  在这个函数里,当走子一方改变时就要对返回值取负值,以反映当前局面评价的更改。就根结点是白先走的情况,如果没有剩下的层数,那么“评价”返回的值是就白方而言的,如果有剩下的层数,就产生后续局面,函数对这些局面逐一做递归,每个次递归都得到就黑方而言的评价,黑方走得越好值就越大。当评价值返回时,它们被取负数,变成就白方而言的评价。

  该函数在遍历时结点的顺序同“最小-最大”搜索的函数是一样的,产生的返回值也一样。它的代码更短,同时减少了移植代码时出错的可能,代码维护起来也比较方便。

  Alpha-Beta 同“最小-最大”非常相似,事实上只多了一条额外的语句。最小最大运行时要检查整个博弈树,然后尽可能选择最好的线路。这是非常好理解的,但效率非常低。每次搜索更深一层时,树的大小就呈指数式增长。

  通常一个国际象棋局面都有35个左右的合理着法,所以用最小-最大搜索来搜索一层深度,就有35个局面要检查,如果用这个函数来搜索两层,就有35

  个局面要搜索。这就已经上千了,看上去还不怎样,但是数字增长得非常迅速,例如六层的搜索就接近是二十亿,而十层的搜索就超过两千万亿了。

  要想通过检查搜索树的前面几层,并且在叶子结点上用启发式的评价,那么做尽可能深的搜索是很重要的。最小-最大搜索无法做到很深的搜索,因为有效的分枝因子实在太大了。

  幸运的是我们有办法来减小分枝因子,这个办法非常可靠,实际上这样做绝对没有坏处,纯粹是个有益的办法。这个方法是建立在一个思想上的,如果你已经有一个不太坏的选择了,那么当你要作别的选择并知道它不会更好时,你没有必要确切地知道它有多坏。有了最好的选择,任何不比它更好的选择就是足够坏的,因此你可以撇开它而不需要完全了解它。只要你能证明它不比最好的选择更好,你就可以完全抛弃它。

  你可能仍旧不明白,那么我就举个例子。比如你的死敌面前有很多口袋,他和你打赌赌输了,因此他必须从中给你一样东西,而挑选规则却非常奇怪:

  每个口袋里有几件物品,你能取其中的一件,你来挑这件物品所在的口袋,而他来挑这个口袋里的物品。你要赶紧挑出口袋并离开,因为你不愿意一直做在那里翻口袋而让你的死敌盯着你。

  很显然,当你挑出口袋时,你的死敌会把口袋里最糟糕的物品给你,因此你的目标是挑出“诸多最糟的物品当中是最好的”那个口袋。

  你很容易把最小-最大原理运用到这个问题上。你是最大一方棋手,你将挑出最好的口袋。而你的死敌是最小一方棋手,他将挑出最好的口袋里尽可能差的物品。运用最小-最大原理,你需要做的就是挑一个有“最好的最差的”物品的口袋。

  假设你可以估计口袋里每个物品的准确价值的话,最小-最大原理可以让你作出正确的选择。我们讨论的话题中,准确评价并不重要,因为它同最小-最大或Alpha-Beta的工作原理没有关系。现在我们假设你可以正确地评价物品。

  最小-最大原理刚才讨论过,它的问题是效率太低。你必须看每个口袋里的每件物品,这就需要花很多时间。

  我们从第一个口袋开始,看每一件物品,并对口袋作出评价。比方说口袋里有一只花生黄油三明治和一辆新汽车的钥匙。你知道三明治更糟,因此如果你挑了这只口袋就会得到三明治。事实上只要我们假设对手也会跟我们一样正确评价物品,那么口袋里的汽车钥匙就是无关紧要的了。

  现在你开始翻第二个口袋,这次你采取的方案就和最小-最大方案不同了。你每次看一件物品,并跟你能得到的最好的那件物品(三明治)去比较。只要物品比三明治更好,那么你就按照最小-最大方案来办——去找最糟的,或许最糟的要比三明治更好,那么你就可以挑这个口袋,它比装有三明治的那个口袋好。

  比方这个口袋里的第一件物品是一张20美元的钞票,它比三明治好。如果包里其他东西都没比这个更糟了,那么如果你选了这个口袋,它就是对手必须给你的物品,这个口袋就成了你的选择。

  这个口袋里的下一件物品是六合装的流行唱片。你认为它比三明治好,但比20美元差,那么这个口袋仍旧可以选择。再下一件物品是一条烂鱼,这回比三明治差了。于是你就说“不谢了”,把口袋放回去,不再考虑它了。

  无论口袋里还有什么东西,或许还有另一辆汽车的钥匙,也没有用了,因为你会得到那条烂鱼。或许还有比烂鱼更糟的东西(那么你看着办吧)。无论如何烂鱼已经够糟的了,而你知道挑那个有三明治的口袋肯定会更好。

  Alpha-Beta就是这么工作的,并且只能用递归来实现。稍后我们再来谈最小一方的策略,我希望这样可以更明白些。

  这个思想是在搜索中传递两个值,第一个值是Alpha,即搜索到的最好值,任何比它更小的值就没用了,因为策略就是知道Alpha的值,任何小于或等于Alpha的值都不会有所提高。

  第二个值是Beta,即对于对手来说最坏的值。这是对手所能承受的最坏的结果,因为我们知道在对手看来,他总是会找到一个对策不比Beta更坏的。如果搜索过程中返回Beta或比Beta更好的值,那就够好的了,走棋的一方就没有机会使用这种策略了。

  在搜索着法时,每个搜索过的着法都返回跟Alpha和Beta有关的值,它们之间的关系非常重要,或许意味着搜索可以停止并返回。

  如果某个着法的结果小于或等于Alpha,那么它就是很差的着法,因此可以抛弃。因为我前面说过,在这个策略中,局面对走棋的一方来说是以Alpha为评价的。

  如果某个着法的结果大于或等于Beta,那么整个结点就作废了,因为对手不希望走到这个局面,而它有别的着法可以避免到达这个局面。因此如果我们找到的评价大于或等于Beta,就证明了这个结点是不会发生的,因此剩下的合理着法没有必要再搜索。

  如果某个着法的结果大于Alpha但小于Beta,那么这个着法就是走棋一方可以考虑走的,除非以后有所变化。因此Alpha会不断增加以反映新的情况。有时候可能一个合理着法也不超过Alpha,这在实战中是经常发生的,此时这种局面是不予考虑的,因此为了避免这样的局面,我们必须在博弈树的上一个层局面选择另外一个着法。

  在第二个口袋里找到烂鱼就相当于超过了Beta,如果口袋里没有烂鱼,那么考虑六盒装流行唱片的口袋会比三明治的口袋好,这就相当于超过了Alpha(在上一层)。算法如下,醒目的部分是在最小-最大算法上改过的:

  把醒目的部分去掉,剩下的就是最小-最大函数。可以看出现在的算法没有太多的改变。

  这个函数需要传递的参数有:需要搜索的深度,负无穷大即Alpha,以及正无穷大即Beta:

  val = AlphaBeta(5, -INFINITY, INFINITY);

  这样就完成了5层的搜索。我在写最小-最大函数时,用了一个诀窍来避免用了“Min”还用“Max”函数。在那个算法中,我从递归中返回时简单地对返回值取了负数。这样就使函数值在每一次递归中改变评价的角度,以反映双方棋手的交替着子,并且它们的目标是对立的。

  在Alpha-Beta函数中我们做了同样的处理。唯一使算法感到复杂的是,Alpha和Beta是不断互换的。当函数递归时,Alpha和Beta不但取负数而且位置交换了,这就使得情况比口袋的例子复杂,但是可以证明它只是比最小-最大算法更好而已。

  最终出现的情况是,在搜索树的很多地方,Beta是很容易超过的,因此很多工作都免去了。

  这个算法严重依赖于着法的寻找顺序。如果你总是先去搜索最坏的着法,那么Beta截断就不会发生,因此该算法就如同最小-最大一样,效率非常低。该算法最终会找遍整个博弈树,就像最小-最大算法一样。

  如果程序总是能挑最好的着法来首先搜索,那么数学上有效分枝因子就接近于实际分枝因子的平方根。这是Alpha-Beta算法可能达到的最好的情况。

  由于国际象棋的分枝因子在35左右,这就意味着Alpha-Beta算法能使国际象棋搜索树的分枝因子变成6。

  这是很大的改进,在搜索结点数一样的情况下,可以使你的搜索深度达到原来的两倍。这就是为什么使用Alpha-Beta搜索时,着法顺序至关重要的原因。

  你搜索到F,发现子结点的评价分别是11、12、7和9,在这层是棋手甲走,我们希望他选择最好的值,即12。所以,F的最小-最大值是12。

  现在你开始搜索G,并且第一个子结点就返回15。一旦如此,你就知道G的值至少是15,可能更高(如果另一个子结点比G更好)。这就意味着我们不指望棋手乙走G这步了,因为就棋手乙看来,F的评价12要比G的15(或更高)好,因此我们知道G不在主要变例上。我们可以裁剪(Prune)结点G下面的其他子结点,而不要对它们作出评价,并且立即从G返回,因为对G作更好的评价只是浪费时间。

  一般来说,像G一样只要有一个子结点返回比G的兄弟结点更好的值(对于结点G要走棋的一方而言),就可以进行裁剪。

  我们来讨论更复杂的可能裁剪的情况。例如在同一棵搜索树中,我们评价的G、H和I都比12好,因此12就是结点B的评价。现在我们来搜索结点C,在下面两层我们找到了评价为10的结点N:

  我们能用更为复杂的路线来作裁剪。我们知道N会返回10或更小(轮到棋手乙走棋,需要挑最小的)。我们不知道J能否返回10或更小,也不知道J的哪个子结点会更好。如果从J返回到C的是10或者更小的值,那么我们可以在结点C上作裁剪,因为它有更好的兄弟结点B。因此在这种情况下,继续找N的子结点就毫无意义。考虑其他情况,J的其他子结点返回比10更好的值,此时搜索N也是毫无意义的。所以我们只要看到10,就可以放心地从N返回。

  一般来说,如果返回值比偶数层的兄弟结点好,我们就可以立即返回。如果我们在搜索过程中,把这些兄弟结点的最小值Beta作为参数来传递,我们就可以进行非常有效的裁剪。我们还用另一个参数Alpha来保存奇数层的结点。用这两个参数来进行裁剪是非常有效的,代码就写在下边。像上次一样,我们用负值最大(Negamax)的形式,即搜索树的层数改变时取负值。

  double alphabeta(int depth, double alpha, double beta) {

  double val = -alphabeta(depth - 1, -beta, -alpha);

  Alpha和Beta定义了一个评价的实数区间(Alpha, Beta),这个区间是我们“感兴趣的”。如果某值比Beta大我们就会做裁剪并立即返回,因为我们知道它不是主要变例的一部分,我们对它的准确值不感兴趣,只需要知道它比Beta大。如果某值比Alpha小,我们不作裁剪,但是仍然对它不感兴趣,因为我们知道搜索树里肯定有一个着法会更好。

  但是在搜索树的根结点,我们不知道感兴趣的评价是在哪个范围内,如果我们要保证不会因为意外而裁剪掉重要的部分,我们就设Alpha = -Infinity,Beta = Infinity(无穷大)。

  但是,如果我们使用迭代加深,就可能有办法知道主要变例是怎么样的。假设我们猜其值为

  + Epsilon)内。这种情况下,我们知道它返回的是正确值,我们就能放心地选择这个着法,在搜索树中这个着法指向具有返回值的那个结点。

  + Epsilon,但是我们不知道它到底是几(正确的主要变例可能被裁剪掉了,因为我们看到有别的着法的值大于Beta)。我们必须把我们所猜的值

  调整得更高,然后再试一次(可能还要用更大的Epsilon)。这种情况称为“高出边界”(Fail High)。

  调整得更低,然后再试一次(可能还要用更大的Epsilon)。这种情况称为“低出边界”(Fail Low)。

  即便有两种可能失败的情况,使用期望搜索(用一个比(-Infinity, Infinity)更小的区间(Alpha, Beta))总体来说效率会有所提高,因为它作了更多的裁剪。

  让我们对Alpha-Beta搜索作一下分析,来知道它为什么是个很有用的算法。跟普通的算法不同,我们采用“Beta情况的分析”,即假设任何可能的情况下都会发生Alpha-Beta裁剪。下一次我们会知道如何让Alpha-Beta搜索接近我们的所分析的情况。在这里我只考虑浅的裁剪,因为它会让分析变得更加简单。

  在最好的情况下,除了主要变例上的结点不会裁剪外(如果这个结点也被裁剪了,那么整个算法会高出边界或低出边界,这当然不是最好的情况),在裁剪前,深

  -2层时,谁也没有被裁剪,因为所有的子结点都返回大于或等于Beta的值,而

  ,那么在搜索树一半的深度上,结点以因子B作增长,而在另一半的深度上则保持不变(我们忽略了主要变例)。所以这个搜索树所有要搜索的结点数,粗略地写成

  。因此Alpha-Beta搜索最终可以将分枝因子减少为原来的平方根那么多,因此它可以让我们搜索原来两倍的深度。正因为这个原因,它是所有基于最小-最大策略的棋类对弈程序的最重要的算法。

  【译注:原作者一开始提到的“浅的裁剪”和“深的裁剪”这两个概念,实际上包含了

  double alphabeta(int depth, double beta) {

  double val = -alphabeta(depth - 1, -alpha);

  Alpha-Beta剪枝用于裁剪搜索树中没有意义的不需要搜索的树枝,以提高运算速度。

  上图为整颗搜索树。这里使用极小极大算法配合Alpha-Beta剪枝算法,正方形为自己(A),圆为对手(B)。

  对于B(第四层)而已,尽量使得A获利最小,因此当遇到使得A获利更小的情况,则需要修改β。这里3小于正无穷大,所以β修改为3。

  对于A(第三层)而言,自己获利越大越好,因此遇到利益值大于α的时候,需要α进行修改,这里3大于负无穷大,所以α修改为3

  B(第四层)拥有一个方案使得A获利只有2,α=3,  β=2, α  β, 说明A(第三层)只要选择第二个方案, 则B必然可以使得A的获利少于A(第三层)的第一个方案,这样就不再需要考虑B(第四层)的其他候选方案了,因为A(第三层)根本不会选取第二个方案,多考虑也是浪费.

  B(第二层)要使得A利益最小,则B(第二层)的第二个方案不能使得A的获利大于β, 也就是3. 但是若B(第二层)选择第二个方案, A(第三层)可以选择第一个方案使得A获利为15, α=15,  β=3, α  β, 故不需要再考虑A(第三层)的第二个方案, 因为B(第二层)不会选择第二个方案.

  A(第一层)使自己利益最大,也就是A(第一层)的第二个方案不能差于第一个方案, 但是A(第三层)的一个方案会导致利益为2, 小于3, 所以A(第三层)不会选择第一个方案, 因此B(第四层)也不用考虑第二个方案.

  当A(第三层)考虑第二个方案时,发现获得利益为3,和A(第一层)使用第一个方案利益一样.如果根据上面的分析A(第一层)优先选择了第一个方案,那么B不再需要考虑第二种方案,如果A(第一层)还想进一步评估两个方案的优劣的话, B(第二层)则还需要考虑第二个方案,若B(第二层)的第二个方案使得A获利小于3,则A(第一层)只能选择第一个方案,若B(第二层)的第二个方案使得A获利大于3,则A(第一层)还需要根据其他因素来考虑最终选取哪种方案.

  1.极小极大搜索方法   一般应用在博弈搜索中,比如:围棋,五子棋,象棋等。结果有三种可能:胜利、失败和平局。暴力搜索,如果想通过暴力搜索,把最终的结果得到的话,搜索树的深度太大了,机器不能满足,一般...博文来自:Allure Love的博客

  最近正在做一个人工智能的中国象棋,所以不可避免的接触到了博弈论,因为考虑到以后还会有所涉及(alpha-betasearch),所以写成了一片文章这里以中国象棋为前提,AI首先需要一个博弈树(变种的二...博文来自:Racal

  看了很多帖子,都没这个帖子讲的清楚.Alpha-Beta剪枝搜索是棋类走子计算的首选算法,由于估值函数问题,不适用于围棋...博文来自:正在编程

  博弈树搜索在下图中,第一层节点表示开始局面,我方先走,第二层节点表示我方可走的三个位置,第三层节点表示对于我方的每一种走法对手的各种走法,下方数字代表了对每个局面的评价值。这里的评价值都是相对于我方来...博文来自:启人zhr的博客

  最近用到Alpha-Beta剪枝算法,对其原理是理解了,但是,程序不太理解。参考了一下别人的源码,看到有一些在递归的时候,是这样调用的: 原定义:AlphaBeta(depth,alpha,beta)论坛

  目录一、问题描述二、算法描述三、评估函数四、参考资料五、源代码(Java版)一、问题描述利用极小极大搜索和alpha-beta剪枝算法预测五子棋落子问题,初始棋局如图所示,AI为白子,玩家为黑子,当前...博文来自:一颗贪婪的星

  Alpha-Beta搜索作为棋类算法最常用的一种搜索算法,也是最基本的一种博弈搜索算法。Alpha-Beta主要考虑了最大最小搜索中的冗余搜索问题,极大的减少了冗余搜索量,提高了搜索效率。最小-最大的...博文来自:九三智能控

  alpha-beta剪枝算法及实践算法原理算法伪码中国象棋AI实践算法原理alpha-beta剪枝算法是基于极大极小搜索算法的。极大极小搜索策略是考虑双方对弈若干步之后,从可能的步中选一步相对好的走法...博文来自:洋葱的博客

  Alpha-beta算法是棋类游戏中最常用的,也是最基础的剪枝方法,要说Alpha-beta算法就得先说下max_min博弈树算法,就是模拟电脑下子,要下在对电脑最优的地方,模拟人下子就要下在对人最优...博文来自:但求心安的博客

  最近在做中国象棋对弈程序,用到了alpha-beta算法。这个博文来自:贰到不行的专栏

  在博弈游戏中,可以将游戏过程,用一棵博弈树进行存储,树上每个节点表示游戏状态,树枝表示动作。为了赢得游戏,需要有一定的前瞻性(即搜索深度要尽可能深一些),但是随着搜索深度的加深,需要考虑的状态数目成指...博文来自:Ontheway的博客

  看本章之前,请先参看前一篇文章《Minimax算法及实例分析》由于Minimax算法有一个很大的问题就是计算复杂性。由于所需搜索的节点数随最大深度呈指数膨胀,而算法的效果往往和深度相关,因此这极大限制...博文来自:我的专栏

  有人说“即使一把火把可口可乐烧得精光,它也能凭借着它的LOGO东山再起。“当然了,至于有没有人说过,我们无法考证。但是这句话充分说明了一个LOGO所能发挥的作用。LOGO对对大部分网站来说应该是不可或...

  创建一个简单的动画常用快捷键:command+3打开预览界面;空格键直接预览1、command+N创建一个工作空间,尺寸选择720x1280或者如图在当前工作空间右键NewComposition2、在...

  前段时间在完成老师布置的一个简单的20以内加减法的在线做题系统,在设计页面的时候,我想到了logo的问题。▍LOGASTER碰巧的是,我在一个公众号看到了一个设计logo的网站:

  lomo风格是一种带有暗角的非主流风格,一直以来因其独特的韵味受人们的喜爱示例5新建合成,导入素材,选择图层,添加曲线 ,降低红色通道添加 cccomposite  透明度为75%,composite...

  ltd0924的博客2.5D风格场景插画立体图案一键生成PS插件_安装教程

  首先我们需要下载陌鱼社区快速实现2.5D风格场景插画PS扩展面板或者扁平化2.5D轴测概念插画生成PS扩展面板,一个是Win版,一个是Mac版,按自己需求下载,下面我们来演示一下安装教程。01、软件图...

  作者:ArashiH链接:来源:知乎著作权归作者所有。商业转载请联系作者获得授权,非商业...

  文章目录前言核心Core-Code总结前言需求:(项目又一反人类需求)不同的样式模板,替换数据生成新的PPT花了我4天时间,转载请注明作者感谢~核心效果图:读取模板,样式不变只替换其中数据POI操作数...

  手机应用上有很多地方需要用到动画的地方,比如启动页面欢迎界面等,有些动画比如简单的伸缩旋转等我们可以用属性动画来制作,但是涉及到一些复杂的不规则的动画我们要实现起来就很麻烦,但是利用lottie加载j...

  weixin_34128237的博客【热门】零基础学手绘插画,需要掌握哪些要点?

  零基础学手绘插画,需要掌握哪些要点?这是学习画手绘插画的人最开始苦恼的一个问题。想要让自己更好的画出完美的手绘插画,是需要掌握一些小技巧的。下面就和小编一起来看看零基础自学手绘插画的方法。学手绘插...

  在视频制作过程中少不了一些文字,但是如果只是单纯的文字总觉得有些单调,那今天我们来讲一讲特效文字。首先普及一下,其实ae自带了很多效果动画完全可以满足我们的基本需求                  ...

  ae有着大量的效果动效可以创建丰富多彩的视频特效,这也为影视后期工作提供了无限的创作的空间,通过不同效果的组合可以产生各种你想要的特效从最简单的特效开始 天空云雾 模拟自己想要的天空素材以用于更换实际...

  替换素材:如图所示,相框外的人是成双成对的,相框里面的却只有一个人,我们想要把这个素材替换成两个人的。我们鼠标放到视频预览框的任何一个元素上面底部都会提示这是什么素材。比如我放到一个人的上面,则该人物...

  acetaohai123123的博客ae教程 (六)人物滤镜 (二)清新粉色调

  示例2:清新粉色调这里我以图片作为示例,但其同样可以应用视频新建合成,拖入素材,复制该图层,选中顶层图层添加效果通道通道合成器 参数如下  添加 颜色平衡(HLS),降低饱和度至-100,使图片变为黑...

  示例三:烟花这里主要用粒子运动来创建模拟烟花的粒子效果,通过添加发光效果来增强烟花发光发亮的效果首先新建合成,新建黑色纯色层,命名为烟花,添加粒子运动场 ,具体参数如图所示,粒子数颜色等参数可以稍微调...

  之前一直有人问我关于如何做海报,如何做徽章之类的问题。起初我推荐他们去看oeasy的ps教程,但是该教程比较系统,需要的时间较长,无法满足他们在较短的时间出作品的愿望。于是我想把我自己的经历教给他们。...

  功能需求:模拟电影里面酷炫吊的各种动态全息界面,如图:参考教程:(需翻墙)电影里面都是后期合成的这些高科技,所以我...

  ae教程 (六)人物滤镜 (一)林间光线:林间光线在本例中主要应用Shine效果创建发射光束,模拟树林中晨雾的透光效果老规矩,新建合成,将树林的图片拖入时间线添加曲线 效果,降低亮度选中图层添加效果TrapcodeShine 具体参数...博文来自:ltd0924的博客

  如何制作一张海报摘要海报设计是一种产品、一张名片、一个品牌宣传工作中重要的一环。海报设计其实更是一种艺术,它强调文字与图案的结合,色彩与结构的搭配。设计巧妙的海报设计能够到来人气和利润,而缺乏设计的海...博文来自:weixin_40377691的博客

  今天带来的这些规范,可是成为优秀UI设计师必须知道的“纯干货”,还能让大家深刻了解UI设计规范()的本质是什么。图标规范很多设计师以为UI设计就是设计图标。...博文来自:jongde1的专栏

  酷炫的AE火焰特效怎么做?两种方式教你快速实现这么高大上的效果!方法1:用到爱剪辑里的“烈火燎原”的动景特效先可以看看加上火焰特效后,画面一下有了炸裂的视觉感。把视频导入到爱剪辑后,在界面顶部选择“画...博文来自:Skr520的博客

  深度学习读书笔记之AE声明:1)该博文是整理自网上很大牛和机器学习专家所无私奉献的资料的。具体引用的资料请看参考文献。具体的版本声明也参考原文献。2)本文仅供学术交流,非商用。所以每一部分具体的参考资...博文来自:mytestmy的专栏

  2.5D插画设计风格,已经越来越多的出现我们的UI设计中,H5动画、APP闪屏、广告banner、ICON等等,那我们来看看2.5D到底是什么样的风格。       好了,看到这里,不知道有木有小心动...博文来自:programmer_feng的博客

  上篇主要介绍了一下2.5d矢量插画,这篇咱们来说说它的绘制吧!使用软件:illustrator(AI源文件可以在文末进群向管理员索要哦~免费视频课程在文末,点击即可进入,11月6日晚19:00准时直播...博文来自:万和IT教育

  插画,西文统称为「illustration」,源自于拉丁文「illustraio」,意指照亮之意,也就是说插画可以使文字意念变得更明确清晰。现代的插画大多为商业服务,应用于各种版面包括挂历、书籍、刊物...博文来自:weixin_34107739的博客

  对于刚入行的UI设计师,最容易犯的错就是在设计移动APP时,不懂什么尺寸或者用哪种屏幕的尺寸是最适当的?为了解决这个问题,今天我们就简单的为大家整理做UI时最基础的尺寸规范。现象首先说现象,大家都知道...博文来自:盐碘

  色彩是极富艺术表现力的视觉预言,不同的颜色会给人们的情绪带来不同的反应,既能起到渲染环境,营造气氛的作用新建合成导入素材设置合成的时长添加曲线 降低红色,稍提高亮度复制图层,选择顶层图层,设置混合模式...博文来自:ltd0924的博客

  分享一个最近做业务遇到的简单又蛮有意思的的文本显示处理过程。具体就是有这么一段文字,类似“转盘抽奖获得跑车x1,点击领取~”,用TextView显示。设计师:“能让文字加粗吗?”“可以”,然后加上了粗...博文来自:振之的博客

  一、简介:Lottie是一个可以播放由AE打包的json动画文件的开源库,使用它,你可以简单实现播放利用AE制作的动画。(其实Lottie的本质就是解析.json文文件并通过Canvas方式进行绘制动...博文来自:的博客

  1. 前言 隐马尔科夫HMM模型是一类重要的机器学习方法,其主要用于序列数据的分析,广泛应用于语音识别、文本翻译、序列预测、中文分词等多个领域。虽然近年来,由于RNN等深度学习方法的发展,HMM模型...博文来自:tostq的专栏

  有了上篇单目标定示例程序的经验,双目标定就是小菜一碟哈。 本人目前菜鸟,但还是愿意厚着脸皮分享我一下午的成果。不要拍我... 1.找到目录   ...\opencv\sources\sam...博文来自:t247555529的博客

  reids是一个key-value存储系统,为了保证效率,缓存在内存中,但是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,以保证数据的持久化。   所以:redis是一...博文来自:那么好,

  帐号相关流程注册范围 企业 政府 媒体 其他组织换句话讲就是不让个人开发者注册。 :)填写企业信息不能使用和之前的公众号账户相同的邮箱,也就是说小程序是和微信公众号一个层级的。填写公司机构信息,对公账...博文来自:小雨同学的技术博客

  XML基础+Java解析XML 一:XML基础 XML是什么: 可扩展的标记语言 XML能干什么: 描述数据、存储数据、传输(交换)数据。 XML与HTML区别: 目的不一样 XML...博文来自:NWK工作者的博客

  最近在公司做一个项目,老大让我们实现加解密的方法,我把工作直接推给了java服务端,他们也是直接在网上copy的代码,说我直接放到我的android代码中就可以了,不需要太多的更改。我就照做了,但是在...博文来自:HarryWeasley的专栏

  多重背包问题:有N种物品和容量为V的背包,若第i种物品,容量为v[i],价值为w[i],共有n[i]件。怎样装才能使背包内的物品总价值最大?网上关于“多重背包”的资料倒是不少,但是关于怎么实现O(N*...博文来自:flyinghearts的专栏

  最近比较有空,大四出来实习几个月了,作为实习狗的我,被叫去研究Docker了,汗汗! Docker的三大核心概念:镜像、容器、仓库 镜像:类似虚拟机的镜像、用俗话说就是安装文件。 容器:类似一个轻量...博文来自:我走小路的博客

  强连通分量: 简言之 就是找环(每条边只走一次,两两可达) 孤立的一个点也是一个连通分量   使用tarjan算法 在嵌套的多个环中优先得到最大环( 最小环就是每个孤立点)   定义: int Ti...博文来自:九野的博客

  jquery/js实现一个网页同时调用多个倒计时(最新的) 最近需要网页添加多个倒计时. 查阅网络,基本上都是千遍一律的不好用. 自己按需写了个.希望对大家有用. 有用请赞一个哦! //js ...博文来自:Websites

  详细过程见下面的链接: 需要更新的是: 1. 原文中bag 数据的下载地...博文来自:feixin620的博客

  默认maven的本地仓库的位置是在C盘,如果重装了系统,仓库就没了,因此,把仓库位置改到其他盘。     第一步:打开maven安装位置下的conf/settings.xml;   第二步:在第5...博文来自:a24b86的博客

  花了几天,终于把matlab版的人脸检测运行成功了,虽然正确率不是很高,看着各种论文上的人脸检测正确率都出奇的高,我是不怎么相信的,有的论文连基于平均脸的人脸检测正确率都能达到98%,汗啊~~  也许...博文来自:海海人生

  最近在学习大数据,在学习的时候碰到了一个问题就是给CentOS虚拟机配置静态IP后,就无法访问网络了,这个问题纠结了我好长时间,现在终于找到解决方法了,赶紧记录下来,以备以后查询。注: 我这里说的方法...博文来自:u012453843的专栏

  上一篇文章讲解了SNMP的基本架构,本篇文章将重点分析SNMP报文,并对不同版本(SNMPv1、v2c、v3)进行区别! 四、SNMP协议数据单元 在SNMP管理中,管理站(NMS)和代理(Age...博文来自:假装在纽约

  CGLIB介绍与原理(部分节选自网络) 一、什么是CGLIB? CGLIB是一个功能强大,高性能的代码生成包。它为没有实现接口的类提供代理,为JDK的动态代理提供了很好的补充。通常可以使用Java的动...博文来自:zghwaicsdn的专栏

  分页实现的效果:      /**/ 组图0-1.分页实现效果图一       /**/ 组图0-2.分页实现效果图二 一、从效果可以看出内容由两部分组成: 1.学生信息     数据库中插入一些记录...博文来自:niaonao

  在MATLAB中,可以注释一段程序。 使用“%{”和“%}”。 例如 %{ 。。。 %} 即可。 经典方法是用 if 0,但缺点是不够直观,注释掉的内容仍然保持代码的颜色。现在可以用 ...博文来自:知识小屋

本文链接:http://mzi-ads.com/boyishusousuo/262.html

相关推荐:

网友评论:

栏目分类

现金彩票 联系QQ:24498872301 邮箱:24498872301@qq.com

Copyright © 2002-2011 DEDECMS. 现金彩票 版权所有 Power by DedeCms

Top