Questions tagged «didactics»

特别适合计算机科学教育的教学工具和方法

13
如何愚弄“尝试一些测试用例”启发式算法:看起来正确但实际上不正确的算法
为了尝试测试某个问题的算法是否正确,通常的出发点是尝试在多个简单的测试案例上手动运行该算法-在一些示例问题实例(包括一些简单的“拐角案例”)上进行尝试”。这是一种很好的启发式方法:这是一种快速清除算法中许多错误尝试并了解为什么该算法无效的好方法。 但是,在学习算法时,有些学生很想停在这里:如果他们的算法在一些示例上都能正常工作,包括他们认为可以尝试的所有极端情况,那么他们得出的结论是算法必须正确。总是有一个学生问:“如果我可以在几个测试用例上尝试一下,为什么我需要证明我的算法正确?” 那么,如何欺骗“尝试一堆测试用例”启发式方法?我正在寻找一些很好的例子来表明这种启发式方法是不够的。换句话说,我正在寻找一个或多个算法的示例,这些示例从表面上看可能是正确的,并且在任何人都可能想出的所有小输入上输出正确答案,但是该算法实际上在哪里不起作用。也许该算法恰好在所有小输入上都能正常工作,仅对大输入失败,或者仅对具有异常模式的输入失败。 具体来说,我在寻找: 一种算法。该缺陷必须在算法级别上。我不是在寻找实现错误。(例如,该示例至少应与语言无关,并且该缺陷应与算法问题有关,而不是与软件工程或实现问题有关。) 有人可能会提出的一种算法。伪代码应该看起来至少看起来是正确的(例如,混淆或明显可疑的代码不是一个好例子)。如果这是某些学生在尝试解决作业或考试问题时真正想到的一种算法,则可加分。 通过概率较高的合理手动测试策略的算法。手动尝试一些小型测试用例的人应该不太可能发现该缺陷。例如,“手动模拟十二个小型测试用例的QuickCheck”应该不太可能揭示该算法不正确。 优选地,确定性算法。我已经看到许多学生认为“手动尝试一些测试用例”是检查确定性算法是否正确的合理方法,但是我怀疑大多数学生不会认为尝试几个测试用例是验证概率的好方法算法。对于概率算法,通常没有办法判断任何特定输出是否正确。而且您手头不足以对输出分布进行任何有用的统计检验。因此,我宁愿专注于确定性算法,因为它们更清楚地了解了学生的误解。 我想教导证明算法正确的重要性,并且希望使用一些这样的示例来帮助激发正确性的证明。我希望那些相对简单并且可以被大学生使用的例子;需要重型机械或大量数学/算法背景的示例不太有用。另外,我也不想使用“非自然”的算法;虽然构造一些怪异的人工算法来欺骗启发式方法可能很容易,但是如果看起来很不自然,或者构造了明显的后门只是为了欺骗这种启发式方法,那么它可能不会使学生信服。有什么好的例子吗?

5
学习用于同一目的的不同算法/数据结构的原因是什么?
自从我是一名本科生以来,我一直在想这个问题。这是一个普遍的问题,但我将在下面详细说明。 我见过很多算法-例如,对于最大流量问题,我知道大约3种算法可以解决该问题:福特-富克森(Ford-Fulkerson),埃德蒙兹-卡普(Edmonds-Karp)和狄尼克斯(Dinic),其中狄尼克斯具有最高的复杂性。 对于数据结构(例如堆),有二进制堆,二项式堆和Fibonacci堆,其中Fibonacci堆具有最佳的整体复杂性。 让我感到困惑的是:我们有什么理由需要全部了解它们吗?为什么不学习并熟悉最好的复杂性呢? 我知道这是最好的,如果我们都了解它们,我只是想知道是否有任何“更有效的”原因,例如某些问题/算法只能通过使用A而不是B来解决,等等。

2
关于“论真正教计算机科学的残酷”
迪克斯特拉(Dijkstra)在他的论文《关于真正教授计算科学的残酷性》中,提出了有关编程入门课程的以下建议: 一方面,我们教看起来像谓词演算的事物,但与哲学家却截然不同。为了训练新手程序员如何使用未解释的公式,我们将其更多地讲授布尔代数,使学生熟悉逻辑连接词的所有代数性质。为了进一步切断与直觉的联系,我们将布尔域的值{true,false}重命名为{black,white}。 另一方面,我们讲授一种简单,干净,命令式的编程语言,以跳过和多重赋值作为基本语句,具有局部变量的块结构,以分号作为语句组合的运算符,一种不错的替代构造,一种不错的方法。重复,以及(如果需要)过程调用。为此,我们添加了最少的数据类型,例如布尔值,整数,字符和字符串。至关重要的是,无论我们引入什么内容,相应的语义都是由附带的证明规则定义的。 从一开始,贯穿整个过程,我们强调程序员的任务不仅是编写程序,而且他的主要任务是提供形式证明,证明他提出的程序符合同样正式的功能规范。在设计证明和程序的同时,学生有充分的机会利用谓词演算来完善自己的操作敏捷性。最后,为了向人们传达这种入门编程课程主要是形式数学课程的信息,我们发现有问题的编程语言尚未在校园内实施,因此可以保护学生免受测试其程序的诱惑。 他强调这是一个认真的建议,并概述了各种可能的反对意见,包括他的想法“完全不现实”和“太难了”。 但事实证明,那只风筝不会放飞,因为事实证明是错误的:自80年代初以来,每年都有数百位大学新生成功地参加了这样的入门编程课程。[因为根据我的经验,说这一次是不够的,所以前一句话至少应再重复两次。] Dijkstra指的是哪门课程,并且还有其他文献可以讨论吗? 这篇论文发表于1988年,当时Dijkstra在德克萨斯大学奥斯汀分校的时候,这可能是一个线索-他们托管Dijkstra档案,但馆藏很大,我特别想听听其他人对这门课程的兴趣。 我不想在这里讨论Dijkstra的想法是好的还是现实的。我考虑过将此内容发布在cstheory.se或cs.se上,但因为在这里定居下来,是因为a)一个教育工作者社区可能更容易有人可以轻松回答,并且b)Dijkstra本人强调他的课程“主要是形式数学。” 如果您不同意,请随时举报迁移。

3
NP完整性教学-Turing减少vs Karp减少
我对如何最好地向计算机科学专业的学生教授NP完整性的问题感兴趣。特别是,我们应该使用Karp缩减还是Turing缩减来教授它? 我觉得NP完全性和约简的概念是每个计算机科学专业都应该学习的东西。但是,在教授NP完整性时,我注意到使用Karp约简法有一些缺点。 首先,对某些学生来说,减少Karp似乎不必要地令人困惑。减少的直观概念是“如果我有解决问题X的算法,那么我也可以使用它来解决问题Y”。这是非常直观的-但映射到Turing缩减比映射Karp缩减要好得多。结果,我看到试图证明NP完整性的学生因直觉而误入歧途,并形成了错误的证明。尝试教授这两种简化方法并强调Karp简化方法的这一方面有时会感觉有点像是不必要的形式主义,并且会占用不必要的课堂时间和学生的注意力,这似乎是无关紧要的技术细节;我们为什么要使用这种更严格的还原概念,这并不是不言而喻的。 我确实了解Karp缩减和Turing(Cook)缩减之间的区别,以及它们如何导致NP完整性的不同概念。我意识到,减少Karp可以使我们更好地区分复杂度等级之间的区别。因此,对于认真研究复杂性理论,减少Karp显然是正确的工具。但是对于仅学习此方法并且永远不会进入复杂性理论的计算机科学专业的学生来说,我不确定这种更好的区分是否对他们至关重要至关重要。 最后,作为一名学生,我记得遇到“重言式”之类的问题时感到困惑-例如,给定一个布尔公式,检查它是否是重言式。令人困惑的是,这个问题显然很难解决:任何多项式时间算法都意味着P=NPP=NPP=NP; 解决这个问题显然和解决重言式问题一样困难。但是,即使从直觉上讲重言式和可满足性一样难,重言式也不是NP难的。是的,我今天了解为什么会这样,但当时我记得对此感到困惑。(一旦我终于明白了,我的脑海便是:无论如何,我们为什么要区分NP-hard和co-NP-hard?这似乎是人为的,并且在实践中没有很好的动机。为什么我们专注于NP而不是从实际的角度来看,共NP硬度似乎与NP硬度在本质上具有相同的实际结果,所以为什么我们都对这种区别挂了钩?是的,我知道答案,但是作为一名学生,我记得这只是让这个科目变得更加神秘和缺乏动力。) 所以,我的问题是这个。当我们向学生教授NP完全性时,使用Karp归约法或Turing归约法更好吗?有没有人尝试使用图灵归约法来教授NP完全性的概念?如果是这样,情况如何?如果我们使用图灵归约法讲授概念,而跳过与Karp归约法相关的概念性问题,会有任何明显的陷阱或弊端吗? 相关:请参见此处和此处,其中提到我们在文献中使用Karp归约法的原因是因为它使我们能够区分NP硬度和共NP硬度。但是,似乎没有给出任何针对该能力是否对每个CS专业都应该学习的算法课程的学习目标至关重要的教学观点的答案。另请参见cstheory.SE上的此处,该讨论也有类似的讨论。

4
如何愚弄地块检验启发法?
在这里,戴夫·克拉克(Dave Clarke)提出,为了比较渐近增长,您应该画出手边的函数。作为理论上有偏见的计算机科学家,我称这个伏都教徒为阴谋,永远无法证明。再三考虑,我必须同意,这是一种非常有用的方法,有时甚至没有得到充分利用。情节是获得第一个想法的有效方法,有时这就是您所需要的。 在教授TCS时,总是有学生问:“如果我能做总是有效的X,我需要什么正式证明?” 由他的老师指出并说明谬论。有一组出色的示例示例,这些示例最终会在math.SE上进行故障转移,但这是相当数学的情况。 那么,您如何愚弄小区检验的启发式方法?在某些情况下,很难分辨出差异,例如 [ 来源 ] 进行猜测,然后检查实际功能的来源。但这并没有我所希望的那么壮观,特别是因为即使对于初学者,真正的关系也很容易从功能上发现。 是否存在(相对)渐近增长的示例,其中从函数定义中得出的真相并不明显,并且对较大图检验会给您一个完全错误的想法?都欢迎数学函数和实际数据集(例如,特定算法的运行时);不过,请不要使用分段定义的函数。nnn

3
用什么直观的方式来解释和理解德摩根定律?
戴摩根定律经常在计算机科学课程的入门数学中引入,我经常将其视为通过否定术语将陈述从AND变为OR的一种方式。 是否有更直观的解释说明为什么这样做有效,而不仅仅是记住真值表?对我来说,这就像使用黑魔法,有什么更好的方法来解释这一点,从而使数学上不太偏爱的人有意义?

4
Quicksort向孩子们解释
去年,我读了一篇有关“幼儿园量子力学”的精彩论文。这不是件容易的事。 现在,我想知道如何用最简单的词来解释quicksort。我如何证明(或至少是手波)平均复杂度为,对于幼儿园班级,最佳和最差情况是什么?还是至少在小学?Ø (ñ日志n )Ø(ñ日志⁡ñ)O(n \log n)

3
日常材料的逻辑门
逻辑门是一种抽象设备,可以用电磁继电器,真空管或晶体管来实现。这些实现已在计算中取得成功,部分原因是其可链接性,耐用性和大小超出了其基本的二进制稳定性,具有各种特性。它们也很好地工作,因为电力是能源,可以很容易地运送到周围。 我见过用木材,大理石和重力建造的加法器。我看过“芯片实验室”毛细管作用驱动的原型。我见过各种专业机械计算器(Curta,计算尺)。我已经将多米诺路径视为一次性逻辑门。 我对其他说明性的计算设备感兴趣,这些计算设备不一定方便,耐用或快速,但可以利用日常材料的属性进行计算并且可以直接看到。多米诺骨牌小径很近,但是有点太复杂以至于无法重置。 磁机械布置?管道/槽中有水?更一般的大理石装置? PS。这是一个新的。 机械CPU时钟

6
线性代数的哪些部分在计算机科学中使用?
我一直在阅读《线性代数及其应用》以帮助理解计算机科学材料(主要是机器学习),但我担心很多信息对CS毫无用处。例如,除非您尝试编写新的方程式求解器,否则了解如何有效地求解线性方程式系统似乎没有什么用。此外,这本书还讨论了跨度,线性相关性和独立性(矩阵有逆的时候)以及它们之间的关系,但是我想不出它在CS中的任何应用。那么,CS中使用线性代数的哪些部分?

6
在一个间隔中找到两个数字的最大异或:我们能做得比二次更好吗?
lllrrrmax(i⊕j)max(i⊕j)\max{(i\oplus j)}l≤i,j≤rl≤i,j≤rl\le i,\,j\le r 天真的算法只检查所有可能的对。例如在红宝石中,我们有: def max_xor(l, r) max = 0 (l..r).each do |i| (i..r).each do |j| if (i ^ j > max) max = i ^ j end end end max end 我感觉到,我们可以做得比二次。是否有针对此问题的更好算法?

1
使用实时编码的教学技巧
我参加了第一年的编程和算法课程。在最近的一次演讲中,我决定使用实时编码来介绍这些资料,这实际上意味着我坐在键盘后面,编写代码并使用emacs对其进行评估,以对其进行评估。 这是相当成功的,学生们评论了他们对这种(互动式)互动形式的欣赏程度。因为这是我第一次尝试使用这种教学格式,所以我知道它运行得并不完美。有些问题与对emacs的了解不尽如人意有关,而其他问题则与允许学生提出的问题使我离脚本太远了。我知道我可以做得更好。 使用现场编码讲座进行讲座(和其他演示)的一些准则是什么? 有哪些陷阱要避免?
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.