楽しいパズル臨時。トップパズルのソリューションは非常に平易かつ入手しやすいことができない、我々はフラッシュを見つける必要があります。パズル解決アルゴリズムを指すが、パズルのためのアルゴリズムであり、ステップは自動的に機械の解決を行ってもよいです。アルゴリズムでは英語ができたり、他の自然言語で記述することが、より正確に言えば、彼らは擬似コードで記述される傾向にあります。それは、コンピュータ上で実行するのに十分な程度に洗練されていない、とのプログラミング言語で書かれたコードが同じではありませんので、それは「擬似」と呼ばれています。
今日の世界でキャリアとしてコンピュータプログラミングでより多くの人々があります。プログラミングを学ぶためには、まず、このような代入文と制御周期などの基本的なプログラミング構造の簡単な例を学ばなければならない、とプログラミング演習は、多くの場合、擬似コードアルゴリズムが学習されているプログラミング言語で書かれたコードを変換伴います。また、分析のスキルが必要なパズルを解決するために、プログラマの恩恵を受けて。それは仕様のプログラミング構造、またはあなたのコードの初期位置決め誤差に変換されているかどうか(つまり、デバッグプロセスである)、これらの分析能力が不可欠です。
パズル(パズル)は、それが説明と説得力が容易であるという利点を有し、ベストプラクティスの一種です。後者は現在、特に重要です。アルゴリズムの本ことをお勧め今日見てみましょう。
Pythonでパズルの解法アルゴリズム:楽しいプログラミング
プログラミングは強い関心に退屈な学習プロセスで面白いパズルリーダープログラミングを解くことによって教え革新的な本は、パズルは、現実の世界から面白いと説明するのは容易に適用されます。
プログラミングはパズルの開始の溶液から学んでいる1つまたは2つの試みのパズルを失敗した後、読者が突然光を見ることができます - しかし、検索戦略、データ構造や数式、アルゴリズムジャンプのパズルであってもよいし、物事の残りを達成することができるコードに「翻訳」アルゴリズムのPythonの構文とセマンティクスを使用することです。
読者はあなたが本を読むことができ、基本的なプログラミングの概念を習得する必要があります。本書は、このようなマルチ女王、ハノイの塔などのパズルはよく知られており、広く流通その多くは21のパズル、数独は、ように、数秒以内に問題を解決する6次の隔たりとが含まれています。それぞれのパズルは、プログラミング演習の難易度の異なる装備されている背景には、読者は自分のコーディングに完了し、その後、探求し、改善するための本の中で与えられた答えを制御することができます。
何本のトップアルゴリズムのパズルです。
- 一貫性のある1つのパズル
- 2のパーティをパズルのベストタイム
- パズル3は、心を読むために(少しキャリブレーションを必要とします)があります
- 女王で4つのパズルは別々にしておきます
- クリスタルパズル5が壊れてください。
- 偽札を見つける6つのパズル
- パズルの平方根に7のジャンプ
- 夕食を食べていないパズル8つのゲス
- アメリカのGot Talentパズル9
- 10女王以上のパズル
- 舗装された中庭のパズル11を喜ば
- ハノイのパズルの12タワー
- 13のパズル無秩序な職人
- 14は、もはや数独のパズルを果たしていません
- 14は、もはや数独のパズルを果たしていません
- 15の統計は、パズルの組み合わせを変更します
- 16のパズルの貪欲は良いです
- 17文字パズルクレイジー
- 18のパズルは、メモリをフルに活用します
- 覚えておくべき19のパズルの週末
- 20のパズル6次の隔たり
- 21のパズル発行価格があります。
保護観察のサンプル章:パズル9アメリカのタレントショー
このパズルのパラダイムでカバー構造とアルゴリズムのプログラミング:リストを二次元状こと。
あなたは、テレビ番組「ゴット・タレントだ」というファイルを開催することを決定した[1]
春休みの後そこに多くの選手がサインアップしている、とあなたはラジオ番組のオーディションを開催します。各プレイヤーは(などフラワーアレンジメント、ダンス、スケートボード、など)、独自のユニークなスキルを持っており、あなたは海で彼らのパフォーマンスをテスト選択します。ほとんどのプレイヤーは、パフォーマンスとあなたが満足しないでください、しかし、いくつかの選手が行うことができます。今、あなたは選手のグループを持って、彼らは一人一人はあなたに、少なくとももう1つのトリックを表示します。
あなたのプログラムでは、ユニークなスキルの多種多様のパフォーマンスを強調したいです。週はフラワーアレンジメントショーの様々な場合には評価のすべてが有用ではありません。あなたは彼らのユニークなスキルのリストを整理、選手のリストを思い付きます。その後、プロデューサーに行くので、彼はプログラムでこれらのユニークなスキルをカバーすることに合意しました。あなたのプロデューサーは、最終的なリストを選択するように引き渡さ、(例えば、彼らは観客がプログラムを繰り返すために好きではないと思います)このリストを削減します。彼らはまた、コストをコントロールしたいことを伝えます。
あなたは、コストをコントロールする選手の評価を改善するための最善の方法は、プログラムのように多くの種類を提供しながら、できるだけ少ないに連絡することで理解しています。だから、最終リストのプレイヤーの最小値を選択したいが、彼らはユニークなスキルのすべてを実行することができます。
あなたが最終的にユニークなスキルと表9-1の選手に示す選出されたと仮定します。
表9-1
上記の例では、すべてのユニークなスキルをカバーするために、アリー、ボブ、ドンとイブを選択することができます。アリーは柔術になり、コード、ボブは踊ると魔法、ドンは、イヴダンス、アクションやコードを踊ると歌います。彼らはユニークなスキルの6種類の合計を持っています。
あなたは人々のユニークなスキルのすべてがそうカバーするためにできるだけ使用することができますか?テーブルにはユニークなスキル(列)の全てをカバーできるように、より一般的には、どのように、最も少ない選手(ライン)を選ぶのですか?別の例は、表9-2に示されています。
表9-2
私たちの最初の例では、あなたが選択した選手の数は、以下の4かもしれません。あなただけアリー、カルとイブが可能雇う必要があります。アリーは、柔術やコード、カルの歌とマジック、イブダンス、運動およびコードされます。彼らはユニークなスキルの6種類の合計を持っています。
我们会使用晚餐邀请谜题(谜题8)中同样的策略。这两个问题很相似,不过在晚餐邀请谜题里,我们想邀请最多数量的人,而在这里我们想选择最少数量的人。而它们的共性在于,我们需要检查所有可能的组合(如选手的子集),排除不能覆盖所有绝活的子集,然后选择最小的子集。它们的另一个共性是贪心策略不可用。
两道谜题使用的数据结构是不同的,这里我们需要一张表示选手与绝活之间关系的表格,而非一张不喜欢的关系图。我们的例子可以转化为类似这样的数据结构:
Talents = ['Sing', 'Dance', 'Magic', 'Act', 'Flex', 'Code']
Candidates = ['Aly', 'Bob', 'Cal', 'Don', 'Eve', 'Fay']
CandidateTalents = [['Flex', 'Code'], ['Dance', 'Magic'],
['Sing', 'Magic'], ['Sing', 'Dance'],
['Dance', 'Act', 'Code'], ['Act', 'Code']]
我们有一个绝活列表(表格的列)和一个选手列表(表格的行)。我们需要一个列表的列表CandidateTalents
,用于表示表格中的条目。CandidateTalents
中的条目对应表格的行,而条目的顺序很重要,因为它对应选手在列表Candidates
中的顺序。Bob是Candidates
中的第二位选手,他的绝活对应CandidateTalents
中的第二个列表,也就是['Dance', 'Magic']
。
你可能会猜,两道谜题的代码会非常相似。我们会基于优化版的谜题8,为这道谜题稍微不同地组织代码。
9.1 每次生成并测试一个组合
这是顶层过程的代码,会每次生成一个组合,检查是否正确,取最小数量的正确组合。
1. def Hire4Show(candList, candTalents, talentList):
2. n =len(candList)
3. hire = candList[:]
4. for i inrange(2**n):
5. Combination = []
6. num = i
7. for jinrange(n):
8. if (num % 2 == 1):
9. Combination = [candList[n-1-j]] + Combination
10. num = num // 2
11. ifGood(Combination, candList, candTalents, talentList):
12. iflen(hire) > len(Combination):
13. hire = Combination
14. print('Optimum Solution:', hire)
第4~10行生成值num = i
对应的组合。第11行调用函数Good
——这会在后面详述——用于检查给定的选手组合是否覆盖所有绝活。如果是,则与当前已知最优的选手组合比较,如果选手人数少于最优组合,则更新最优组合(第12~13行)。
第3行与谜题8的对应行的invite = []
不同。在谜题8中,我们希望最大化能邀请的客人数量,因此将一个空列表作为最初的最优组合。在这里,我们想最小化聘请的选手数量,因此将完整的选手列表作为最初的最优组合。我们假定完整的选手组合能够满足覆盖所有绝活的要求。如果不能满足,可以重新考量绝活的列表。
9.2 确定缺少一门绝活的组合
我们调用函数Hire4Show
来确定一个给定的选手组合是否包含所有绝活。我们要做的这项检查与谜题8有很大不同,这一点会在下面展示。
1. def Good(Comb, candList, candTalents, AllTalents):
2. for tal in AllTalents:
3. cover = False
4. for cand inComb:
5. candTal = candTalents[candList.index(cand)]
6. if tal in candTal:
7. cover = True
8. ifnot cover:
9. returnFalse
10. returnTrue
for
循环(第2~9行)对绝活列表遍历每项绝活tal
。对组合中的每位选手(第4行开始的内层for
循环),我们使用选手在选手列表candList
中的索引,作为“选手-绝活”数据结构的索引(第5行)。
我们现在需要在for
循环的迭代中(第2行开始)检查选手的绝活中是否覆盖绝活tal
,这项检查在第6行完成。如果选手拥有绝活tal
,我们在第7行做标记。不过,如果遍历完内层for
循环没有找到当前选手组合中有覆盖绝活tal
的选手,我们便得知这个选手组合需要被抛弃——缺少一项绝活,便不能视为正确的组合。因此我们能省却检查其他绝活,直接返回False
即可(第9行)。
如果我们检查了所有的绝活且在所有的迭代中都没有返回False
,意味着该组合覆盖了所有的绝活,可以返回True
(第10行)。
我们对开始的例子运行以下这段代码。例子中的表格转化为代码是:
Talents = ['Sing', 'Dance', 'Magic', 'Act', 'Flex', 'Code']
Candidates = ['Aly', 'Bob', 'Cal', 'Don', 'Eve', 'Fay']
CandidateTalents = [['Flex', 'Code'], ['Dance', 'Magic'],
['Sing', 'Magic'], ['Sing', 'Dance'],
['Dance', 'Act', 'Code'], ['Act', 'Code']]
如果我们运行
Hire4Show(Candidates, CandidateTalents, Talents)
产生输出
Optimum Solution: ['Aly', 'Cal', 'Eve']
与我们期望的完全一致。
如果对第二个稍大的例子运行代码
ShowTalent2 = [1, 2, 3, 4, 5, 6, 7, 8, 9]
CandidateList2 = ['A', 'B', 'C', 'D', 'E', 'F', 'G']
CandToTalents2 = [[4, 5, 7], [1, 2, 8], [2, 4, 6, 9],
[3, 6, 9], [2, 3, 9], [7, 8, 9],
[1, 3, 7]]
Hire4Show(CandidateList2, CandToTalents2, ShowTalent2)
会产生输出
Optimum Solution: ['A', 'B', 'D']
9.3 应用
这道谜题是集合覆盖问题(set-covering problem)的一个实例,而集合覆盖问题有很多应用场景。例如,汽车公司可能希望在能得到所有汽车配件供应的前提下,与最少汽车配件供应商合作,减少公司需要做的审查数量。NASA也希望在确保执行所有维护工作的前提下,最小化发射到太空的工具集合的总重量。
集合覆盖是一个难题:包括我们编写的算法在内的所有已知算法,对所有问题实例都要保证选中集合的基数最小,对某些实例可能需要耗费选手数量的指数时间。在这种意义上,集合覆盖问题与晚餐邀请谜题(谜题8)是等价的。
如果对绝对的最小基数不感兴趣,我们可以使用一种贪心法来解决问题。它可以做到快速,因为它只需要对表格做少量扫描或者遍历。适用本谜题的贪心算法会首先选出拥有最多绝活的选手,一旦该选手被选出,该选手覆盖的所有绝活都从表格中移除。这一过程持续至覆盖到所有绝活为止。
对于我们第二个稍大的例子,选手A
到G
中,我们会首先选出C
,他覆盖4项绝活:2、4、6和9。变小的表格如表9-3所示。
表9-3
这里选手G
覆盖3个(额外的)绝活。G
会中选,因为其他选手都只覆盖两个绝活。选出C
和G
后,得到表9-4所示的表格。
表9-4
我们仍需要覆盖绝活5,这需要选手A
;也需要绝活8,这需要选手B
或F
。总共4位选手。我们知道这并非最优解,前面的代码已经给出了3位选手的结果。
9.4 习题
习题1
在第一个例子中,Eve会“完胜”Fay,因为她会Fay会的所有绝活,而且会得更多。修改代码,将被完胜的选手移出表格,这能使组合的生成更加高效。
习题2
在我们的第一个例子里,Aly一定会被选出,因为她是唯一会柔术的选手。在表格中可以看得一清二楚,因为柔术一列只有一个标记。类似地,在我们第二个例子中,D
是覆盖绝活4的唯一选手,而F
是覆盖绝活7的唯一选手。
修改原始代码,做到:(1)识别出拥有独一无二绝活的选手;(2)削减表格,移除这些选手的所有相关绝活;(3)基于削减后的表格找出最优的选择;(4)加入步骤1中发现的选手。
难题3
あなたはプレイヤーの一部のみでなければなりません以上を支払うために、自分のために目を持っていると思います。だから、プレーヤーを受け入れることを選択することができ支払うための方法が必要です。あなたは、自分の値札を考えていること、各プレイヤーに重みを割り当てます。すべてのスキルをカバーするために以前のように、それは、選手たちのグループを見つけることができるようにコードを変更しますが、値札の重みを最小限に抑えます。
仮定は次式で与えられます。
ShowTalentW = [1, 2, 3, 4, 5, 6, 7, 8, 9]
CandidateListW = [('A', 3), ('B', 2), ('C', 1), ('D', 4),
('E', 5), ('F', 2), ('G', 7)]
CandToTalentsW = [[1, 5], [1, 2, 8], [2, 3, 6, 9],
[4, 6, 8], [2, 3, 9], [7, 8, 9],
[1, 3, 5]]
どのCandidateListW
番号がどのように高価な各プレイヤーのタプルに対応しています。あなたのコードは、それが生成する必要があり、コストを最小限にするためのものです。
Optimum Solution: [('A', 3), ('C', 1), ('D', 4), ('F', 2)]
Weight is: 10
イブはフェイよりもはるかに高価である場合には、最適化のこの「勝利」はもはや実行可能であることに注意してください!ときにのみ、右イブと重いフェイが同じ以下、この最適化を確立することができます。あなたは、コード1つの運動を使用している場合ので、これに注意してください。
問題4
ユニークなプレーヤーのために最適化された演習2が行う覚えていますか?問題3は、プレイヤーのセットで最低重量を選択するためにそれをコードに追加されました。
[1]このパズルはNBCのタレントショー(2006-)のタイトルから取られました。