[英]Haskell and Genetic Algorithm solving Sudoku

遗传算法详解(GA)(个人觉得很形象,很适合初学者) 本文是去年课题组周报中的一个专题讲解,详细讲了GA,由于是周报,所以十分详细。文章综合参考了一些互联网资料。发博客以备忘! 阅读详情
#Genetic Algorithm in Haskell
#as sudoku solver
#Author:[CACppuccino](https://github.com/CACppuccino)
####The author always keeps the copyright of the article and the experiment data
####This report is part of my school assignment
In the GA part, I seperate the algorithm into 4 parts:Genetic,CrossOver,RNG and Mutation. Since the scale of the program is large, it is divided into four modules, for the convenience of debugging and logic constructing.  
Generally, GA is usually conducted as 4 steps: encode, crossover, select and mutation, I will explain my GA algorithm in this order as well.  
At the same time, all the experiment data results were stored in the **evolution.txt** under the project file.  
The workflow is as follows:
![](http://i.imgur.com/1Y9Uv84.jpg)
####Prepare-RNG
This part used to be the most difficult section to me, because haskell's purity makes it extremly difficult to generate a real random number, unless using IO function which will bring more difficulties and can't safisfy the demand of continually generates random numbers. Inspired by tutor **Matthew**, I tried to use one of the **pseudorandom** theory:**Linear congruential generator**. The formula is simple and consumes **little memory** to retain the state, it basically suits the need for the GA, but need designers treating the paremeters carefully.


NewSeed = (A*Seed+B) mod M
*:M = range of the random numbers


Adjustment still need to be done to these parameters since it affects the **distribution** of the numbers in the particular range. I pick A=171 and B=71 in all my random number generators(RNG) randomly, since I will adjust A and B to optimise the performance of RNG. By using the **MATLAB**, I found the number distribution is as follows (1000 times result, initial seed is 5):
![](http://i.imgur.com/6WQLxuU.jpg)  
This indicates that **LCG** doesn't actually cover all the numbers, but only part of them. I tried A=99 as well and receive a worse result, so parameters affects the result strongly.   
This also means that GA's performance is not only affected by the design of the program (like most traditional algorithms), but also heavilly depend on the parameter set in the program. 
![](http://i.imgur.com/aaLNZyq.jpg) 


####Encode
In order to adjust the Sudoku, I have to transfer the solution into a stream of numbers, so that the solution can act like genes and make the transformation by doing crossover and mutation, speak in another way, it is easier to operate.Espicially the phenomenon exists on most of creatures, so the combination of crossover, mutation and selection can lead the gene to a better state is undoubtful. Thus, the simulation about the gene leads solution to a better state, but detail reasons may still need to be explained in biologic way.  


Inspired by ideas on the internet (mainly from blogs, wikipedia and piazza), I decide to design my encoding part as follows:


type Gene = [Maybe Int]
type Chr = [Gene]


A example of Chr:


[[Just 1,Just 2,Just 4],[Just 5,Just 3,Just 6],[Just 9,Just 7].....]

In each **Gene**, the numbers are the candidates in each row that haven't been put into the whole solution.This makes the whole solution generated and limited in rows, all the crossover and mutation actions will only allowed to do in the particular row but not in the whole Chr. This ensures the **security** of the answers won't lost during any changes happened in Chr and optimise the **efficiency**. 
####CrossOver
CrossOver is resonable simple when the encode type is a **Chr**, because all I need to do is switch the two **gene** in mom and dad then produce to new children. But in this part, I choose to do two kinds of crossover: one is generally switch **gene**, another is switch part of the parent's **gene**. These two functions lead to different results and stand different meaning at here.  
The first one, I see that as more **a spread of the mutation**, in other words, trying to get a better solution by doing the different combination.  

mom:[[Just 1,Just 2,Just 4],[Just 5,Just 3,Just 6]......]
dad:[[Just 1,Just 4,Just 2],[Just 6,Just 5,Just 3]......]
child1:[[Just 1,Just 2,Just 4],[Just 6,Just 5,Just 3]......]
child2:[[Just 1,Just 4,Just 2],[Just 5,Just 3,Just 6].......]
The second one, is seen as **another way of mutation**, it produces new possible anwsers in blocks. Since it is more a mutation, I consider to set a very low possibility on this function to be called or cancel this function after debugging.


swap Gene2 part(Just 5 and Just 3)
mom:[[Just 1,Just 2,Just 4],[Just 5,Just 3,Just 6,Just 4,Just 7]......]
dad:[[Just 1,Just 4,Just 2],[Just 6,Just 5,Just 3,Just 7,Just 4]......]
child1:[[Just 1,Just 2,Just 4],[Just 6,Just 5,Just 6,Just 4,Just 7]......]
child2:[[Just 1,Just 4,Just 2],[Just 5,Just 3,Just 3,Just 7,Just 4]......]
Adjust children to no-repeat Gene:
child1:[[Just 1,Just 2,Just 4],[Just 6,Just 5,Just 3,Just 4,Just 7]......]
child2:[[Just 1,Just 4,Just 2],[Just 5,Just 3,Just 6,Just 7,Just 4]......]
In the first design of this GA, I forgot to do the adjustment and produced tons of bugs here. After I found that this **crossover** does the same with the **mutation** but much slower than mutation function when conducted as programs, I shutdown this function in the second design(the function is not called in actual running).  
But from genetic view, both ways of the crossover exists in the real world, so from some perspectives it is still a resonable crossover method, though should be treated cautiously in the algorithm. 
####Mutation
In the mutation part, I **swap a pair of numbers** in a random block in order to achieve the result of 'mutation'.


e.g.
father:[[Just 1,Just 2,Just 4]......]
child:[[Just 1,Just 4,Just 2].......]
In the current design, the function is forced to mutate in one random Chr's gene. There is no much problems when the population is large enough, but the frequency of the mutation may increase rapidly after several evolution.  
At this stage, the population is set as 700, number for drop members is 10, assume in each gene there are 5 elements. Thus, mutation rate (genetic level) in each generation is as follows:  
*:To make the trend clearer,I made the function become continous instead of being discrete.


![](http://i.imgur.com/tsJNTuG.jpg)


####Selection
From the materials I get from the Internet, I found that the selection method plays an important role on whether the whole algorithm will achieve a local maximum or global maximum. A good selection should keeps most of the good candidates but not greedily pick the current best answers since it will reaches to the local maximum rapidly.  
In the first design, the goal is only 'GA can be run as a Haskell program', so I simply choose **Roulette Wheel Selection(RWS)** as my selection strategy, though the only reason choosing this is that this method is easy to conduct.  
This algorithm is described as randomly choosing the candidates by the candidates' accumlated possibility. In the selection part, I modify a litte bit, by doing the **inverse** of each candidate's possibility and **drop** the selected Chr. In this way, the efficiency may be optimised somehow.  

--slect by using Roulette Wheel Selection
--count means the adjustable parameter for number of delated elements
sByRWS :: Int-> Double -> [(Chr,Double)] -> ([(Chr,Double)],Double)
sByRWS 0 seed lis = (lis,seed)
sByRWS count seed lis = sByRWS (count-1) nseed res
  where
     (res,nseed) =  rws seed (sortBy sortByW lis)


####GA performance analysis
After a series of tests and looking up support materials, I found that there were multiple reasons that may lead GA having a slow speed or couldn't reach the global solution(the reasons are explained from biology and computer science perpective):  
1. The **potential good genes** are dropped in the early stage before spread by the crossover  
2. The **potential good genes** are lost or broken by the crossOver
3. The **elite genes** are dropped during the selection in a extremely low possibility
4. The **Mutation rate** is too low that can't bring enough **potential genes** to select in the evolution
5. The **Mutation rate** is too high that erase the **exist advance genes**


####Population
In the first version without the 'elite preservation' strategy, I have tested the population with 1,000 2,000 5,000 and 10,000.
The start weight is 9, drop number in each iteration is 10,but different population leads to total different evolution speed and performance:  
Among these tests, **4 tests get the 12** (of full score 27) as the maximum score, only the 1000 population got 11.  
Talking about the **speed** reaching to the maximum, 10,000=2,000=1,000>700>5,000, the first three reaches the maximum at their third generation.  
Then, stability should also be seen as an important creterion measruing the quilty of the parameters. It's easy to see that the #10,000 group got a high stability which maintains the maximum for 80+ iterations while the #700 group dropped quikly with only 1 iteration maintainance and never came to the maximum again. This indicates that #700 group was more a coinstance reaching a higher maximum than #1000 group.
In conclusion, a larger population may have more potential generate a better gene and seperates in the future.
####Selection Number (Drop number)
In the first version without the 'elite preservation' strategy, I also tested the iteration with 100,50 and 10.
All of their maximum weight point is 12, but the #10 group had a high stability by keeping the maximum weight for 7 iteration while other group only had one and appears much later than the #10 group.
In conclusion, I think smaller selection number ensures the **'potential excellent gene'** can be spread by the crossover. Thus, the stability increases as the selection number is decreasing.
####Elite Preservation
From the materials, I found that simple selection may lead GA trapped in the local maximum. To solve this problem, an usual solution is taken as 'elite preservation', which preserves the best Chr (or several high rank Chrs) in each iteration.  
In the second version, I put this strategy in the **selection** part, avoid the possibility of **elites being drop out**. Then I got a significant improve:  
The maximum of the goup (population 2,000 and drop number 10) with 1 and 5 members preservation got 13 and 14 as their maximum number respectively. 
####Parameter Selection and Improvement
In GA, there are several adjustable parameters that can strongly affect the performance of the algorithm:  
1.population  
2.the number of candidates dropt in each iteration  
3.the number of genes that mutate in each iteration  
4.the multiplier and increment in the RNG
5.a smaller iteration
6.a higher mutation rate
####GA optimisation and further improvement  
After the second version of GA, I tried to increase the rate of the mutation to generate more **potential advance genes** for the group in the third version. It was under the condition of:  

population:2000
RNG:*171 +71 
drop number:10
elite preservation:10
In this case, the maximum weight in the evaluation **increases** to 16 from 14 when the mutation rate(number of Chrs doing the mutation in each iteration) is improved from 1 to 5. But the maximum **decreases** to 14 when the rate is adjusted to 8, which is **close to the drop number**. Thus, I suspect that the mutation rate is a good method to bring **new advance genes** into the group, but need a larger population to tolerant the mutation so that the mutation's **damage** to **exist advance genes** can be limited.  
So I expanded the population and reduced the elite preservation, the parameters became as follows:  

population:5000
RNG:*171 +71 
drop number:10
elite preservation:5
As the result, GA got 16 as maximum but had a higher or stable distribution on high weights, which indicates that larger population made the group have higher opportunity to spread the **advance genes** by cross over. Then I slightly modify the parameters by increas the elite preservation but decrese the mutation rate:

population:5000
RNG:*171 +71 
drop number:10
elite preservation:5
Though the maximum still remains to be 16, the **quilty** of the evolution became much better since it had more high weight among best Chrs.


Then I tried to boost the mutation rate by incresing it to 30 and 100 respectively, but the maximum **stuck** at 16 and didn't increase any more, which indicated that there is a local maximum trap and that I couldn't solve unless I try to other ways bringing **fresh genes** to the group.


After that, I activated the second crossover method I mentioned above, trying to bring new genes to the group. However, this only makes the performance of the alogrithm worse, by unkown reasons. The maximum only reached 14 and the whole quilty of the group is obviously lower than others.


At last, I also attempt to use the concept of **'disaster'**, dropping 10 'advance genes' at the middle stage in order to get rid of the local optima.


population:5000
RNG:*171 +71 
drop number:10
elite preservation:5
The test is under the condition above, and was found that the maximum hadn't been reached again, since might be the reason that **all the advance genes were totally erased**, or **mutation was not powerful enough to bring enough good genes to the group to digest and spread**.  
So I increse the mutation rate to 50, which brought the group a strong ability of **recover**. But at the same time, extremly high mutation rate erased the **potential advance gene** in the early stage, so the maximum didn't reach to 16 before the 'disaster'.  
![](http://i.imgur.com/GJb7Xo0.jpg)
Thus, I lowered down the mutation rate again but **put foward the 'disaster'** to remain more time for the 'recover' section. The result still didn't breakthrough the local optima, I doubt that it may need **more population** to suffer the disaster. All the results ditribution could be seen in the distribution graph, d-1, d-2 and d-3 represent 3 different strategies I tried above.  


![](http://i.imgur.com/Q8sKlgH.jpg)
**All in all, I believe there should be a mathmatic way optimising GA by evalutaing GA in some functions like the cost function for many machine learning algorithms. I had'n found a mathmatic method so far, so the adjusting time could be long.**
#####Parallel
The property of the cross over section makes it easy to be designed as parallel computing/programming. GA can be optimised by this significantlly espicially when the population is large.
#####Other RNG algorithms
**LCG** is simple and fast in generating random numbers, but the shortage is as mentioned above-less randomness and bad distribution. 
####Debug & Design Reflection
#####Modularisation
When first designing the GA, I haven't consider much engineering strategies into this design. But gradually it was found that the algorithm could be more complex and larger than expected, so I seperate the algorithm into four modules, which  
1.Make it more **readable**  
2.**Safer** by using the interface




-----
###Reference
[1] [A method taking GA to solve Sudoku](http://www.voidcn.com/blog/suolong123/article/p-1293961.html)  
[2] [General introduction to Genetic Algorithm](https://en.wikipedia.org/wiki/Genetic_algorithm)  
[3] [Pseudorandomness in Wikipedia](https://en.wikipedia.org/wiki/Pseudorandomness)   
[4] [Elite preservation](http://www.cnhup.com/index.php/archives/elitist-preservation-in-genetic-algorithm/)  
[5] [Genetic Algorithm Background Information](https://segmentfault.com/a/1190000004155021)
5个4000比特大状态置换算法的设计与分析 下面是 5 个概念性、实验性的 4000 位可逆置换设计。它们都保证是双射,但未经过密码分析,不可直接用于生产系统。风格分别覆盖:三维 SPN、Feistel、可逆元胞自动机、ARX、宽轨迹/Keccak 式结构。 这 5 个设计分别代表了 SPN、Feistel、元胞自动机、ARX、宽轨迹 Keccak 五种不同风格,覆盖了主流大状态置换的构造思路。再次强调:它们只是实验性概念,若要用于实际协议,必须经过严格安全性分析。 阅读详情

相关推荐

sudoku.hs:Haskell中的数独解算器

数独 用Haskell编写的数独游戏! 截屏 关于 这是一个简单的数独游戏,使用haskell-gi库使用gtk3构建。 Sudokhs不需要任何互联网连接,并且具有生成,验证和解决数独表的功能。 建筑 cabal build 正在安装 cabal install 为Arch和Debian发行版提供了附加的二进制(x86_64)软件包。您可以从页面下载适当的软件包。 拱门: pacman -U sudokuhs-1-1-x86_64.pkg.tar.xz Debian: dpkg -i sudokuhs_0.1-0.deb MacOS:需要 : brew install gtk+3 fontconfig >双击.dmg(从发行页面下载)。 控制项 (✓)-突出显示相对于选定单元格的所有冲突 [x)-清除选定的单元格 (?)-如果可能,求解选定的单元格* 新游戏-以选定的难度级别开始

闲人真多啊:Sudoku(数独?)的XQuery解决方案

 从Haskell作者的blog看来的。如果觉得不够变态的话,可以欣赏一下XQuery后面XSLT写的程序。XQuery的程序:declare namespace fn = "sudoku";declare variable  $board as xs:integer+ := (1,0,0,  3,0,0,  6,0,0,0,2,0,  5,0,0,  0,0,4,0,0,9,  0,0,

负暄琐话 2734

解放双手:用KUKA示教器白键一键触发复杂工艺,自定义你的快捷指令

本文详细介绍了如何利用KUKA示教器的工艺白键功能,通过自定义快捷指令一键触发复杂工艺,显著提升自动化产线效率。文章涵盖UserTech技术栈解析、KRL脚本封装、人机交互视觉工程及工业实战策略,帮助工程师实现机械臂操作的高阶优化。

weixin_30379531的博客 432

《Haskell并行与并发编程》——第2章,第2.3节示例:并行化数独解算器

本节书摘来自异步社区《Haskell并行与并发编程》一书中的第2章,第2.3节示例:并行化数独解算器,作者【英】Simon Marlow,更多章节内容可以访问云栖社区“异步社区”公众号查看 2.3 示例:并行化数独解算器Haskell并行与并发编程本节将分析一个实例,考察如何并行化一个程序,使之对多组输入数据执行相同的计算。该计算实现了数独求解的功能。解...

weixin_33948416的博客 427

五、e2studio VS STM32CubeIDE之汉化

介绍stm32cubeide汉化方案和汉化包e2studio自带汉化包,在安装过程中可选择安装e2studio STM32CubeIDE切换中英文。

cl234583745的博客 1766

手把手教你逆向分析某里系bx-ua参数(以225版本为例)

本文详细解析了某里系应用bx-ua参数的逆向工程实战方法,重点拆解其三层加密体系(二进制加密、字符替换和Base64编码)。通过工具链配置和实战案例,帮助开发者掌握逆向分析技巧,适用于合法合规的安全研究和加密技术评估场景。

weixin_33220360的博客 412

尝试haskell

<br /><br />尝试用haskell编写一个SQL解释器,做了一个初步的后端<br /> <br />代码:moduleFunswhereimportData.ListimportMonadimportSystem.DirectoryimportSystem.FilePathimportSystem.IOimportText.Regex.PCREdataStore t p =Text p |Csv p |Bin p

追寻真理之美 2271

从零开始:PLUMED与GROMACS整合安装全攻略

本文详细介绍了如何从零开始整合安装PLUMED与GROMACS,包括系统环境检查、MPI配置、PLUMED编译安装、GROMACS补丁应用及常见问题解决方案。通过本教程,研究人员可以快速完成分子动力学模拟工具的整合安装,实现增强采样和自由能计算功能。

weixin_42520796的博客 292

haskell(26)

22、Data.Char Data.Char模块中含有一系列用于对字符进行判断的函数,函数的类型全部声明为Char -> Bool。 isControl 判断一个字符是否是控制字符.  isSpace 判断一个字符是否是空格字符, 包括空格, tab, 换行符等. isLower 判断一个字符是否为小写. isUper 判断一个字符是否为大写.  isAlpha 判断一个字符是否为字母

麦好的AI乐园 1742

Unity Android构建报错:compileSdk 35兼容性五层定位法

Android构建中的compileSdk是编译时API目标版本,其升级并非孤立操作,而是触发JDK、Android Gradle Plugin(AGP)、NDK、targetSdk与Unity引擎版本之间强耦合校验的起点。当出现'using a newer Android Gradle plugin to use compileSdk = 35'类报错,本质是代际技术栈错配——例如AGP 7.1.3不识别compileSdk 35所需Java 17语法,或NDK 21与AGP 7.4的ABI规范冲突。该问

weixin_32496547的博客 568

银河麒麟桌面系统批量交付:封装自动化ISO镜像,百台装机效率提升10倍

麒麟桌面系统自动化ISO镜像定制摘要 本文详细介绍麒麟桌面版ISO安装镜像的定制方法,通过修改系统文件实现自动化安装部署。主要内容包括:1) 挂载原版ISO并提取文件;2) 使用unsquashfs解压系统文件进行定制化修改,包括添加系统标记配置;3) 配置ky-installer.cfg自动应答文件,设置安装参数如用户名、密码、分区方案等;4) 修改grub引导配置启用自动安装模式。该流程支持磁盘加密、自定义分区、自动登录等功能,生成的定制镜像可满足批量部署需求,显著提升系统安装效率。

信创运维工程师 · 银河麒麟 & 容器实战 | 金融生产环境迁移·等保加固 | 142篇原创·17万+阅读 1507

视频隐私脱敏工程化:CSRT/KCF追踪算法在本地推理中的实现与边界

在短视频内容合规审查中,动态遮挡(Dynamic Masking)是高频且高耗时的环节。传统手动关键帧打码不仅效率低下,且在目标快速移动或遮挡时极易出现遮罩漂移。本文从计算机视觉工程角度,解析基于CSRT与KCF算法的目标追踪方案在视频隐私处理中的技术路径、性能权衡及落地实践。

Mysssone的博客 210

基于YOLO26/11/v8算法的Web目标检测系统,人脸表情识别系统,Django+Vue3 的前后端分离,实现摄像头实时识别,YOLO26/YOLO11/v8 + LLM大模型智能分析,科研必备

在人工智能迈向通用化(AGI)的今天,“视觉感知 + 语言理解”的多模态联合是未来的趋势。单纯的检测画框已经无法满足复杂的业务需求,如何让系统“看懂”画面并进行“思考”,是当前视觉项目的重点。我们知道目标检测是计算机视觉中的重要任务,广泛应用于安防监控、自动驾驶、智能家居等领域。因此本项目将 YOLO 目标检测模型(兼容 YOLO26/v11/v8 系列)与 DeepSeek 等顶流大语言模型(LLM) 进行联合,使用 Django (后端) + Vue3 (前端) 技术栈

在职AI算法工程师,擅长计算机视觉,YOLO目标检测、分割等,擅长web、pyqt界面可视化,好内容持续更新中,来这里跟大家一起学习,共同进步 2839

【算法拾光】链表 哈希表|K个一组翻转链表 + 两数之和

K个一组翻转链表需分段反转,借助哑节点与前驱指针维护连接,避免断链;两数之和利用哈希表实现O(1)查找,空间换时间,高效定位目标组合。前者考察链表指针操作,后者聚焦映射关系构建,均为面试高频题。

wuqingyigexiaoba的博客 313

基于matlab的图像HOG特征提取算法仿真

方向梯度直方图(Histogram of Oriented Gradient, HOG)特征是一种在计算机视觉和图像处理中用来进行物体检测的特征描述子。它通过计算和统计图像局部区域的梯度方向直方图来构成特征。Hog特征结合SVM分类器已经被广泛应用于图像识别中,尤其在行人检测中获得了极大的成功。需要提醒的是,HOG+SVM进行行人检测的方法是法国研究人员Dalal在2005的CVPR上提出的,而如今虽然有很多行人检测算法不断提出,但基本都是以HOG+SVM的思路为主。

平时工作较为繁忙,私信消息一般晚上回复,谢谢大家~~ 730

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

排序算法深度笔记(下):非比较类排序的线性突破与工程边界

排序算法时间复杂度额外空间复杂度稳定性是否基于比较选择排序O(N^2)(O(1))不稳定是冒泡排序O(N^2)(O(1))稳定是插入排序O(N^2)(O(1))稳定是归并排序O(N\log N)(O(N))稳定是快速排序O(N\log N)O(log N)不稳定是堆排序O(N\log N)O(1)不稳定是计数排序(O(N + M))O(M))稳定否基数排序O(N)稳定否桶排序平均O(N) / 最坏O(N^2)

2401_87069538的博客 571

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

算法日常・每日刷题--<动态规划>42

本题为“不相交的线”,与最长公共子序列问题相似。使用动态规划求解:定义 dp[i][j] 表示 nums1[0:i] 与 nums2[0:j] 的最大不相交连线数。若元素相等,则继承左上值加1;否则取上方或左方最大值。最终返回 dp[m][n],即两数组的最大不相交连线数。时间复杂度 O(mn),空间复杂度 O(mn)。

2503_92261635的博客 20

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

C语言程序设计题|有序数组插入数字冒泡排序

题目要求将一个数插入有序数组末尾,并用冒泡排序实现整体升序。代码先将输入数存入数组最后位置,再通过双重循环进行冒泡排序,每轮将较大元素向后移动,最终输出11个升序元素。该方法虽时间复杂度为O(n²),但符合题目要求,逻辑清晰,适合初学者理解排序原理。

2301_81429079的博客 749

【算法拾光】模拟|外观数列 + 数青蛙

本文总结两道模拟题解法:外观数列通过迭代统计连续数字个数生成下一项,关键在于处理末尾字符;数青蛙则模拟青蛙叫声“croak”状态转移,维护各阶段青蛙数量,记录最大并发数并确保全部完成。共性在于严格遵循流程、细致处理边界与非法情况,锻炼字符串遍历与状态管理能力。

wuqingyigexiaoba的博客 369

牛客周赛165C题(前后缀性质,递推,排序,枚举)

题目大意:给定长度为 `n` 的数组,选择 `k ∈ [1,n]`,将前 `k` 个元素整体翻转,后面的元素不变。要求操作后的整个数组非递减,统计满足条件的 `k` 的数量。题目链接:https://ac.nowcoder.com/acm/contest/141721/C。时间复杂度:O(nlogn)

2501_94316951的博客 170

408 算法 04|主元素与三元组最小距离:两种“扫描时做决定“的思路

2013(41) 的主元素用摩尔投票一遍选出候选,但真正的考点是"选完必须验票";2020(41) 的三元组最小距离,三指针每次只挪最小的那个,靠的是 D=2×(max−min) 这个恒等式。两套完整 C 代码加真实输出,附官方评分档位表。

m0_56226131的博客 406

【数据结构-3】算法美学之降复杂度

在while循环的循环体内,首先用临时变量保存最后一个位置的数据,再通过for循环把所有元素往后移动一位,最后把tmp中保存的值放到下标为0的位置上去。方法二的思路是:创建新数组,让原数组中后k个数据移动到新数组中前面的位置,让原数组中前numsSize-k个数据移动到新数组中后面的位置,这。这段代码的思路是:三次逆置,第一次逆置前numsSize-k个数据,第二次逆置后k个数据,最后整体逆置。这篇博文分享一道解法不一的算法题,求解过程的目的在于降低算法的时间复杂度,题源力扣。,属于空间换时间的操作。

weixin_44218929的博客 83

算法61,判定是否为字符重排

两字符串能互为重排 ⇔。

sheshibenniaodan的博客 218

算法日常・每日刷题--<动态规划>32

给定严格递增的正整数数组,求最长斐波那契子序列长度。使用二维DP,dp[i][j]表示以arr[i]、arr[j]为最后两项的序列长度,初始化均为2。通过哈希表快速查找前一项target = arr[j] - arr[i],若存在且下标小于i,则状态转移:dp[i][j] = dp[k][i] + 1。遍历更新全局最大长度,最终若结果小于3则返回0。时间复杂度O(n²),空间复杂度O(n²)。

2503_92261635的博客 178

算法札记:几何分布在算法题UVA1262的运用

集卡问题求解核心:将集齐n种优惠券的过程分为n个阶段,每个阶段期望购买次数为 $ \frac{n}{k} $(k为剩余种类数),总期望为 $ n \cdot H_n $(调和数)。通过自洽方程推导单阶段期望,无需几何分布或无穷级数,逻辑清晰且适用于大一水平。例如,n=5时期望约11.42,非5。题目要求以带分数形式输出精确结果,算法上需累加分数并化简。

Keven_11的博客 350

SSL证书选RSA还是ECDSA:公钥算法、CA签名与兼容性怎么核对

申请SSL证书时,RSA和ECDSA该怎么选?先分清站点公钥算法、CA签名算法和TLS实际兼容性,再用隔离OpenSSL实验读取两类材料,核对申请、续期和部署交接,避免只看Signature Algorithm就选错。

谁呀!的博客 399
上一篇: 机器学习历史简介
下一篇: [译]机器学习简史
LordCup
博客等级 码龄10年 1粉丝 2原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值