From 00a84fbc013dcff41dfc6152944b493dfbcf4191 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E7=AB=8B=E8=8B=8F?= <467322500@qq.com> Date: Sat, 17 Apr 2021 14:46:32 +0800 Subject: [PATCH] g08-v1.0.2 --- .idea/.gitignore | 8 + .idea/artifacts/framework1_0_1.xml | 6 + .idea/checkstyle-idea.xml | 16 + .idea/csv-plugin.xml | 30 + .idea/dbnavigator.xml | 464 ++++++++++ .idea/inspectionProfiles/Project_Default.xml | 41 + .idea/misc.xml | 6 + .idea/modules.xml | 9 + .idea/uiDesigner.xml | 124 +++ .idea/vcs.xml | 6 + SearchFramework1.0.1.iml | 42 + .../SearchFramework1.0.1/META-INF/MANIFEST.MF | 3 + .../SearchFramework1.0.1/algs4/util/In.class | Bin 0 -> 13546 bytes .../SearchFramework1.0.1/algs4/util/Out.class | Bin 0 -> 4373 bytes .../algs4/util/StdIn.class | Bin 0 -> 8823 bytes .../algs4/util/StdOut.class | Bin 0 -> 3424 bytes .../algs4/util/StdRandom.class | Bin 0 -> 9077 bytes .../algs4/util/Stopwatch.class | Bin 0 -> 1382 bytes .../algs4/util/StopwatchCPU.class | Bin 0 -> 1676 bytes .../core/problem/Action.class | Bin 0 -> 309 bytes .../core/problem/Problem.class | Bin 0 -> 3250 bytes .../core/problem/State.class | Bin 0 -> 454 bytes .../core/runner/EngineFeeder.class | Bin 0 -> 2420 bytes .../core/runner/HeuristicType.class | Bin 0 -> 1271 bytes .../core/runner/ProblemType.class | Bin 0 -> 1096 bytes .../core/runner/SearchRunner.class | Bin 0 -> 3215 bytes .../core/solver/Node.class | Bin 0 -> 4322 bytes .../core/solver/Searcher.class | Bin 0 -> 932 bytes .../solver/blinded/BreadthFirstSearch.class | Bin 0 -> 319 bytes .../solver/blinded/DepthFirstSearch.class | Bin 0 -> 313 bytes .../solver/heuristic/AbstractFrontier.class | Bin 0 -> 1562 bytes .../solver/heuristic/BestFirstSearch.class | Bin 0 -> 2448 bytes .../solver/heuristic/EvaluationType.class | Bin 0 -> 1097 bytes .../core/solver/heuristic/Predictor.class | Bin 0 -> 188 bytes .../g08/problem/npuzzle/DecodeTalker.class | Bin 0 -> 4648 bytes .../g08/problem/npuzzle/FeederG08.class | Bin 0 -> 2619 bytes .../g08/problem/npuzzle/Maze.class | Bin 0 -> 1805 bytes .../g08/problem/npuzzle/Nod.class | Bin 0 -> 669 bytes .../g08/problem/npuzzle/Npuzzle.class | Bin 0 -> 2173 bytes .../g08/solver/heuristic/LinkedFrontier.class | Bin 0 -> 2547 bytes .../xu/problem/pathfinding/Direction.class | Bin 0 -> 2743 bytes .../xu/problem/pathfinding/FeederXu.class | Bin 0 -> 2921 bytes .../xu/problem/pathfinding/GridType.class | Bin 0 -> 1494 bytes .../xu/problem/pathfinding/Move.class | Bin 0 -> 1451 bytes .../xu/problem/pathfinding/PathFinding.class | Bin 0 -> 4866 bytes .../xu/problem/pathfinding/Point.class | Bin 0 -> 4124 bytes .../xu/problem/pathfinding/Position.class | Bin 0 -> 5036 bytes .../xu/solver/heuristic/LinkedFrontier.class | Bin 0 -> 2545 bytes .../problem/pathfinding/PathFeederTest.class | Bin 0 -> 1286 bytes .../problem/pathfinding/PathFindingTest.class | Bin 0 -> 1569 bytes .../xu/problem/pathfinding/PositionTest.class | Bin 0 -> 1088 bytes .../solver/heuristic/LinkedFrontierTest.class | Bin 0 -> 2573 bytes resources/npuzzle.txt | 4 + resources/pathfinding.txt | 14 + src/META-INF/MANIFEST.MF | 3 + src/algs4/util/In.java | 819 ++++++++++++++++++ src/algs4/util/Out.java | 341 ++++++++ src/algs4/util/StdIn.java | 696 +++++++++++++++ src/algs4/util/StdOut.java | 339 ++++++++ src/algs4/util/StdRandom.java | 674 ++++++++++++++ src/algs4/util/Stopwatch.java | 110 +++ src/algs4/util/StopwatchCPU.java | 112 +++ src/core/problem/Action.java | 6 + src/core/problem/Problem.java | 143 +++ src/core/problem/State.java | 22 + src/core/runner/EngineFeeder.java | 85 ++ src/core/runner/HeuristicType.java | 16 + src/core/runner/ProblemType.java | 8 + src/core/runner/SearchRunner.java | 98 +++ src/core/solver/Node.java | 146 ++++ src/core/solver/Searcher.java | 29 + .../solver/blinded/BreadthFirstSearch.java | 4 + src/core/solver/blinded/DepthFirstSearch.java | 5 + .../solver/heuristic/AbstractFrontier.java | 66 ++ .../solver/heuristic/BestFirstSearch.java | 78 ++ src/core/solver/heuristic/EvaluationType.java | 11 + src/core/solver/heuristic/Predictor.java | 18 + src/g08/problem/npuzzle/DecodeTalker.java | 197 +++++ src/g08/problem/npuzzle/FeederG08.java | 83 ++ src/g08/problem/npuzzle/Maze.java | 65 ++ src/g08/problem/npuzzle/Nod.java | 28 + src/g08/problem/npuzzle/Npuzzle.java | 82 ++ src/g08/solver/heuristic/LinkedFrontier.java | 89 ++ src/xu/problem/pathfinding/Direction.java | 60 ++ src/xu/problem/pathfinding/FeederXu.java | 109 +++ src/xu/problem/pathfinding/GridType.java | 23 + src/xu/problem/pathfinding/Move.java | 43 + src/xu/problem/pathfinding/PathFinding.java | 146 ++++ src/xu/problem/pathfinding/Point.java | 107 +++ src/xu/problem/pathfinding/Position.java | 132 +++ src/xu/solver/heuristic/LinkedFrontier.java | 89 ++ .../problem/pathfinding/PathFeederTest.java | 29 + .../problem/pathfinding/PathFindingTest.java | 28 + test/xu/problem/pathfinding/PositionTest.java | 20 + .../solver/heuristic/LinkedFrontierTest.java | 65 ++ 95 files changed, 5997 insertions(+) create mode 100644 .idea/.gitignore create mode 100644 .idea/artifacts/framework1_0_1.xml create mode 100644 .idea/checkstyle-idea.xml create mode 100644 .idea/csv-plugin.xml create mode 100644 .idea/dbnavigator.xml create mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/uiDesigner.xml create mode 100644 .idea/vcs.xml create mode 100644 SearchFramework1.0.1.iml create mode 100644 out/production/SearchFramework1.0.1/META-INF/MANIFEST.MF create mode 100644 out/production/SearchFramework1.0.1/algs4/util/In.class create mode 100644 out/production/SearchFramework1.0.1/algs4/util/Out.class create mode 100644 out/production/SearchFramework1.0.1/algs4/util/StdIn.class create mode 100644 out/production/SearchFramework1.0.1/algs4/util/StdOut.class create mode 100644 out/production/SearchFramework1.0.1/algs4/util/StdRandom.class create mode 100644 out/production/SearchFramework1.0.1/algs4/util/Stopwatch.class create mode 100644 out/production/SearchFramework1.0.1/algs4/util/StopwatchCPU.class create mode 100644 out/production/SearchFramework1.0.1/core/problem/Action.class create mode 100644 out/production/SearchFramework1.0.1/core/problem/Problem.class create mode 100644 out/production/SearchFramework1.0.1/core/problem/State.class create mode 100644 out/production/SearchFramework1.0.1/core/runner/EngineFeeder.class create mode 100644 out/production/SearchFramework1.0.1/core/runner/HeuristicType.class create mode 100644 out/production/SearchFramework1.0.1/core/runner/ProblemType.class create mode 100644 out/production/SearchFramework1.0.1/core/runner/SearchRunner.class create mode 100644 out/production/SearchFramework1.0.1/core/solver/Node.class create mode 100644 out/production/SearchFramework1.0.1/core/solver/Searcher.class create mode 100644 out/production/SearchFramework1.0.1/core/solver/blinded/BreadthFirstSearch.class create mode 100644 out/production/SearchFramework1.0.1/core/solver/blinded/DepthFirstSearch.class create mode 100644 out/production/SearchFramework1.0.1/core/solver/heuristic/AbstractFrontier.class create mode 100644 out/production/SearchFramework1.0.1/core/solver/heuristic/BestFirstSearch.class create mode 100644 out/production/SearchFramework1.0.1/core/solver/heuristic/EvaluationType.class create mode 100644 out/production/SearchFramework1.0.1/core/solver/heuristic/Predictor.class create mode 100644 out/production/SearchFramework1.0.1/g08/problem/npuzzle/DecodeTalker.class create mode 100644 out/production/SearchFramework1.0.1/g08/problem/npuzzle/FeederG08.class create mode 100644 out/production/SearchFramework1.0.1/g08/problem/npuzzle/Maze.class create mode 100644 out/production/SearchFramework1.0.1/g08/problem/npuzzle/Nod.class create mode 100644 out/production/SearchFramework1.0.1/g08/problem/npuzzle/Npuzzle.class create mode 100644 out/production/SearchFramework1.0.1/g08/solver/heuristic/LinkedFrontier.class create mode 100644 out/production/SearchFramework1.0.1/xu/problem/pathfinding/Direction.class create mode 100644 out/production/SearchFramework1.0.1/xu/problem/pathfinding/FeederXu.class create mode 100644 out/production/SearchFramework1.0.1/xu/problem/pathfinding/GridType.class create mode 100644 out/production/SearchFramework1.0.1/xu/problem/pathfinding/Move.class create mode 100644 out/production/SearchFramework1.0.1/xu/problem/pathfinding/PathFinding.class create mode 100644 out/production/SearchFramework1.0.1/xu/problem/pathfinding/Point.class create mode 100644 out/production/SearchFramework1.0.1/xu/problem/pathfinding/Position.class create mode 100644 out/production/SearchFramework1.0.1/xu/solver/heuristic/LinkedFrontier.class create mode 100644 out/test/SearchFramework1.0.1/xu/problem/pathfinding/PathFeederTest.class create mode 100644 out/test/SearchFramework1.0.1/xu/problem/pathfinding/PathFindingTest.class create mode 100644 out/test/SearchFramework1.0.1/xu/problem/pathfinding/PositionTest.class create mode 100644 out/test/SearchFramework1.0.1/xu/solver/heuristic/LinkedFrontierTest.class create mode 100644 resources/npuzzle.txt create mode 100644 resources/pathfinding.txt create mode 100644 src/META-INF/MANIFEST.MF create mode 100644 src/algs4/util/In.java create mode 100644 src/algs4/util/Out.java create mode 100644 src/algs4/util/StdIn.java create mode 100644 src/algs4/util/StdOut.java create mode 100644 src/algs4/util/StdRandom.java create mode 100644 src/algs4/util/Stopwatch.java create mode 100644 src/algs4/util/StopwatchCPU.java create mode 100644 src/core/problem/Action.java create mode 100644 src/core/problem/Problem.java create mode 100644 src/core/problem/State.java create mode 100644 src/core/runner/EngineFeeder.java create mode 100644 src/core/runner/HeuristicType.java create mode 100644 src/core/runner/ProblemType.java create mode 100644 src/core/runner/SearchRunner.java create mode 100644 src/core/solver/Node.java create mode 100644 src/core/solver/Searcher.java create mode 100644 src/core/solver/blinded/BreadthFirstSearch.java create mode 100644 src/core/solver/blinded/DepthFirstSearch.java create mode 100644 src/core/solver/heuristic/AbstractFrontier.java create mode 100644 src/core/solver/heuristic/BestFirstSearch.java create mode 100644 src/core/solver/heuristic/EvaluationType.java create mode 100644 src/core/solver/heuristic/Predictor.java create mode 100644 src/g08/problem/npuzzle/DecodeTalker.java create mode 100644 src/g08/problem/npuzzle/FeederG08.java create mode 100644 src/g08/problem/npuzzle/Maze.java create mode 100644 src/g08/problem/npuzzle/Nod.java create mode 100644 src/g08/problem/npuzzle/Npuzzle.java create mode 100644 src/g08/solver/heuristic/LinkedFrontier.java create mode 100644 src/xu/problem/pathfinding/Direction.java create mode 100644 src/xu/problem/pathfinding/FeederXu.java create mode 100644 src/xu/problem/pathfinding/GridType.java create mode 100644 src/xu/problem/pathfinding/Move.java create mode 100644 src/xu/problem/pathfinding/PathFinding.java create mode 100644 src/xu/problem/pathfinding/Point.java create mode 100644 src/xu/problem/pathfinding/Position.java create mode 100644 src/xu/solver/heuristic/LinkedFrontier.java create mode 100644 test/xu/problem/pathfinding/PathFeederTest.java create mode 100644 test/xu/problem/pathfinding/PathFindingTest.java create mode 100644 test/xu/problem/pathfinding/PositionTest.java create mode 100644 test/xu/solver/heuristic/LinkedFrontierTest.java diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..a221f6d --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Datasource local storage ignored files +/../../../../../:\AI_Study\AI2021\SearchFramework1.0.1\.idea/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/artifacts/framework1_0_1.xml b/.idea/artifacts/framework1_0_1.xml new file mode 100644 index 0000000..2420375 --- /dev/null +++ b/.idea/artifacts/framework1_0_1.xml @@ -0,0 +1,6 @@ + + + $PROJECT_DIR$/out/artifacts/framework1_0_1 + + + \ No newline at end of file diff --git a/.idea/checkstyle-idea.xml b/.idea/checkstyle-idea.xml new file mode 100644 index 0000000..6cd7127 --- /dev/null +++ b/.idea/checkstyle-idea.xml @@ -0,0 +1,16 @@ + + + + + + \ No newline at end of file diff --git a/.idea/csv-plugin.xml b/.idea/csv-plugin.xml new file mode 100644 index 0000000..6ea239b --- /dev/null +++ b/.idea/csv-plugin.xml @@ -0,0 +1,30 @@ + + + + + + \ No newline at end of file diff --git a/.idea/dbnavigator.xml b/.idea/dbnavigator.xml new file mode 100644 index 0000000..2f7edc7 --- /dev/null +++ b/.idea/dbnavigator.xml @@ -0,0 +1,464 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..b770297 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,41 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..d5d79e0 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..8f05ca6 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml new file mode 100644 index 0000000..e96534f --- /dev/null +++ b/.idea/uiDesigner.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/SearchFramework1.0.1.iml b/SearchFramework1.0.1.iml new file mode 100644 index 0000000..e25bd34 --- /dev/null +++ b/SearchFramework1.0.1.iml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/out/production/SearchFramework1.0.1/META-INF/MANIFEST.MF b/out/production/SearchFramework1.0.1/META-INF/MANIFEST.MF new file mode 100644 index 0000000..6a864cb --- /dev/null +++ b/out/production/SearchFramework1.0.1/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: runner.SearchRunner + diff --git a/out/production/SearchFramework1.0.1/algs4/util/In.class b/out/production/SearchFramework1.0.1/algs4/util/In.class new file mode 100644 index 0000000000000000000000000000000000000000..f9c9f69fd232ecf6f0f036fc495037fa38e26c3c GIT binary patch literal 13546 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 literal 0 HcmV?d00001 diff --git a/out/production/SearchFramework1.0.1/algs4/util/StdIn.class b/out/production/SearchFramework1.0.1/algs4/util/StdIn.class new file mode 100644 index 0000000000000000000000000000000000000000..e87911917c7e95490c9f07a8266487f781e754f4 GIT binary patch literal 8823 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 XGfu(=1%idMZ<+j*`#)5v;U|9s2OW*Z literal 0 HcmV?d00001 diff --git a/out/production/SearchFramework1.0.1/algs4/util/Stopwatch.class b/out/production/SearchFramework1.0.1/algs4/util/Stopwatch.class new file mode 100644 index 0000000000000000000000000000000000000000..749a96407ae26d0235ea52d0058854144828021a GIT binary patch literal 1382 zcmZux-%}e^6#g!|n_ZSQ{Afafszoc3#Fj`zETvLP(-zVM&>%C6zARx0ifv0z9l2h<8Z}!-c2ql96c}(kyA?WnTW*68>`>(DH;>q-VY@ynGoP0a z?T2>Wv;8_t1J|!F%6kZxzcuFBL7g2goRh``A|xVW2eZr!+YK7Q7MhIF@17O9XEbq~ z_O)tc*S@USt@s%_u8=|jv)XJ2HRqlypPPL7j2U@93n`>^tXQ~%qJB~2E51m@1Zt@RLVe4p-*+Vj&ipY?*S|K6e8C_->*=9X1os< zxh8oEybBf67(fPN+*z!Y>o_K8g%qrZwaPr1KSY@2%eh~mIFD0Mn?Etu#WQJvS>_dD ztkHNs)WcGV`UdYP(2qB9xr-`}k%(XLB&QTQ{Qvy{edj5RO0uNRYiaG$4;aa&wMQNF z*Gk8l`0?cV)!$$)Xd?sKpRjh6Y=;B9qmF6Pc987V-_Vl_hB|MiO(I+zGt%ax6b3sS zl?CJ2B+RpMUE-K8aK?-tkl6#0G$}DnD;T1`LaOg#kW)U4`y^)-S7@^+A&&?2*0ISc zt#bW>gL+8Y;_e7r_#U6dbnNqsBc++7Y#O$SAw84WPw+O;zz&b`4rBb};9E>FqmSLb zp+wWXOCGxvX_~d0xXsQJ%&$`79AgGMP2fFxCax0c8q^au({x-DI%X7#`Y%!^JTqQ| Pl$Y^wHq5iA5AXjExH$|4 literal 0 HcmV?d00001 diff --git a/out/production/SearchFramework1.0.1/algs4/util/StopwatchCPU.class b/out/production/SearchFramework1.0.1/algs4/util/StopwatchCPU.class new file mode 100644 index 0000000000000000000000000000000000000000..ce68d450b83e1d3c0d440ce6f19b365ba1245f11 GIT binary patch literal 1676 zcmZ`(T~ixn6n`@GM2&pFS#zyI^|ZvdvT zts{tcb-ah!ZuoJt2XmO0-uoIB{EIJNT7*HzE!@@_C2|o<(n|)A(y**!1$T6OfK~sk zKO|Iw7qKQVm|e`~^2^CwHkIFAU%t29_60;rpf_2y8;)r^n`XIb3G_Job<5n{C{?Vw zz~%IT`NT|=O}m(=n6_E8DwgdeHe5{R;gV(Aa{?*}>JIss%s*eUOU{CT5{+#N_>$FK zvi7A*wv}yGcC7k_xl?8&oURtk@}^lY$#o~_bM{LOfswRXE;gnUO{Y{& z$@Tlp)nk>-TElV==q6zeid{Wqs)|{%S#9)@=g@hlUb2gG@+hLj|0;22y~rdN&Vdm? z2EQYVzfNSMS)ozonzkLEYR75ZIBjpfm71ty{~PrE(4y)e#g{M-~?5KAU|vRSWFV(k~nT2l(qoinu+I^$Ti9jho68mO7| zhQ*~oB2Hg;Mul}>Fmq-eJ17Vi>6{!kEcngYSR^`_C#KW+@9o2dFyKfSWf6a z)7i~6$>*<8YYsO>&pC)!ZS7gOqEu>9x@t7VqhOr3ImmmfU=#z0fMVvV3mU>wAoRmh z8!kdf{SfggS2^wwv?K8s5b+keoz8N*5Ui=2(SVVo=LQi4sNEP26|8@08 z7_(})SN#>iEhW}MUw+FstV-KLe`o(qEjSzS&FB%G3`4_#i2if{p%yL_W&=k$Y5pA1 zB#(Z=GaTp;=^Y~3FvV@y68h<+ z8t>*IHt`i6xb4_uW8_TVL=-CHqpqjR;>i=I)$oi1iLy0)_>yB8X9Gj{0@t`pVV)gK z(o>mfk*jgy^H{*!j0Ko!6xZqLm?G0P_>P%O)$oqcFs)D&avC3D!W-Pw Hg_(Z=qUmA0 literal 0 HcmV?d00001 diff --git a/out/production/SearchFramework1.0.1/core/problem/Action.class b/out/production/SearchFramework1.0.1/core/problem/Action.class new file mode 100644 index 0000000000000000000000000000000000000000..7718a84809ebb3960dbbe0378e9c1afa48170d1b GIT binary patch literal 309 zcmZusu};G<5PjD;NeO|LR(t>(FyMs^gj7{RLW*Djb$46~T%~d4xbR&}NDO=cAB8xl zjCiM=Wu`UBY2MHTng&0zBgY literal 0 HcmV?d00001 diff --git a/out/production/SearchFramework1.0.1/core/problem/Problem.class b/out/production/SearchFramework1.0.1/core/problem/Problem.class new file mode 100644 index 0000000000000000000000000000000000000000..75441745ff675213edb08fc64b263b35c3600d25 GIT binary patch literal 3250 zcmb_eT~iZh6n-|@WRtLhAfVAASla>#8m&rOK`y!-BX&w0+r`<%1+WmESFPUK9${!fzKLn1y@suDv67-f!hXL4W?6cJjW_bdX{HvXdTO!Tsv2GOS1+0R!&I=HR$sttH4Lac|av? zR6~4742Lyjd+M3gll4v!;dp6|2u)*7(H>vCHEX-)Eqc<>GFHl4g(=H*lvc@PlJmeXs0$RGc@>+ump>-S(c|F!pM~231d~oMktu(vJ4@GI67_`mXo*s1$@z zx7H0yA`oLAHc=@R?)a$__cANvmP($6LxHUv+iq^bUUZ#`=j3w}u07}Ey^=c^gdAv$ zv!EF#8y zz!J*Ewf59p$cTM=(H<1y_iPZ?EwUOBbFOt)1G|EDq_tD@CP*d5KUrFI^Y%$c=7kwd zfxSXP6FYIk*o?2u(AI!(NR4h@^vv&_Jvi2>XZCA!(7NF2U@6Zg=~%QbNy4-9;6 z;vpXKrcHc-{U(<1CGA3U(yy|KGZ>fiuS|T6jERpiX5t$>Ht{VUvo;}{AOVKB)<xxwItZhnVFt+_c4qkz0B$N*PHcAWIK3Ke}9KdsyN`Hn&t4sxdp4b_t*yh%xyZ-(7?i*E!_ z?liR%hY{uG?ZC~93J5SW*}fI%nU1H3t@&tFSljv6UMU0wKmUdsOT9&ws7Gh}FgS{KD|^DKweKZZ z!WhBI)yJx#g^zWBSO;H%B_z;vjlT9X?qR%<2mBfa!r~R&B~L%=rb5m ztRS&gec#mxIe4PRRY$c19Sq?Rp_|c<_XyktXcu9SNx;%`B&S!98qY4HVL(so%P^l| zlZJsUrWB#sXz@Y7xOxh56>$UzwU)rb!+Mkph z(ndBNZ%ec#8TUYHPdc@Xwu?Xf{rw(ELRW3HSA{cy1kSOA&a*007{n!v;4&sL1B?Hs zE4YdW+&#jqO7uEXJnzT*tfWD$ZhXMIPEaGwuSN%}SfP9nL)6=c(>RP_wh)u9mSzbb z@>JSkNfjwV>$^CDqimW++{Q5?>p0GH=?VXAgl8uxX+`t}wi`HU;FN)n{=(HiS=>>c zL~xq-$`1;Y)8#uunZ~9(%e9O9!_<)bP0FQ4m(jky86MW$W3n1-QY9*snZPH6@?D+d T`y>knJ}=bDsWC+-5nTKSm`lOC literal 0 HcmV?d00001 diff --git a/out/production/SearchFramework1.0.1/core/problem/State.class b/out/production/SearchFramework1.0.1/core/problem/State.class new file mode 100644 index 0000000000000000000000000000000000000000..24fe46b5adbb84e24de62705a32340c05b88f008 GIT binary patch literal 454 zcmZut%SyvQ6g|`CVPmwl*1C3=SZFrxS_&cvLeNE|`$;;~Dd|MUsrp;41Q&jQA0^(5 z6$v_vd+y_$`JalKjRLf`Vd zq)b1p3SQ2+mUX;MI_6G3FbvY7(jvLn6_wUWX1Ea(>b21Pi9m^G!!U}Ptn8~;n1j+)K4BWENIvTCCXaVhKD z0y}kFPYL0`rEC8l#L)X)<0fB;!Z;^r(O=fj0UZjLtVdBo$OzrjSFjgyTJXtwHtAu9 f{P3HA4gyj$?2@>~5PKH)(IrODY7fZkTkr4-^YUnp literal 0 HcmV?d00001 diff --git a/out/production/SearchFramework1.0.1/core/runner/EngineFeeder.class b/out/production/SearchFramework1.0.1/core/runner/EngineFeeder.class new file mode 100644 index 0000000000000000000000000000000000000000..76ecc9172925592cc49fad277cd5713282d783e1 GIT binary patch literal 2420 zcma)7+fv(B6kRgLHjWw`+LDAckP9TnK-`ujy+BF1xzGx5Dnd*1&^g!#TOcHlB-8NL z59&kPhtf%A@&TQGQ>W`lGT6Z|=s`z&pM6>Ts(=1_{T9Guyv#z!bRWN-WN`&g)A%fl zB&O5&Jc}>zWfm#SsO#AQ%Fm~oJtH=OL&%|V`eg_TfT-NqvCq9=rtWjdc|d@M&*)}Rq4%WxKfir*>kCMK+y+z zL)bO{aj_X#c5&6288`OCp@_(N&l5+6fLBgN^0=?{>r1QLNc1cr4zG~P+TU9-M z+G(a#JvP|c(*zOs^;oCqJ9TELfeiafRe8zU+gH`m@PRE3cB*2ujXC;6!$b_X)tHfb z6l*7Md{slQudLHpHvy)q<_eqDGTo+EktIuw=C$^Td!&NY@gAG6Jy{`?(e6+>2ZZsLUKj?~NR*v3gVHI^5|6xU7F$Vf zh@ie}IaP~p%dT&!vE!m?w5CAA%Z|}!kDTM?OrxD6cRFBdxAv9iH&=dM+%Pw@*g#or z>E|rv$u{76y#LPNo!oJqwPrPq?{%2?LB}MfG~7GQrR5yD`?6?+ZOFQaUG5CmJK_>P zIHl6q=Gr%0cfZ--9$8h(aM2dNFA3n^I0IpAVtY}ASACro|CW<0tm`nf!E%N5k;Na>=_am(D*YkcFn^i|>9? zMV=bZ-oi1oKlqVAj_*{+9Ktnz>yZEk@IH{_Y~w?621D8FA${Y7zDb(%8p?fy+u=Ek zk?_2uPDqyYI5Rlq>qvLof17Es;fMK z1!S;9x)h=-L>3}+$`f>&Yj3a3@3x@AqeHNKLn9z1EDwtByw3b3NeVM zJQD{ F_CM2;k0}5E literal 0 HcmV?d00001 diff --git a/out/production/SearchFramework1.0.1/core/runner/HeuristicType.class b/out/production/SearchFramework1.0.1/core/runner/HeuristicType.class new file mode 100644 index 0000000000000000000000000000000000000000..859113e18bf3280e883b3f9df5861ca8c30076db GIT binary patch literal 1271 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 literal 0 HcmV?d00001 diff --git a/out/production/SearchFramework1.0.1/core/solver/Searcher.class b/out/production/SearchFramework1.0.1/core/solver/Searcher.class new file mode 100644 index 0000000000000000000000000000000000000000..ff5685f8f6874870744777b8ecac67e4a9923cd1 GIT binary patch literal 932 zcma))!EVz)5QhJCOq`?+Z9|f_6iQ1Qut~rdE-0lE0&#Lnq@YMWZpB5cs;W--~2l>KmUCF4&W&s8@O8n!$t}Bu(^OO+&8do zV22?e3ogAQ2HSGIND5~tqkbSxoX+TM+wL(x@-~T|X2D$w^rk^sjhrgkwtIP+3i7ntfTlATD9~~jQw!;uFTkX~GT9&L%+a~| z4eanUwEgA!v@yrpC}_1mat4# qYFBWJ>J=!iN;w)ugKAGaE96-vPZ8R06b!7@#v*T1$U0qUxbqJSQth_@ literal 0 HcmV?d00001 diff --git a/out/production/SearchFramework1.0.1/core/solver/blinded/BreadthFirstSearch.class b/out/production/SearchFramework1.0.1/core/solver/blinded/BreadthFirstSearch.class new file mode 100644 index 0000000000000000000000000000000000000000..97d342978298ba34b4f1ebba6a6e938368337920 GIT binary patch literal 319 zcma)%KT88a5XIkI?vI|Q2{zU?5-r@uPO(r(b!ZVuzqdDd8`fLc+vIy$2^M|;Ka^xH z*x5J(k9j|49?bX8=NEt*%t}mfT;Qa@l#t)q-o|^vWPZ6Kq>sL3!nC$MKW*L`4llZK zLQZRMv|H(5NB;}c*x7+FuZ<6^2Jf~URO4*la;qK!>o#@^8-}=K9ZYviD3^W{3@_}M zdG>eZdabv*LW+!V@xN5UY&=p<_pj=?S+j{aMbF5XQgB<&Vbb9fA)ah^U3z*eN#3RY8lB>o=Rh?6GELvv==hC0O_XK9o2) ztgM`YkNJMgd@x_%AD;lOFe@>^eu0AmQ$l`YdmC>Fle647VTcRX!F1Pza^cs(@Z64x zM}HSCS9+r>q{s*-|4Agw#uMdq|EwOH6`P1-B=X)^BrRE@xj41;Kz8vCdJ~YK5X}Wc T4t7MV?VMp3r8vT#XoBhoHBd-O literal 0 HcmV?d00001 diff --git a/out/production/SearchFramework1.0.1/core/solver/heuristic/AbstractFrontier.class b/out/production/SearchFramework1.0.1/core/solver/heuristic/AbstractFrontier.class new file mode 100644 index 0000000000000000000000000000000000000000..8d60363c10704ecf8b0fae17d3e8d9b97a59fad9 GIT binary patch literal 1562 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 literal 0 HcmV?d00001 diff --git a/out/production/SearchFramework1.0.1/g08/problem/npuzzle/DecodeTalker.class b/out/production/SearchFramework1.0.1/g08/problem/npuzzle/DecodeTalker.class new file mode 100644 index 0000000000000000000000000000000000000000..722241eef5123a653b959f44598653feabc80020 GIT binary patch literal 4648 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 literal 0 HcmV?d00001 diff --git a/out/production/SearchFramework1.0.1/g08/problem/npuzzle/FeederG08.class b/out/production/SearchFramework1.0.1/g08/problem/npuzzle/FeederG08.class new file mode 100644 index 0000000000000000000000000000000000000000..0440496e3caca1f5026b6b85eac7a96c5d7550ac GIT binary patch literal 2619 zcma)8OK%fb6#lMb&vnc|XutsjE~UJj5Ms(BrEy4cD1o$&33Zw@&<8j6)EO{#G#(?! zI-Bn3vQotYsiNwt?SfQ|)Ll3I4XnEDAE;0Z{qD@za)J}F@XWpEo^$SZzVjIW`Qo?V z0i4BGG4x_w;!+GDjK}Z+F6+mH#36|*F-TmMn2eztA8L({ByurKAs>T@Yu%W}^%&m3 z#}WmJ83AL|uG;RHKv$}NRv>(-R@~&Qj@QfoeV~E#hPQa=nH7d zj1j{2f~$&mrqq(hH*+q~U9ihlBf zcO6x1c_gJ_mj*1sO)NGz7BIcawMur;tq~C^_pWjpnyd8HCZa82Ogn)+@87?Ly+Dk& zO_mhX&b#)e*2h(_lv7+}h6Hv}ub_c6Wi&0+8cxxguywcYXf@xE?kp3#u$y`7&}9;z zn3%MEp4YH z7EBZ|YN7-NknD6%D=6Y@&%)(und8boWz(#iEu1}zs-Cy*yLzN~V~$}+$5N%qDklcV z9;b**O>&y(0XP^WIOy^;Q{h?}KWXb_o_d!ml{g53(yyp$Iel&6wpDa9{k&#pds*ha z$=YrCrQ2Riukf^?3fsryrP|#k-%OKI-a&0F%kVHE}>*|z4WGb7#nw^=+<~h$; zN?E_)&b)qcH|s8gL;RZb^2-E%d01lD&1amuG~a^n$iOPZ&s>Di$EV>5_h1j#rmuj# zNN~sLjs4W3vG@xSe!zeq*ASXtMc34crwD(G@A!(0C6j-^2#tihh9mJv@-dEd4I6QT zi+Ca&kDQJhTI<@1A)dVadnLl>v%n(KRHTKBOV1(_H%`Z;Zy`MkZTD;qaz2>|uOd2P z`0I#X%QbY*Cyazlt|B%P9ZW=@V%yx4m&L)Kh&Jp+IO~PK4^c+bgCq%g69;e*M@iKX z4r7Gxi`-A(81gudIrQTePN2fK!~K0~t&qNlIEP0V#`ky^Kj6H_*b25IMZONuuR$Nj z={rfTZUi!k>w(PRz28tHi7sk?jkkDfnD@=$ZLT7`;SjMLp_hlmdz355+axg^Cvq|$ zWJRx1M8-nFV+;^y2!lM=x$`9_DH)<<2(f<=l}NuppO7#Fcj7trJV)d|#MTS`VSJ}( z6T&-Q-cS2^XSDq8YPrySwpYvrFaAFNw1q8%GyF>=0$=C28YWwQ0bXR}+LyTobNowD%>EBecWqYy literal 0 HcmV?d00001 diff --git a/out/production/SearchFramework1.0.1/g08/problem/npuzzle/Maze.class b/out/production/SearchFramework1.0.1/g08/problem/npuzzle/Maze.class new file mode 100644 index 0000000000000000000000000000000000000000..f69a484cf9234836ee83254c383031e3d8ec9bec GIT binary patch literal 1805 zcmZ`(T~ixn6n@^_z>;(+5WXseT4`(Z0Z9v`AOsMq)o3WyR2+t@C9H8V*<_YYRj&CZ z-gxJz)21CAz3Nr{2l`K#`tiKGYm%*T7|#2iujiceoOko$ub+Mea2tCuj9@8>Vcd~o zIf@m$HGowOYcb@p9>WGUrFeS)TN<`wxPT=o?n?2F6z^)dr{O(;$cc4o3Wx%)HA7z2 zg99r4dCRuk4XVl19({M~NAwL9E!(``tR0%pL*uYYOT1Vw8`V9-v7{atBkt$ciNI8` za&sluaO(8ba(1J6dRjGeJFK!Mpd|||B(ViUMU9q<=}M8O^3Z^dj{n*J<&IqJmA(#u4CC1fw54oZs=rp`hafe8}xxpIv6ss!enEGr6@wXl;H3 z(?-3tFdE5jNNncilmBJ=pv&Y_#%I+7hUl7yQ?=y_Ycx!oe9!kl>~1Z@EFlu%&cklJ z!B2gJ-@n2?uGqVA%RDtMjGL#tL@mdYJ49dlDZ~$6*lU#io^cpcyz71drjei~lV>Pp z@;<>;oBmsM!K%8R@Nd_CL?qr9`33#^DlO{tLL&PN zTB(JBPtO$b?ccvMpoQp};QhHAOZ6&WCZ-%BhFK1FjU>)u32$PJwk;&vBkD-uDhHEG z*kqhP;&w3hbz%%7@)C-8iKsY7@|?f5f;cyV!SC=?7^R3;r=Ig_O!(e5jS6e0m?Mxz zhCaEYIZy9}ajT0tCBT@I)iBQ-ey@}g;TflvYut>-if!r^)r}dS#H&B!!v0g}nHB~m ziHU`oYzr4#{P{mq$=e?ulfPx;2;KB8Q(M6xR=KJ?Zt+~EzD}a#3rVx&5XX`9spz9e k(kIE-3|dv0b(47ll1RR>KhdXQA>i`HIgvyf)`y zKsTQ0&*Rm~waq~=xuN+}JEB2iK9^f0p=9*9o=VsE0*mwsOr`sEEE!#1pgjh0IJWN` z4w0jo7c*;V>CjNnkwadG0+pe@g@B>V>rL14r{=?GW{)GB(NbjERE9ok79LHaQw9m5 zKvt*7q?7S%`vdG%lMjUN)MGsm)dFCCwedMpEt8 zJ2HRL8s$L}GOA)iO~gtf&(ZihIQ2eiDInQRkXkB89S3P3*-elp|IfC7@WpbFhIo4O E7tzgCQUCw| literal 0 HcmV?d00001 diff --git a/out/production/SearchFramework1.0.1/g08/problem/npuzzle/Npuzzle.class b/out/production/SearchFramework1.0.1/g08/problem/npuzzle/Npuzzle.class new file mode 100644 index 0000000000000000000000000000000000000000..1f6c59a2735cc0ee3954b40f485fac9a3f44bc73 GIT binary patch literal 2173 zcmbVNZBrXn6n<{rHc1zGYbb?=z9=?<*ifxd2~CT^TG|k(L8`6QS;9_OT(awC(+bm% z{0}>hGyT#pI!b5!;16*6i#m?=xpxCX8yz$+ckekl_nhZE=h@BgfByO#fJ^u)iCz@t zay5Y-TuWjWA0|=4oHRd@%k>04#*H}Ulemdnaa>HIj0I^_;#iEMpkYbFZGqT~)v)}c zz<8!yb38Nedd{kCZsx1L;hTj{zU+!Xq~xrb0^Mb+VOCn3tERVX@R&ef*{K=!is4z( zZaX9Xy44g&m+KRk_X{-K*7mk-<}1OqAfQVqmSL;X0>?WQXX(0Q*aEpD3Z9$}GO=mYgO- zj{;@3=37pqkY)X7Q&LOn4doL^9d5K8Dv&f>*S2Z_)c;b1J?YJL=V8^cTe2*<%#=5b z2S%Qzou4zmX_*DZifj1m0==*OC@^q%kX!EFFh^evo(bSfR!uKop)d+XPBT%p>J7th zd2BWFTKSHL6r?rJc*t2~q>*qvtKlyxkjbjk@@nRFOUg`dtLB32N=G01<#I~LNepTD zL`N0N8a~yrf;&2fF{C4n5e=W|_#C7s*=p>mK*K#9U*NumFLiu?X=zLgoVe2YB{2Li zDkjs1?xLmOZW8EG^xHV_GWCK=JK;R{X2M+B;9`l{jy5Y@w zp0P!(X0lSI2jjM=%T4m_o+rm(O=1Tz?skx{=4|`U&yA#4eKIr;(?uA69G?(ars7vTz1n zBzq9&ki}b=#@l?PpT{CHxQj8|r?1A}EL?z#34Du-*yf*wWVpzFa+u=j5k%R0g>fT_ zokwkULX3TrK0fW>Fw-dO4PuQoMv3D*bDV|tl1HN&GD1U^A5Q2G^oVm^FA(LYhlj^7 z9*~G@yvpf^!m^cM@G<(pTkP+lhxUgPBEVqiA-uyDLWGxR8-bSoIa~3F*#zl$mszDU ztGr4HCM4mX`5_K`B5)TA{`!ExDkDLm;&l9?8M|vi?o1!O#%iQr9!c`W! zLyv4ZO>Iy|I_vGCiw2b>jlMV9#RGl@I2_;x1w79&++>PdlzmwN35uoLKm-b%yXo%G Q%@Vu0{lB}JQGH$c3+H#CVE_OC literal 0 HcmV?d00001 diff --git a/out/production/SearchFramework1.0.1/g08/solver/heuristic/LinkedFrontier.class b/out/production/SearchFramework1.0.1/g08/solver/heuristic/LinkedFrontier.class new file mode 100644 index 0000000000000000000000000000000000000000..98c9cac9c7dba373a883b6220f1789864ccc6a1d GIT binary patch literal 2547 zcma)7+fp1=6kUh84-FyQA|@f22$@SJ6Qj|DA>fE&&|#t>5)&`685(F9rm?4oQlEYG z15$nfFL{VnN-A1fKKlc{`Wsr&xOR6B3^PqtisJOy=bXLwT5Iof=8yk={tduu*h=CA z=3;m^i7wnoU>NfXL4oV*86>XWgtTjF;9fU2W!DHySpPniU`RoNd({)361)v7=WT zlIt+P77Vg+DACv3&19`)4?K<_n+xU`cv^VJ)(l6KQb?sd`L=C~M7Q#bj_w$Rbf=~i zOUfnEbm*<1sLNnbB!wP^tZXjm+pdZ+e8Jk-#+J3iSVKPUs$N^m-(21>Do!DNkKruI zgG30 z5lW@!nb2BYHCW#8wpFcC0S4*-CcB2Q>FowkN-kOryJF0l(su)1^EbQbqMX-o3a9BF zbVFp12VTI4hDj8tu7+h)G^}7&p|2f`1_P@xtZ7)sD;h4za1JlWU~1UFrp70rs^L1O zWp+iwo0!$`mNyi|IP3g@2V3Mfpp=0CV8#pSwV>lLTTlC?hI)~t&wv9#*CUN0M8 z@r|J5tZ}&J8gX{8+pAt(-9(3bnDpD#X6G4SHuS1A>p{kY+r?}Z_kmy~&Ihz+XGcmC z45#J;HkR-b-?|fgR!L6^#P5r=x^NOboU^8!k8gNJGT!phYPe6E^<{v=qchcI z-DiJ_&nY744GRR1`C0z@fr+}9WE8KH&l|*kjVqJ1rg%N3U3eMFJBlH$WnH0*`#_7X zGKvvq=zEo4(W4)sf00xar( zdh$y9lC;G+)-LXifH+Dnz3)HCtWuq5hQjoN8g03*yI-c#3hlJwC_T zaP5?CwLt0igDE~oM}+7P2yv$~L|>5&((E;(CN)loyp_HcFk`x+lMWD45L#x5kAg2^#RX9!4av)7gE(oYE zzVOC)nep=GjITau(835hJUTKy`3v+9_@=(-xYo`gJ>fF#m}&Of>-O!n_F8MFKmYsv zj{pwhJs%XD^=uQ)8w2;wf{9Fnxx#P%>-vN)= z)Nz$YW+tO!KMn{4_S{ef|n#O{k-hvWe+a{yrd9+gyI}82DmP; z^%+5)E>|s{Y>x4Uj(6}brMnUe-xytOzF02NJ%r;4$8Bb3FVU+&cQxqjk95(jR)-vB ztsZShCBKN%&o;|&DcuWp|E##!hduRt%_`NVdD6%;o}luFoxsh27&a2mIQ<_z6y&v3 zr_O7eEKb~+#k0>J-A7OCPI~6`(M?<@fGCwpQmU4uR4_@YW|C6bB&EtpO2s3D5Vr@> zD7OTtcWLj!Ao0{OE&lmHlpBzADttJKA<_&J*GH5;{szP{To2&>nmB{eB#S+Q|@Gu?C-tVwQ^LX6&}JtWZqr5DbX{$_Xq&FPP1o~C=Lm!1q`!dYzCY)7XLE`x+YEt(At_Ya zh2fUayX;9G%jXK>&z2nDe znvM%J30JTV@56)p=)zAl^AE8ZzhVo1BfmfBAGLqbD>@Jpo6skAVVfAlc9Et>KZ|}b zhuz{j_J~^;5MLrC?qaX_1^dMB*f0K~w_}t}=Gl9QYsk`xAmk;yN;~=uvZwD143fJr F^&b=sUdI3c literal 0 HcmV?d00001 diff --git a/out/production/SearchFramework1.0.1/xu/problem/pathfinding/FeederXu.class b/out/production/SearchFramework1.0.1/xu/problem/pathfinding/FeederXu.class new file mode 100644 index 0000000000000000000000000000000000000000..fadac00948888209bd630cfec08f6c107047fa77 GIT binary patch literal 2921 zcma)8U2_vv7=AX*W|MR)U#1eV0;QCsEksJG&_Ja?3z4)$Qa(ymI8ByxOS)S(oAPnZ zjK6>jM=u7<2pdXckd&w1bHecsQ_AOHRKJAffP zilY-(H00w5;Yu8nn9^`nLm`d`K9TR&G!)~AVOqoWINEVTE;pt4Ee$hq+{SDiJMgKL z`7DOdaVL%h?rIPk<`hKEn3m~|DrifkZzu>~u*-&m9eL9-rs|7xhBGbZsyx}9w@adW zLpY{<4-UibyjfFlF#oWgS#oS%EM}I3JAco#%BEGxOc+MlaBkJJ3fe1%Tku7w(VNPP zYNa-msk>%1le4nv{DN2({_B|Ih(~#|=29(MGOE?-M@wX&vLe!#V4R~6{e z0aH|qu5c;Vl1#y_QO>rA8m`!anp(hFK~F0W3iM{e_l9~Q)0VN>NS!1D96FY0;YYY; zJ|;P};+SQM9h#kOW$_Xvq{B4VxiRKE4B~$DO;*n2OSWUI=OGAoc9cLJj7{nOq*(Iw zz0{XjQyPvdh!xF>CEU70dZXJ)%NBgwFTt}4F5oIm8UUl}i z(AWgba`hU)D4QkMCL@O2OPf=dvC3R-Fxrwv!3p$ff8Q4R3gWbuD+}hIw)Unr`c*W9 zQ<`Un6zrs2Q4(pKQMG8-osuzO%J%PQwDK|8r#jxjUZ(90J*%OlqYSEaZ>Plfx0oD_ zF3@og6&>?n)3=gsG`3{L`Ow`0vZ&;~jzKE<(gOj5t zmEKNV+vi1X%6RC?IqqTH=I}}7a&pEG1SJgk2ClIXT6v`A?gs`!T|(gEq8*J z4tuv2QG01oBd%m~g#4ZoB~3;#8RsAea@UUm<|2x3ag_W*wD&cWc@S;%BF| zk=gU5PEcxyCp}PKkw`?tNe#mqK2$WEVh#L@UCK-Be+l&;+@w#k7Dl{$XZ?KBU;g`$ z=ZcJEbETa3yzcaG*I9-bk+anCu|~Q32bn^7m5Q1x|G z9b=4`EZYmX7@(czQ=+Lv+PxX(Ruhc64xW%3#_`fEDRSX|5G0d3!9u8 zKlh`W&bw@RqtX3v&Yt%??{m&`&hD?@-+uy_!kd2(V`U$rAX}ZMM}~g(+sV)z~FCFaWxUzqzTn_G!o~|XxoNTt5=9h z2$~stFhtW5Yo%6)3_Zb6yCPyNuUlp43Q^9ULM4rQF?Ol61zMRWQ>s_;>axaX)%kaq zQ+!Yo2KmP{Bw-mThLKD5FCl;x33sq6VE{Ks{rPDx)iu4KRybx_!gIV}0QYGLlbGVi zK?y$iCG>IA4?jcK2?-ZP-&kHR8Px09v8?BI)qIWgoLO>0SE|+Msk!{y`dL=G=WDkr zK31nvE~`d?VUYH7fy$CZ1e0wD{*Parp&zW5eqP67KbH)UC)K7W;gpg26anu5UjxNX zxG{_oFpN?ZAkQC91FQ+#G3=ixqTiIP)6CfkAHbM}pM%Xj^~gf_8yv?FINo*!KTao7 z3x!*_ZRTkwgc_yy71*g~LWCy<58(_CeTD0@iQzT7C<}B@ZHa6rIG2xZa>kIUhre+} zc7*BFh6$=PfV)n*dy39)(TRv)+M;_82ay4(BM4c!%kG^%ME3!_W_V5Tj+voshSwe5uo?C^ we-PT6X_e88iVQBR zxPn;)S5+uT$<3UMt_5&iK5xinM!`+_W?sQ9fnd?Jje=uZ6@jt!*R@R5w(=#ToT=*0 z&U3R;G%MSgmE)YOfPcZPn9icWMB?A+$t?k2&MF!LJ?m!0cvvgv4f~1C4g!7aRzWXq z>9#5N?xD}wG4}*wov=5oeS<8tZNq7?5*SY;I~BCDSmi6)`YQo%Lh=giIYu>S?KzEu zH6A$Drekwnfhh5I^?f~4(m8(fRL*X^tm!4v>rb@3ew5#(g4yIV0Y$G^&W>Rd(#r43 z5l>LuG=c6-M=!kC(5vpq>ZVn*3&yG`MG49QXJnOz2x1z}piemuqIJXxJK7a8JW3?h8OZ9|(+ea9DQLFouf)k%DC#t!uF4-i_Y2 zCI?imEJv(SyZ+{grj>b2?Hn>N^fI-IGzv~1Q=qC$D)F+NlF(IH+A`XKVarF_SZKKR zUl)+R`u7gXd8^d0nR5B{YSpL|1Jw7Jb=I1G`vxxII*vnrhO_!cA z@-vPg%C(=nRe1OT)YK6~D*Xwb_uP3fz%>jn*C2dQxrQ*v-9R%NLpaMF>l&znXu}wB zF*AJ9TXdy9!t;(n6HYdkpb|!FCb%#h8Zn+oLi5a)d7%&Rrt0w3(RIQ|ZFG;YYqSj} z)PgyW3ogtopAse@Iedoyka0VWp|<)!tDYCxtzU6z41b04^r#6_N3agHFI0zCNB5tD z#o7>uTZp{7F5&?ZrJnJ0>Mgo_hv^>(zdEnp8DWX1{o(9dyxDM7!50M literal 0 HcmV?d00001 diff --git a/out/production/SearchFramework1.0.1/xu/problem/pathfinding/PathFinding.class b/out/production/SearchFramework1.0.1/xu/problem/pathfinding/PathFinding.class new file mode 100644 index 0000000000000000000000000000000000000000..7bc32b14ea950da9b5795211ac746c885b46475b GIT binary patch literal 4866 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 O7}vkLcM*UGyZ;Xbf?2iz literal 0 HcmV?d00001 diff --git a/out/production/SearchFramework1.0.1/xu/problem/pathfinding/Point.class b/out/production/SearchFramework1.0.1/xu/problem/pathfinding/Point.class new file mode 100644 index 0000000000000000000000000000000000000000..2b0e3863e3100ad4cb9f55ff156fb89117f990d0 GIT binary patch literal 4124 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 Lv#HGNGnn{4tWTa? literal 0 HcmV?d00001 diff --git a/out/production/SearchFramework1.0.1/xu/solver/heuristic/LinkedFrontier.class b/out/production/SearchFramework1.0.1/xu/solver/heuristic/LinkedFrontier.class new file mode 100644 index 0000000000000000000000000000000000000000..5d85dfbef0579f9b3eaddc7968c0a56829c29949 GIT binary patch literal 2545 zcma)7+fp1=6kTWTGc<&7i<{?rZ)ip1+TA@c%rvD%ar*3Y&fa^iwf8ym+dn`40^ntAr*I1M zalD;E2-lMs!h+1+>B74x$*>qlIfVpnr0^czm%W>EYN-pi@PU}iGTcsa?L(Q}k>ReG zAIb2s44=gDX&m-n;=}yBo6taPb zrb-pdHVSpCx@*{lGDA+z&@nb;)=XzcVL095HfL?`=(g@y_GD&RAu`9~3MZJ-C^xoO z4EvV8Qsqit$*SnpW!*N#_7@}0hFMoQU%KCDrrR(YHi4QIAN9O#)g05X1-Y@SR~wS* zD7_X4vT-EO7dy>dty~X1j^UaQrWklyXvfzLM}$&Hr#Pa%3rmjf7?YV!NvV}o zOO)x5TR~BlfuKkV-3(dTTGV%35##ubrLm1|YnQPGecV;OwqCfgvT0PD$;@4bvm}q( z5v^MaVSRPgb?d+&Zc!1OVbv!87ucz6G1D>Ja#QMbrlk=U{B;&88@LfD9#yEDUou5F zompT)Yi-S7c_TYkwMqpTr~{bn8pf8l8$cgxS^?SYF?4rwZUc(ujrF+l? zkv$%G2E!UAFiCYate~P{6>|!`?O-$*Sc_v_!vW-~foF++@`jA?)EUv=RsT+E|Y~1Gy zLB(0(NX<18Y+$!ly|TKAj#d9*q`im;(#X)3q+ioJ!f!tNJtF&v zE?#;6@i^UfSAW6S_+rBsv-OYi8u=9{vs45t>{CWrY(9T1sd~reM=+c>JZ}*ki#fP zkALzYcoJ9e68DvKt{>`W0uZ3Z@U+jfocDQ-bK>!wh;UCEj^rMrJB)7-+e7lJklK6t zyZD?Tf}V&#@R*PBw+~DdVv-TOLO!n&`!%ji(3;}ym~r7{Denjdxt4Qa< zn5FM){E8lZ2>*?gq99LjA&zT*61b8p&3!4@6_*;2@QFw*T1A<2vwDS3__@4(o1!Og zv@c0poD=QhUJr<)1GR*EHQ8Kc(&?kS-K$$M_qg4xvMA*LN4_4G@lJS%#x6TV)aqLKCId1Fc$B&z0=;O1YNP zJlCvfs}=$AI)F*L3j6vyJvdu*9Q~+Z`qa{m1s+w;i=1rcFxQ;$0&}%&x_a^LnqKvr z0;r^eoprFt*H^$%ZXjmhI}UXfK9h z+MZK1R!k{KM`LrRWK}9!(Izl(i5x+{UVG%&&>)g>jG7<2c2U16_t2Fg7Zl`Gr16+F zsCa@!7NX)QmQ*~$vOs4u@l>oxE<=}aX=E?Z=BrZCd23$m>>EYO*yD$7qBx6hq9O0- zKkF)6r@OX8y|aOSe&|it;l0eun?9WV@0N@<(^=jfDMJt|oxKP;&q0i`r`OhvLz3n* zdc$XA`J2vj{Dr!Rj+7kzJqFRjcPoD({wW*;+PTs=3(nE86Npd#af)NiH>&91S`7f` zL>G6UG;Itboqr%qBrt!9(Dn(!g;PYfQ_&N|*2X7}p{!3HBR(6+L_Xt+zz1~8RYKq! zlC#lF^cd>Lv!60)1TyJ$C>+}nXQ~v_^zh3egBkQ<4*fov9HO*E(ap1{OkJlH$25_> zq?*Dw`iKq@F@$T38pZ&TvW&noNXrdc`Vczfaa6%g1-BI3RxqSs82ClE5dvfvvYZ7* IIfgLy2U9LNGXMYp literal 0 HcmV?d00001 diff --git a/out/test/SearchFramework1.0.1/xu/problem/pathfinding/PathFindingTest.class b/out/test/SearchFramework1.0.1/xu/problem/pathfinding/PathFindingTest.class new file mode 100644 index 0000000000000000000000000000000000000000..6e6801ab0e10a9fb08bf328fb010a4fa3e279d73 GIT binary patch literal 1569 zcmZ`(TT|0O7(Lq-Qqw5NP4J2rupkgG;H`*Ouv!h*GK}Rdl(j5Vl1wfP{w#fzbbp5iXl`Y)|;Ywis?El8s9Uap?4BKRfLWPj|wf zkJz^bSc`-xED+GhMqv5kfNu#;kUB-nvVBwXAg)&p+pX*S0m)CTBYfJr=?J~8RK*V5 z8ZQZ{{=gX}XXG|D3}T4kMuPZ}fFA>f^QROeRxbBKaPQ=4&G<*YgnX@FQNt46Btx&o zQpxg?g0~vpq0DeAfyoK-3|A70mhD5X;JthO1anu&QAV>l!v>xPoL0UF1fTIeLtLJK!#kM`|+95sg38)_-~?#yf7-?s zGAb{ejupej3lrN!v9o!Lp2ywT;5jpVDVYtAES$-2%VikZN{temZon~$e!AD>FGYVc zG#D4^V9(Rc#_|w2-Ox zbv4nwd~fO)%1R5_YOkU+aqf9$I(-cFCvqd17PRVDoNwa7F?znC_iW~3JJTl#r6CDj zheGW|x_bxEM+AoHxkL08h}K6UCW+2QWMZOOtm7KZqdOIEaf1{{(VQY~;uc}v!5nT= bo52{(lv|8)(h0O(5~i+m!-iwsPfWbXb@Ewo`9XGj4kgr&)7+ zrSCmuBHUMjz@mK|SuNkA;m~S1;r=`2?kacBdhG=&RGzyngRsoxt~?F}Mp`|!z}&D% zMoqqn+)y3LnhF#vR9x2!9i5exr)|&QvkoFsplqp7`j*pDRk;J#BzUfT`mrwpVoP9tP-{>9*xSY8a4%hRxo9^$ zU!D%R(kWCfo!4%0E|OXE{~t;v2&CT|oauBf)%TIpED3sB&#`z2z%5 z`R?@>3*z{J#WhNP2GBo z>Z6{4K{OfuCJH3EMx-x^w2mA;5Wi-V?;`H8$soX0OpxIks$@1nX4mMY`A>2exK0_v F)E|nf2-yGt literal 0 HcmV?d00001 diff --git a/out/test/SearchFramework1.0.1/xu/solver/heuristic/LinkedFrontierTest.class b/out/test/SearchFramework1.0.1/xu/solver/heuristic/LinkedFrontierTest.class new file mode 100644 index 0000000000000000000000000000000000000000..16c2ff862a6e3b8d62c34bb3677ad9fd4cc8c7cf GIT binary patch literal 2573 zcmb7GTT>fl7=AuTvLRjClos0bU@OuZply1#1xj065Hvt7EeIZ$WPybw8#fzT>iK+_ zah&nO8NG4F3w!Cv1!x%^XS{Hx-Z?tswLhR2UUWvs5ubOH6w(G;L-sqo`@F~R`QC8- zpKIR%IE?p0*ok%x9W^+C&Jcn)8A26KX*eB101s<8Bf_&9x@ypkM?wgpM-aWTeN=|W zWE)?DKJ?2lP=j-LJcRQYl;MJ?UlhoYfQM!EguED$)u;?l%J7unp4RY;hG!K59ahG2 zI~A&<%|i;lGj`HcSQoc4W`90CW;z#)u@ohBaXVq8h78A&eNpIhC#{@9G=4cB%h{;7N(xQ) zU|KY?cFuAwJEO3%U@`01j58e@bPZQ*2C{}@W?W_{o)v2OA~D@(WW7|pYIJCLj;El( zP>7t*GwifEWaTW{Ii1PaG(-nXcU#`1li!wCo zcnL4-cm=QOcullk#~bqEO&xEExwl369lWdKJ*mO&yVpP}%XFl0v6R6?2gat%1VwdT zhNV(?XHB7p%ez)8*2}XoT$_YzT3L%_l6K7)sl0cv7iP0OFJJe?c$_hn(Q-97X;otu z42X-)=)Gw*$Cm>36aJk(aLY+V)~=Ky)vIFIw{M!z09$9i^^}o>4b2%y*X$k(_e(N`6+->=uwQ@A5AHf1@Ps`tss!lV(l83hUbPD)DX#7NF;mK6`Ms8(#EUUgWP zVH!`ce;Stbor?aY4AD^uBb>By3BySaIOol5%1F?cX63rlS$CG0ter}+IhNupcjQYt z#wGqd?cgJyDn9H_PxII>5n>hQV+)bxuy7`!FlyND3A)+|6T0NQ-5 z5#Ky&hdp38a0?mn6`*Sg^@VF`s|*?rRKU`s?yrE=R>20sH7o75&LiCBkNCgAdWBE0 zMOJkR-y_%-n8SuhU>+NIH9hiQ~iQd9x;1Jz8n01 zrx`5>5LsLaA&X>PtA0c)_K?7vX<;w+k+{3nmt=hlbL&wbFpn1aaDZ7hBd~Input. This class provides methods for reading strings + * and numbers from standard input, file input, URLs, and sockets. + *

+ * The Locale used is: language = English, country = US. This is consistent + * with the formatting conventions with Java floating-point literals, + * command-line arguments (via {@link Double#parseDouble(String)}) + * and standard output. + *

+ * For additional documentation, see + * Section 3.1 of + * Computer Science: An Interdisciplinary Approach + * by Robert Sedgewick and Kevin Wayne. + *

+ * Like {@link Scanner}, reading a token also consumes preceding Java + * whitespace, reading a full line consumes + * the following end-of-line delimeter, while reading a character consumes + * nothing extra. + *

+ * Whitespace is defined in {@link Character#isWhitespace(char)}. Newlines + * consist of \n, \r, \r\n, and Unicode hex code points 0x2028, 0x2029, 0x0085; + * see + * Scanner.java (NB: Java 6u23 and earlier uses only \r, \r, \r\n). + * + * @author David Pritchard + * @author Robert Sedgewick + * @author Kevin Wayne + */ +public final class In { + + ///// begin: section (1 of 2) of code duplicated from In to StdIn. + + // assume Unicode UTF-8 encoding + private static final String CHARSET_NAME = "UTF-8"; + + // assume language = English, country = US for consistency with System.out. + private static final Locale LOCALE = Locale.US; + + // the default token separator; we maintain the invariant that this value + // is held by the scanner's delimiter between calls + private static final Pattern WHITESPACE_PATTERN = Pattern.compile("\\p{javaWhitespace}+"); + + // makes whitespace characters significant + private static final Pattern EMPTY_PATTERN = Pattern.compile(""); + + // used to read the entire input. source: + // http://weblogs.java.net/blog/pat/archive/2004/10/stupid_scanner_1.html + private static final Pattern EVERYTHING_PATTERN = Pattern.compile("\\A"); + + //// end: section (1 of 2) of code duplicated from In to StdIn. + + private Scanner scanner; + + /** + * Initializes an input stream from standard input. + */ + public In() { + scanner = new Scanner(new BufferedInputStream(System.in), CHARSET_NAME); + scanner.useLocale(LOCALE); + } + + /** + * Initializes an input stream from a socket. + * + * @param socket the socket + * @throws IllegalArgumentException if cannot open {@code socket} + * @throws IllegalArgumentException if {@code socket} is {@code null} + */ + public In(Socket socket) { + if (socket == null) throw new IllegalArgumentException("socket argument is null"); + try { + InputStream is = socket.getInputStream(); + scanner = new Scanner(new BufferedInputStream(is), CHARSET_NAME); + scanner.useLocale(LOCALE); + } + catch (IOException ioe) { + throw new IllegalArgumentException("Could not open " + socket, ioe); + } + } + + /** + * Initializes an input stream from a URL. + * + * @param url the URL + * @throws IllegalArgumentException if cannot open {@code url} + * @throws IllegalArgumentException if {@code url} is {@code null} + */ + public In(URL url) { + if (url == null) throw new IllegalArgumentException("url argument is null"); + try { + URLConnection site = url.openConnection(); + InputStream is = site.getInputStream(); + scanner = new Scanner(new BufferedInputStream(is), CHARSET_NAME); + scanner.useLocale(LOCALE); + } + catch (IOException ioe) { + throw new IllegalArgumentException("Could not open " + url, ioe); + } + } + + /** + * Initializes an input stream from a file. + * + * @param file the file + * @throws IllegalArgumentException if cannot open {@code file} + * @throws IllegalArgumentException if {@code file} is {@code null} + */ + public In(File file) { + if (file == null) throw new IllegalArgumentException("file argument is null"); + try { + // for consistency with StdIn, wrap with BufferedInputStream instead of use + // file as argument to Scanner + FileInputStream fis = new FileInputStream(file); + scanner = new Scanner(new BufferedInputStream(fis), CHARSET_NAME); + scanner.useLocale(LOCALE); + } + catch (IOException ioe) { + throw new IllegalArgumentException("Could not open " + file, ioe); + } + } + + + /** + * Initializes an input stream from a filename or web page name. + * + * @param name the filename or web page name + * @throws IllegalArgumentException if cannot open {@code name} as + * a file or URL + * @throws IllegalArgumentException if {@code name} is {@code null} + */ + public In(String name) { + if (name == null) throw new IllegalArgumentException("argument is null"); + if (name.length() == 0) throw new IllegalArgumentException("argument is the empty string"); + try { + // first try to read file from local file system + File file = new File(name); + if (file.exists()) { + // for consistency with StdIn, wrap with BufferedInputStream instead of use + // file as argument to Scanner + FileInputStream fis = new FileInputStream(file); + scanner = new Scanner(new BufferedInputStream(fis), CHARSET_NAME); + scanner.useLocale(LOCALE); + return; + } + + // resource relative to .class file + URL url = getClass().getResource(name); + + // resource relative to classloader root + if (url == null) { + url = getClass().getClassLoader().getResource(name); + } + + // or URL from web + if (url == null) { + url = new URL(name); + } + + URLConnection site = url.openConnection(); + + // in order to set User-Agent, replace above line with these two + // HttpURLConnection site = (HttpURLConnection) url.openConnection(); + // site.addRequestProperty("User-Agent", "Mozilla/4.76"); + + InputStream is = site.getInputStream(); + scanner = new Scanner(new BufferedInputStream(is), CHARSET_NAME); + scanner.useLocale(LOCALE); + } + catch (IOException ioe) { + throw new IllegalArgumentException("Could not open " + name, ioe); + } + } + + /** + * Initializes an input stream from a given {@link Scanner} source; use with + * {@code new Scanner(String)} to read from a string. + *

+ * Note that this does not create a defensive copy, so the + * scanner will be mutated as you read on. + * + * @param scanner the scanner + * @throws IllegalArgumentException if {@code scanner} is {@code null} + */ + public In(Scanner scanner) { + if (scanner == null) throw new IllegalArgumentException("scanner argument is null"); + this.scanner = scanner; + } + + /** + * Returns true if this input stream exists. + * + * @return {@code true} if this input stream exists; {@code false} otherwise + */ + public boolean exists() { + return scanner != null; + } + + //// begin: section (2 of 2) of code duplicated from In to StdIn, + //// with all methods changed from "public" to "public static". + + /** + * Returns true if input stream is empty (except possibly whitespace). + * Use this to know whether the next call to {@link #readString()}, + * {@link #readDouble()}, etc will succeed. + * + * @return {@code true} if this input stream is empty (except possibly whitespace); + * {@code false} otherwise + */ + public boolean isEmpty() { + return !scanner.hasNext(); + } + + /** + * Returns true if this input stream has a next line. + * Use this method to know whether the + * next call to {@link #readLine()} will succeed. + * This method is functionally equivalent to {@link #hasNextChar()}. + * + * @return {@code true} if this input stream has more input (including whitespace); + * {@code false} otherwise + */ + public boolean hasNextLine() { + return scanner.hasNextLine(); + } + + /** + * Returns true if this input stream has more input (including whitespace). + * Use this method to know whether the next call to {@link #readChar()} will succeed. + * This method is functionally equivalent to {@link #hasNextLine()}. + * + * @return {@code true} if this input stream has more input (including whitespace); + * {@code false} otherwise + */ + public boolean hasNextChar() { + scanner.useDelimiter(EMPTY_PATTERN); + boolean result = scanner.hasNext(); + scanner.useDelimiter(WHITESPACE_PATTERN); + return result; + } + + + /** + * Reads and returns the next line in this input stream. + * + * @return the next line in this input stream; {@code null} if no such line + */ + public String readLine() { + String line; + try { + line = scanner.nextLine(); + } + catch (NoSuchElementException e) { + line = null; + } + return line; + } + + /** + * Reads and returns the next character in this input stream. + * + * @return the next {@code char} in this input stream + * @throws NoSuchElementException if the input stream is empty + */ + public char readChar() { + scanner.useDelimiter(EMPTY_PATTERN); + try { + String ch = scanner.next(); + assert ch.length() == 1 : "Internal (Std)In.readChar() error!" + + " Please contact the authors."; + scanner.useDelimiter(WHITESPACE_PATTERN); + return ch.charAt(0); + } + catch (NoSuchElementException e) { + throw new NoSuchElementException("attempts to read a 'char' value from the input stream, " + + "but no more tokens are available"); + } + } + + + /** + * Reads and returns the remainder of this input stream, as a string. + * + * @return the remainder of this input stream, as a string + */ + public String readAll() { + if (!scanner.hasNextLine()) + return ""; + + String result = scanner.useDelimiter(EVERYTHING_PATTERN).next(); + // not that important to reset delimeter, since now scanner is empty + scanner.useDelimiter(WHITESPACE_PATTERN); // but let's do it anyway + return result; + } + + + /** + * Reads the next token from this input stream and returns it as a {@code String}. + * + * @return the next {@code String} in this input stream + * @throws NoSuchElementException if the input stream is empty + */ + public String readString() { + try { + return scanner.next(); + } + catch (NoSuchElementException e) { + throw new NoSuchElementException("attempts to read a 'String' value from the input stream, " + + "but no more tokens are available"); + } + } + + /** + * Reads the next token from this input stream, parses it as a {@code int}, + * and returns the {@code int}. + * + * @return the next {@code int} in this input stream + * @throws NoSuchElementException if the input stream is empty + * @throws InputMismatchException if the next token cannot be parsed as an {@code int} + */ + public int readInt() { + try { + return scanner.nextInt(); + } + catch (InputMismatchException e) { + String token = scanner.next(); + throw new InputMismatchException("attempts to read an 'int' value from the input stream, " + + "but the next token is \"" + token + "\""); + } + catch (NoSuchElementException e) { + throw new NoSuchElementException("attemps to read an 'int' value from the input stream, " + + "but no more tokens are available"); + } + } + + /** + * Reads the next token from this input stream, parses it as a {@code double}, + * and returns the {@code double}. + * + * @return the next {@code double} in this input stream + * @throws NoSuchElementException if the input stream is empty + * @throws InputMismatchException if the next token cannot be parsed as a {@code double} + */ + public double readDouble() { + try { + return scanner.nextDouble(); + } + catch (InputMismatchException e) { + String token = scanner.next(); + throw new InputMismatchException("attempts to read a 'double' value from the input stream, " + + "but the next token is \"" + token + "\""); + } + catch (NoSuchElementException e) { + throw new NoSuchElementException("attemps to read a 'double' value from the input stream, " + + "but no more tokens are available"); + } + } + + /** + * Reads the next token from this input stream, parses it as a {@code float}, + * and returns the {@code float}. + * + * @return the next {@code float} in this input stream + * @throws NoSuchElementException if the input stream is empty + * @throws InputMismatchException if the next token cannot be parsed as a {@code float} + */ + public float readFloat() { + try { + return scanner.nextFloat(); + } + catch (InputMismatchException e) { + String token = scanner.next(); + throw new InputMismatchException("attempts to read a 'float' value from the input stream, " + + "but the next token is \"" + token + "\""); + } + catch (NoSuchElementException e) { + throw new NoSuchElementException("attemps to read a 'float' value from the input stream, " + + "but no more tokens are available"); + } + } + + /** + * Reads the next token from this input stream, parses it as a {@code long}, + * and returns the {@code long}. + * + * @return the next {@code long} in this input stream + * @throws NoSuchElementException if the input stream is empty + * @throws InputMismatchException if the next token cannot be parsed as a {@code long} + */ + public long readLong() { + try { + return scanner.nextLong(); + } + catch (InputMismatchException e) { + String token = scanner.next(); + throw new InputMismatchException("attempts to read a 'long' value from the input stream, " + + "but the next token is \"" + token + "\""); + } + catch (NoSuchElementException e) { + throw new NoSuchElementException("attemps to read a 'long' value from the input stream, " + + "but no more tokens are available"); + } + } + + /** + * Reads the next token from this input stream, parses it as a {@code short}, + * and returns the {@code short}. + * + * @return the next {@code short} in this input stream + * @throws NoSuchElementException if the input stream is empty + * @throws InputMismatchException if the next token cannot be parsed as a {@code short} + */ + public short readShort() { + try { + return scanner.nextShort(); + } + catch (InputMismatchException e) { + String token = scanner.next(); + throw new InputMismatchException("attempts to read a 'short' value from the input stream, " + + "but the next token is \"" + token + "\""); + } + catch (NoSuchElementException e) { + throw new NoSuchElementException("attemps to read a 'short' value from the input stream, " + + "but no more tokens are available"); + } + } + + /** + * Reads the next token from this input stream, parses it as a {@code byte}, + * and returns the {@code byte}. + *

+ * To read binary data, use {@link BinaryIn}. + * + * @return the next {@code byte} in this input stream + * @throws NoSuchElementException if the input stream is empty + * @throws InputMismatchException if the next token cannot be parsed as a {@code byte} + */ + public byte readByte() { + try { + return scanner.nextByte(); + } + catch (InputMismatchException e) { + String token = scanner.next(); + throw new InputMismatchException("attempts to read a 'byte' value from the input stream, " + + "but the next token is \"" + token + "\""); + } + catch (NoSuchElementException e) { + throw new NoSuchElementException("attemps to read a 'byte' value from the input stream, " + + "but no more tokens are available"); + } + } + + /** + * Reads the next token from this input stream, parses it as a {@code boolean} + * (interpreting either {@code "true"} or {@code "1"} as {@code true}, + * and either {@code "false"} or {@code "0"} as {@code false}). + * + * @return the next {@code boolean} in this input stream + * @throws NoSuchElementException if the input stream is empty + * @throws InputMismatchException if the next token cannot be parsed as a {@code boolean} + */ + public boolean readBoolean() { + try { + String token = readString(); + if ("true".equalsIgnoreCase(token)) return true; + if ("false".equalsIgnoreCase(token)) return false; + if ("1".equals(token)) return true; + if ("0".equals(token)) return false; + throw new InputMismatchException("attempts to read a 'boolean' value from the input stream, " + + "but the next token is \"" + token + "\""); + } + catch (NoSuchElementException e) { + throw new NoSuchElementException("attempts to read a 'boolean' value from the input stream, " + + "but no more tokens are available"); + } + } + + /** + * Reads all remaining tokens from this input stream and returns them as + * an array of strings. + * + * @return all remaining tokens in this input stream, as an array of strings + */ + public String[] readAllStrings() { + // we could use readAll.trim().split(), but that's not consistent + // since trim() uses characters 0x00..0x20 as whitespace + String[] tokens = WHITESPACE_PATTERN.split(readAll()); + if (tokens.length == 0 || tokens[0].length() > 0) + return tokens; + String[] decapitokens = new String[tokens.length-1]; + for (int i = 0; i < tokens.length-1; i++) + decapitokens[i] = tokens[i+1]; + return decapitokens; + } + + /** + * Reads all remaining lines from this input stream and returns them as + * an array of strings. + * + * @return all remaining lines in this input stream, as an array of strings + */ + public String[] readAllLines() { + ArrayList lines = new ArrayList(); + while (hasNextLine()) { + lines.add(readLine()); + } + return lines.toArray(new String[lines.size()]); + } + + + /** + * Reads all remaining tokens from this input stream, parses them as integers, + * and returns them as an array of integers. + * + * @return all remaining lines in this input stream, as an array of integers + */ + public int[] readAllInts() { + String[] fields = readAllStrings(); + int[] vals = new int[fields.length]; + for (int i = 0; i < fields.length; i++) + vals[i] = Integer.parseInt(fields[i]); + return vals; + } + + /** + * Reads all remaining tokens from this input stream, parses them as longs, + * and returns them as an array of longs. + * + * @return all remaining lines in this input stream, as an array of longs + */ + public long[] readAllLongs() { + String[] fields = readAllStrings(); + long[] vals = new long[fields.length]; + for (int i = 0; i < fields.length; i++) + vals[i] = Long.parseLong(fields[i]); + return vals; + } + + /** + * Reads all remaining tokens from this input stream, parses them as doubles, + * and returns them as an array of doubles. + * + * @return all remaining lines in this input stream, as an array of doubles + */ + public double[] readAllDoubles() { + String[] fields = readAllStrings(); + double[] vals = new double[fields.length]; + for (int i = 0; i < fields.length; i++) + vals[i] = Double.parseDouble(fields[i]); + return vals; + } + + ///// end: section (2 of 2) of code duplicated from In to StdIn */ + + /** + * Closes this input stream. + */ + public void close() { + scanner.close(); + } + + /** + * Reads all integers from a file and returns them as + * an array of integers. + * + * @param filename the name of the file + * @return the integers in the file + * @deprecated Replaced by {@code new In(filename)}.{@link #readAllInts()}. + */ + @Deprecated + public static int[] readInts(String filename) { + return new In(filename).readAllInts(); + } + + /** + * Reads all doubles from a file and returns them as + * an array of doubles. + * + * @param filename the name of the file + * @return the doubles in the file + * @deprecated Replaced by {@code new In(filename)}.{@link #readAllDoubles()}. + */ + @Deprecated + public static double[] readDoubles(String filename) { + return new In(filename).readAllDoubles(); + } + + /** + * Reads all strings from a file and returns them as + * an array of strings. + * + * @param filename the name of the file + * @return the strings in the file + * @deprecated Replaced by {@code new In(filename)}.{@link #readAllStrings()}. + */ + @Deprecated + public static String[] readStrings(String filename) { + return new In(filename).readAllStrings(); + } + + /** + * Reads all integers from standard input and returns them + * an array of integers. + * + * @return the integers on standard input + * @deprecated Replaced by {@link StdIn#readAllInts()}. + */ + @Deprecated + public static int[] readInts() { + return new In().readAllInts(); + } + + /** + * Reads all doubles from standard input and returns them as + * an array of doubles. + * + * @return the doubles on standard input + * @deprecated Replaced by {@link StdIn#readAllDoubles()}. + */ + @Deprecated + public static double[] readDoubles() { + return new In().readAllDoubles(); + } + + /** + * Reads all strings from standard input and returns them as + * an array of strings. + * + * @return the strings on standard input + * @deprecated Replaced by {@link StdIn#readAllStrings()}. + */ + @Deprecated + public static String[] readStrings() { + return new In().readAllStrings(); + } + + /** + * Unit tests the {@code In} data type. + * + * @param args the command-line arguments + */ + public static void main(String[] args) { + In in; + String urlName = "https://introcs.cs.princeton.edu/java/stdlib/InTest.txt"; + + // read from a URL + System.out.println("readAll() from URL " + urlName); + System.out.println("---------------------------------------------------------------------------"); + try { + in = new In(urlName); + System.out.println(in.readAll()); + } + catch (IllegalArgumentException e) { + System.out.println(e); + } + System.out.println(); + + // read one line at a time from URL + System.out.println("readLine() from URL " + urlName); + System.out.println("---------------------------------------------------------------------------"); + try { + in = new In(urlName); + while (!in.isEmpty()) { + String s = in.readLine(); + System.out.println(s); + } + } + catch (IllegalArgumentException e) { + System.out.println(e); + } + System.out.println(); + + // read one string at a time from URL + System.out.println("readString() from URL " + urlName); + System.out.println("---------------------------------------------------------------------------"); + try { + in = new In(urlName); + while (!in.isEmpty()) { + String s = in.readString(); + System.out.println(s); + } + } + catch (IllegalArgumentException e) { + System.out.println(e); + } + System.out.println(); + + + // read one line at a time from file in current directory + System.out.println("readLine() from current directory"); + System.out.println("---------------------------------------------------------------------------"); + try { + in = new In("./InTest.txt"); + while (!in.isEmpty()) { + String s = in.readLine(); + System.out.println(s); + } + } + catch (IllegalArgumentException e) { + System.out.println(e); + } + System.out.println(); + + + // read one line at a time from file using relative path + System.out.println("readLine() from relative path"); + System.out.println("---------------------------------------------------------------------------"); + try { + in = new In("../stdlib/InTest.txt"); + while (!in.isEmpty()) { + String s = in.readLine(); + System.out.println(s); + } + } + catch (IllegalArgumentException e) { + System.out.println(e); + } + System.out.println(); + + // read one char at a time + System.out.println("readChar() from file"); + System.out.println("---------------------------------------------------------------------------"); + try { + in = new In("InTest.txt"); + while (!in.isEmpty()) { + char c = in.readChar(); + System.out.print(c); + } + } + catch (IllegalArgumentException e) { + System.out.println(e); + } + System.out.println(); + System.out.println(); + + // read one line at a time from absolute OS X / Linux path + System.out.println("readLine() from absolute OS X / Linux path"); + System.out.println("---------------------------------------------------------------------------"); + try { + in = new In("/n/fs/introcs/www/java/stdlib/InTest.txt"); + while (!in.isEmpty()) { + String s = in.readLine(); + System.out.println(s); + } + } + catch (IllegalArgumentException e) { + System.out.println(e); + } + System.out.println(); + + + // read one line at a time from absolute Windows path + System.out.println("readLine() from absolute Windows path"); + System.out.println("---------------------------------------------------------------------------"); + try { + in = new In("G:\\www\\introcs\\stdlib\\InTest.txt"); + while (!in.isEmpty()) { + String s = in.readLine(); + System.out.println(s); + } + System.out.println(); + } + catch (IllegalArgumentException e) { + System.out.println(e); + } + System.out.println(); + + } + +} + +/****************************************************************************** + * Copyright 2002-2020, Robert Sedgewick and Kevin Wayne. + * + * This file is part of algs4.jar, which accompanies the textbook + * + * Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne, + * Addison-Wesley Professional, 2011, ISBN 0-321-57351-X. + * http://algs4.cs.princeton.edu + * + * + * algs4.jar is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * algs4.jar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with algs4.jar. If not, see http://www.gnu.org/licenses. + ******************************************************************************/ diff --git a/src/algs4/util/Out.java b/src/algs4/util/Out.java new file mode 100644 index 0000000..ba29780 --- /dev/null +++ b/src/algs4/util/Out.java @@ -0,0 +1,341 @@ +package algs4.util; +/****************************************************************************** + * Compilation: javac Out.java + * Execution: java Out + * Dependencies: none + * + * Writes data of various types to: stdout, file, or socket. + * + ******************************************************************************/ + +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.net.Socket; +import java.util.Locale; + +/** + * This class provides methods for writing strings and numbers to + * various output streams, including standard output, file, and sockets. + *

+ * For additional documentation, see + * Section 3.1 of + * Computer Science: An Interdisciplinary Approach + * by Robert Sedgewick and Kevin Wayne. + * + * @author Robert Sedgewick + * @author Kevin Wayne + */ +public class Out { + + // force Unicode UTF-8 encoding; otherwise it's system dependent + private static final String CHARSET_NAME = "UTF-8"; + + // assume language = English, country = US for consistency with In + private static final Locale LOCALE = Locale.US; + + private PrintWriter out; + + /** + * Initializes an output stream from a {@link OutputStream}. + * + * @param os the {@code OutputStream} + */ + public Out(OutputStream os) { + try { + OutputStreamWriter osw = new OutputStreamWriter(os, CHARSET_NAME); + out = new PrintWriter(osw, true); + } + catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * Initializes an output stream from standard output. + */ + public Out() { + this(System.out); + } + + /** + * Initializes an output stream from a socket. + * + * @param socket the socket + */ + public Out(Socket socket) { + try { + OutputStream os = socket.getOutputStream(); + OutputStreamWriter osw = new OutputStreamWriter(os, CHARSET_NAME); + out = new PrintWriter(osw, true); + } + catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * Initializes an output stream from a file. + * + * @param filename the name of the file + */ + public Out(String filename) { + try { + OutputStream os = new FileOutputStream(filename); + OutputStreamWriter osw = new OutputStreamWriter(os, CHARSET_NAME); + out = new PrintWriter(osw, true); + } + catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * Closes the output stream. + */ + public void close() { + out.close(); + } + + /** + * Terminates the current line by printing the line-separator string. + */ + public void println() { + out.println(); + } + + /** + * Prints an object to this output stream and then terminates the line. + * + * @param x the object to print + */ + public void println(Object x) { + out.println(x); + } + + /** + * Prints a boolean to this output stream and then terminates the line. + * + * @param x the boolean to print + */ + public void println(boolean x) { + out.println(x); + } + + /** + * Prints a character to this output stream and then terminates the line. + * + * @param x the character to print + */ + public void println(char x) { + out.println(x); + } + + /** + * Prints a double to this output stream and then terminates the line. + * + * @param x the double to print + */ + public void println(double x) { + out.println(x); + } + + /** + * Prints a float to this output stream and then terminates the line. + * + * @param x the float to print + */ + public void println(float x) { + out.println(x); + } + + /** + * Prints an integer to this output stream and then terminates the line. + * + * @param x the integer to print + */ + public void println(int x) { + out.println(x); + } + + /** + * Prints a long to this output stream and then terminates the line. + * + * @param x the long to print + */ + public void println(long x) { + out.println(x); + } + + /** + * Prints a byte to this output stream and then terminates the line. + *

+ * To write binary data, see {@link BinaryOut}. + * + * @param x the byte to print + */ + public void println(byte x) { + out.println(x); + } + + + + /** + * Flushes this output stream. + */ + public void print() { + out.flush(); + } + + /** + * Prints an object to this output stream and flushes this output stream. + * + * @param x the object to print + */ + public void print(Object x) { + out.print(x); + out.flush(); + } + + /** + * Prints a boolean to this output stream and flushes this output stream. + * + * @param x the boolean to print + */ + public void print(boolean x) { + out.print(x); + out.flush(); + } + + /** + * Prints a character to this output stream and flushes this output stream. + * + * @param x the character to print + */ + public void print(char x) { + out.print(x); + out.flush(); + } + + /** + * Prints a double to this output stream and flushes this output stream. + * + * @param x the double to print + */ + public void print(double x) { + out.print(x); + out.flush(); + } + + /** + * Prints a float to this output stream and flushes this output stream. + * + * @param x the float to print + */ + public void print(float x) { + out.print(x); + out.flush(); + } + + /** + * Prints an integer to this output stream and flushes this output stream. + * + * @param x the integer to print + */ + public void print(int x) { + out.print(x); + out.flush(); + } + + /** + * Prints a long integer to this output stream and flushes this output stream. + * + * @param x the long integer to print + */ + public void print(long x) { + out.print(x); + out.flush(); + } + + /** + * Prints a byte to this output stream and flushes this output stream. + * + * @param x the byte to print + */ + public void print(byte x) { + out.print(x); + out.flush(); + } + + /** + * Prints a formatted string to this output stream, using the specified format + * string and arguments, and then flushes this output stream. + * + * @param format the format string + * @param args the arguments accompanying the format string + */ + public void printf(String format, Object... args) { + out.printf(LOCALE, format, args); + out.flush(); + } + + /** + * Prints a formatted string to this output stream, using the specified + * locale, format string, and arguments, and then flushes this output stream. + * + * @param locale the locale + * @param format the format string + * @param args the arguments accompanying the format string + */ + public void printf(Locale locale, String format, Object... args) { + out.printf(locale, format, args); + out.flush(); + } + + + /** + * A test client. + * + * @param args the command-line arguments + */ + public static void main(String[] args) { + Out out; + + // write to stdout + out = new Out(); + out.println("Test 1"); + out.close(); + + // write to a file + out = new Out("test.txt"); + out.println("Test 2"); + out.close(); + } + +} + +/****************************************************************************** + * Copyright 2002-2020, Robert Sedgewick and Kevin Wayne. + * + * This file is part of algs4.jar, which accompanies the textbook + * + * Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne, + * Addison-Wesley Professional, 2011, ISBN 0-321-57351-X. + * http://algs4.cs.princeton.edu + * + * + * algs4.jar is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * algs4.jar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with algs4.jar. If not, see http://www.gnu.org/licenses. + ******************************************************************************/ diff --git a/src/algs4/util/StdIn.java b/src/algs4/util/StdIn.java new file mode 100644 index 0000000..1123102 --- /dev/null +++ b/src/algs4/util/StdIn.java @@ -0,0 +1,696 @@ +/****************************************************************************** + * Compilation: javac StdIn.java + * Execution: java StdIn (interactive test of basic functionality) + * Dependencies: none + * + * Reads in data of various types from standard input. + * + ******************************************************************************/ + +package algs4.util; + +import java.util.ArrayList; +import java.util.InputMismatchException; +import java.util.Locale; +import java.util.NoSuchElementException; +import java.util.Scanner; +import java.util.regex.Pattern; + +/** + * The {@code StdIn} class provides static methods for reading strings + * and numbers from standard input. + * These functions fall into one of four categories: + *

    + *
  • those for reading individual tokens from standard input, one at a time, + * and converting each to a number, string, or boolean + *
  • those for reading characters from standard input, one at a time + *
  • those for reading lines from standard input, one at a time + *
  • those for reading a sequence of values of the same type from standard input, + * and returning the values in an array + *
+ *

+ * Generally, it is best not to mix functions from the different + * categories in the same program. + *

+ * Getting started. + * To use this class, you must have {@code StdIn.class} in your + * Java classpath. If you used our autoinstaller, you should be all set. + * Otherwise, either download + * stdlib.jar + * and add to your Java classpath or download + * StdIn.java + * and put a copy in your working directory. + *

+ * Reading tokens from standard input and converting to numbers and strings. + * You can use the following methods to read numbers, strings, and booleans + * from standard input one at a time: + *

    + *
  • {@link #isEmpty()} + *
  • {@link #readInt()} + *
  • {@link #readDouble()} + *
  • {@link #readString()} + *
  • {@link #readShort()} + *
  • {@link #readLong()} + *
  • {@link #readFloat()} + *
  • {@link #readByte()} + *
  • {@link #readBoolean()} + *
+ *

+ * The first method returns true if standard input has no more tokens. + * Each other method skips over any input that is whitespace. Then, it reads + * the next token and attempts to convert it into a value of the specified + * type. If it succeeds, it returns that value; otherwise, it + * throws an {@link InputMismatchException}. + *

+ * Whitespace includes spaces, tabs, and newlines; the full definition + * is inherited from {@link Character#isWhitespace(char)}. + * A token is a maximal sequence of non-whitespace characters. + * The precise rules for describing which tokens can be converted to + * integers and floating-point numbers are inherited from + * Scanner, + * using the locale {@link Locale#US}; the rules + * for floating-point numbers are slightly different + * from those in {@link Double#valueOf(String)}, + * but unlikely to be of concern to most programmers. + *

+ * As an example, the following code fragment reads integers from standard input, + * one at a time, and prints them one per line. + *

+ *  while (!StdIn.isEmpty()) {
+ *      double value = StdIn.readDouble();
+ *      StdOut.println(value);
+ *  }
+ *  
+ *

+ * Reading characters from standard input. + * You can use the following two methods to read characters from standard input one at a time: + *

    + *
  • {@link #hasNextChar()} + *
  • {@link #readChar()} + *
+ *

+ * The first method returns true if standard input has more input (including whitespace). + * The second method reads and returns the next character of input on standard + * input (possibly a whitespace character). + *

+ * As an example, the following code fragment reads characters from standard input, + * one character at a time, and prints it to standard output. + *

+ *  while (StdIn.hasNextChar()) {
+ *      char c = StdIn.readChar();
+ *      StdOut.print(c);
+ *  }
+ *  
+ *

+ * Reading lines from standard input. + * You can use the following two methods to read lines from standard input: + *

    + *
  • {@link #hasNextLine()} + *
  • {@link #readLine()} + *
+ *

+ * The first method returns true if standard input has more input (including whitespace). + * The second method reads and returns the remaining portion of + * the next line of input on standard input (possibly whitespace), + * discarding the trailing line separator. + *

+ * A line separator is defined to be one of the following strings: + * {@code \n} (Linux), {@code \r} (old Macintosh), + * {@code \r\n} (Windows), + * {@code \}{@code u2028}, {@code \}{@code u2029}, or {@code \}{@code u0085}. + *

+ * As an example, the following code fragment reads text from standard input, + * one line at a time, and prints it to standard output. + *

+ *  while (StdIn.hasNextLine()) {
+ *      String line = StdIn.readLine();
+ *      StdOut.println(line);
+ *  }
+ *  
+ *

+ * Reading a sequence of values of the same type from standard input. + * You can use the following methods to read a sequence numbers, strings, + * or booleans (all of the same type) from standard input: + *

    + *
  • {@link #readAllDoubles()} + *
  • {@link #readAllInts()} + *
  • {@link #readAllLongs()} + *
  • {@link #readAllStrings()} + *
  • {@link #readAllLines()} + *
  • {@link #readAll()} + *
+ *

+ * The first three methods read of all of remaining token on standard input + * and converts the tokens to values of + * the specified type, as in the corresponding + * {@code readDouble}, {@code readInt}, and {@code readString()} methods. + * The {@code readAllLines()} method reads all remaining lines on standard + * input and returns them as an array of strings. + * The {@code readAll()} method reads all remaining input on standard + * input and returns it as a string. + *

+ * As an example, the following code fragment reads all of the remaining + * tokens from standard input and returns them as an array of strings. + *

+ *  String[] words = StdIn.readAllStrings();
+ *  
+ *

+ * Differences with Scanner. + * {@code StdIn} and {@link Scanner} are both designed to parse + * tokens and convert them to primitive types and strings. + * The main differences are summarized below: + *

    + *
  • {@code StdIn} is a set of static methods and reads + * reads input from only standard input. It is suitable for use before + * a programmer knows about objects. + * See {@link In} for an object-oriented version that handles + * input from files, URLs, + * and sockets. + *
  • {@code StdIn} uses whitespace as the delimiter pattern + * that separates tokens. + * {@link Scanner} supports arbitrary delimiter patterns. + *
  • {@code StdIn} coerces the character-set encoding to UTF-8, + * which is the most widely used character encoding for Unicode. + *
  • {@code StdIn} coerces the locale to {@link Locale#US}, + * for consistency with {@link StdOut}, {@link Double#parseDouble(String)}, + * and floating-point literals. + *
  • {@code StdIn} has convenient methods for reading a single + * character; reading in sequences of integers, doubles, or strings; + * and reading in all of the remaining input. + *
+ *

+ * Historical note: {@code StdIn} preceded {@code Scanner}; when + * {@code Scanner} was introduced, this class was re-implemented to use {@code Scanner}. + *

+ * Using standard input. + * Standard input is a fundamental operating system abstraction on Mac OS X, + * Windows, and Linux. + * The methods in {@code StdIn} are blocking, which means that they + * will wait until you enter input on standard input. + * If your program has a loop that repeats until standard input is empty, + * you must signal that the input is finished. + * To do so, depending on your operating system and IDE, + * use either {@code } or {@code }, on its own line. + * If you are redirecting standard input from a file, you will not need + * to do anything to signal that the input is finished. + *

+ * Known bugs. + * Java's UTF-8 encoding does not recognize the optional + * byte-order mask. + * If the input begins with the optional byte-order mask, {@code StdIn} + * will have an extra character {@code \}{@code uFEFF} at the beginning. + *

+ * Reference. + * For additional documentation, + * see Section 1.5 of + * Computer Science: An Interdisciplinary Approach + * by Robert Sedgewick and Kevin Wayne. + * + * @author Robert Sedgewick + * @author Kevin Wayne + * @author David Pritchard + */ +public final class StdIn { + + /*** begin: section (1 of 2) of code duplicated from In to StdIn. */ + + // assume Unicode UTF-8 encoding + private static final String CHARSET_NAME = "UTF-8"; + + // assume language = English, country = US for consistency with System.out. + private static final Locale LOCALE = Locale.US; + + // the default token separator; we maintain the invariant that this value + // is held by the scanner's delimiter between calls + private static final Pattern WHITESPACE_PATTERN = Pattern.compile("\\p{javaWhitespace}+"); + + // makes whitespace significant + private static final Pattern EMPTY_PATTERN = Pattern.compile(""); + + // used to read the entire input + private static final Pattern EVERYTHING_PATTERN = Pattern.compile("\\A"); + + /*** end: section (1 of 2) of code duplicated from In to StdIn. */ + + private static Scanner scanner; + + // it doesn't make sense to instantiate this class + private StdIn() { } + + //// begin: section (2 of 2) of code duplicated from In to StdIn, + //// with all methods changed from "public" to "public static" + + /** + * Returns true if standard input is empty (except possibly for whitespace). + * Use this method to know whether the next call to {@link #readString()}, + * {@link #readDouble()}, etc will succeed. + * + * @return {@code true} if standard input is empty (except possibly + * for whitespace); {@code false} otherwise + */ + public static boolean isEmpty() { + return !scanner.hasNext(); + } + + /** + * Returns true if standard input has a next line. + * Use this method to know whether the + * next call to {@link #readLine()} will succeed. + * This method is functionally equivalent to {@link #hasNextChar()}. + * + * @return {@code true} if standard input has more input (including whitespace); + * {@code false} otherwise + */ + public static boolean hasNextLine() { + return scanner.hasNextLine(); + } + + /** + * Returns true if standard input has more input (including whitespace). + * Use this method to know whether the next call to {@link #readChar()} will succeed. + * This method is functionally equivalent to {@link #hasNextLine()}. + * + * @return {@code true} if standard input has more input (including whitespace); + * {@code false} otherwise + */ + public static boolean hasNextChar() { + scanner.useDelimiter(EMPTY_PATTERN); + boolean result = scanner.hasNext(); + scanner.useDelimiter(WHITESPACE_PATTERN); + return result; + } + + + /** + * Reads and returns the next line, excluding the line separator if present. + * + * @return the next line, excluding the line separator if present; + * {@code null} if no such line + */ + public static String readLine() { + String line; + try { + line = scanner.nextLine(); + } + catch (NoSuchElementException e) { + line = null; + } + return line; + } + + /** + * Reads and returns the next character. + * + * @return the next {@code char} + * @throws NoSuchElementException if standard input is empty + */ + public static char readChar() { + try { + scanner.useDelimiter(EMPTY_PATTERN); + String ch = scanner.next(); + assert ch.length() == 1 : "Internal (Std)In.readChar() error!" + + " Please contact the authors."; + scanner.useDelimiter(WHITESPACE_PATTERN); + return ch.charAt(0); + } + catch (NoSuchElementException e) { + throw new NoSuchElementException("attempts to read a 'char' value from standard input, " + + "but no more tokens are available"); + } + } + + + /** + * Reads and returns the remainder of the input, as a string. + * + * @return the remainder of the input, as a string + * @throws NoSuchElementException if standard input is empty + */ + public static String readAll() { + if (!scanner.hasNextLine()) + return ""; + + String result = scanner.useDelimiter(EVERYTHING_PATTERN).next(); + // not that important to reset delimeter, since now scanner is empty + scanner.useDelimiter(WHITESPACE_PATTERN); // but let's do it anyway + return result; + } + + + /** + * Reads the next token from standard input and returns it as a {@code String}. + * + * @return the next {@code String} + * @throws NoSuchElementException if standard input is empty + */ + public static String readString() { + try { + return scanner.next(); + } + catch (NoSuchElementException e) { + throw new NoSuchElementException("attempts to read a 'String' value from standard input, " + + "but no more tokens are available"); + } + } + + /** + * Reads the next token from standard input, parses it as an integer, and returns the integer. + * + * @return the next integer on standard input + * @throws NoSuchElementException if standard input is empty + * @throws InputMismatchException if the next token cannot be parsed as an {@code int} + */ + public static int readInt() { + try { + return scanner.nextInt(); + } + catch (InputMismatchException e) { + String token = scanner.next(); + throw new InputMismatchException("attempts to read an 'int' value from standard input, " + + "but the next token is \"" + token + "\""); + } + catch (NoSuchElementException e) { + throw new NoSuchElementException("attemps to read an 'int' value from standard input, " + + "but no more tokens are available"); + } + + } + + /** + * Reads the next token from standard input, parses it as a double, and returns the double. + * + * @return the next double on standard input + * @throws NoSuchElementException if standard input is empty + * @throws InputMismatchException if the next token cannot be parsed as a {@code double} + */ + public static double readDouble() { + try { + return scanner.nextDouble(); + } + catch (InputMismatchException e) { + String token = scanner.next(); + throw new InputMismatchException("attempts to read a 'double' value from standard input, " + + "but the next token is \"" + token + "\""); + } + catch (NoSuchElementException e) { + throw new NoSuchElementException("attempts to read a 'double' value from standard input, " + + "but no more tokens are available"); + } + } + + /** + * Reads the next token from standard input, parses it as a float, and returns the float. + * + * @return the next float on standard input + * @throws NoSuchElementException if standard input is empty + * @throws InputMismatchException if the next token cannot be parsed as a {@code float} + */ + public static float readFloat() { + try { + return scanner.nextFloat(); + } + catch (InputMismatchException e) { + String token = scanner.next(); + throw new InputMismatchException("attempts to read a 'float' value from standard input, " + + "but the next token is \"" + token + "\""); + } + catch (NoSuchElementException e) { + throw new NoSuchElementException("attempts to read a 'float' value from standard input, " + + "but there no more tokens are available"); + } + } + + /** + * Reads the next token from standard input, parses it as a long integer, and returns the long integer. + * + * @return the next long integer on standard input + * @throws NoSuchElementException if standard input is empty + * @throws InputMismatchException if the next token cannot be parsed as a {@code long} + */ + public static long readLong() { + try { + return scanner.nextLong(); + } + catch (InputMismatchException e) { + String token = scanner.next(); + throw new InputMismatchException("attempts to read a 'long' value from standard input, " + + "but the next token is \"" + token + "\""); + } + catch (NoSuchElementException e) { + throw new NoSuchElementException("attempts to read a 'long' value from standard input, " + + "but no more tokens are available"); + } + } + + /** + * Reads the next token from standard input, parses it as a short integer, and returns the short integer. + * + * @return the next short integer on standard input + * @throws NoSuchElementException if standard input is empty + * @throws InputMismatchException if the next token cannot be parsed as a {@code short} + */ + public static short readShort() { + try { + return scanner.nextShort(); + } + catch (InputMismatchException e) { + String token = scanner.next(); + throw new InputMismatchException("attempts to read a 'short' value from standard input, " + + "but the next token is \"" + token + "\""); + } + catch (NoSuchElementException e) { + throw new NoSuchElementException("attempts to read a 'short' value from standard input, " + + "but no more tokens are available"); + } + } + + /** + * Reads the next token from standard input, parses it as a byte, and returns the byte. + * + * @return the next byte on standard input + * @throws NoSuchElementException if standard input is empty + * @throws InputMismatchException if the next token cannot be parsed as a {@code byte} + */ + public static byte readByte() { + try { + return scanner.nextByte(); + } + catch (InputMismatchException e) { + String token = scanner.next(); + throw new InputMismatchException("attempts to read a 'byte' value from standard input, " + + "but the next token is \"" + token + "\""); + } + catch (NoSuchElementException e) { + throw new NoSuchElementException("attempts to read a 'byte' value from standard input, " + + "but no more tokens are available"); + } + } + + /** + * Reads the next token from standard input, parses it as a boolean, + * and returns the boolean. + * + * @return the next boolean on standard input + * @throws NoSuchElementException if standard input is empty + * @throws InputMismatchException if the next token cannot be parsed as a {@code boolean}: + * {@code true} or {@code 1} for true, and {@code false} or {@code 0} for false, + * ignoring case + */ + public static boolean readBoolean() { + try { + String token = readString(); + if ("true".equalsIgnoreCase(token)) return true; + if ("false".equalsIgnoreCase(token)) return false; + if ("1".equals(token)) return true; + if ("0".equals(token)) return false; + throw new InputMismatchException("attempts to read a 'boolean' value from standard input, " + + "but the next token is \"" + token + "\""); + } + catch (NoSuchElementException e) { + throw new NoSuchElementException("attempts to read a 'boolean' value from standard input, " + + "but no more tokens are available"); + } + + } + + /** + * Reads all remaining tokens from standard input and returns them as an array of strings. + * + * @return all remaining tokens on standard input, as an array of strings + */ + public static String[] readAllStrings() { + // we could use readAll.trim().split(), but that's not consistent + // because trim() uses characters 0x00..0x20 as whitespace + String[] tokens = WHITESPACE_PATTERN.split(readAll()); + if (tokens.length == 0 || tokens[0].length() > 0) + return tokens; + + // don't include first token if it is leading whitespace + String[] decapitokens = new String[tokens.length-1]; + for (int i = 0; i < tokens.length - 1; i++) + decapitokens[i] = tokens[i+1]; + return decapitokens; + } + + /** + * Reads all remaining lines from standard input and returns them as an array of strings. + * @return all remaining lines on standard input, as an array of strings + */ + public static String[] readAllLines() { + ArrayList lines = new ArrayList(); + while (hasNextLine()) { + lines.add(readLine()); + } + return lines.toArray(new String[lines.size()]); + } + + /** + * Reads all remaining tokens from standard input, parses them as integers, and returns + * them as an array of integers. + * @return all remaining integers on standard input, as an array + * @throws InputMismatchException if any token cannot be parsed as an {@code int} + */ + public static int[] readAllInts() { + String[] fields = readAllStrings(); + int[] vals = new int[fields.length]; + for (int i = 0; i < fields.length; i++) + vals[i] = Integer.parseInt(fields[i]); + return vals; + } + + /** + * Reads all remaining tokens from standard input, parses them as longs, and returns + * them as an array of longs. + * @return all remaining longs on standard input, as an array + * @throws InputMismatchException if any token cannot be parsed as a {@code long} + */ + public static long[] readAllLongs() { + String[] fields = readAllStrings(); + long[] vals = new long[fields.length]; + for (int i = 0; i < fields.length; i++) + vals[i] = Long.parseLong(fields[i]); + return vals; + } + + /** + * Reads all remaining tokens from standard input, parses them as doubles, and returns + * them as an array of doubles. + * @return all remaining doubles on standard input, as an array + * @throws InputMismatchException if any token cannot be parsed as a {@code double} + */ + public static double[] readAllDoubles() { + String[] fields = readAllStrings(); + double[] vals = new double[fields.length]; + for (int i = 0; i < fields.length; i++) + vals[i] = Double.parseDouble(fields[i]); + return vals; + } + + //// end: section (2 of 2) of code duplicated from In to StdIn + + + // do this once when StdIn is initialized + static { + resync(); + } + + /** + * If StdIn changes, use this to reinitialize the scanner. + */ + private static void resync() { + setScanner(new Scanner(new java.io.BufferedInputStream(System.in), CHARSET_NAME)); + } + + private static void setScanner(Scanner scanner) { + StdIn.scanner = scanner; + StdIn.scanner.useLocale(LOCALE); + } + + /** + * Reads all remaining tokens, parses them as integers, and returns + * them as an array of integers. + * @return all remaining integers, as an array + * @throws InputMismatchException if any token cannot be parsed as an {@code int} + * @deprecated Replaced by {@link #readAllInts()}. + */ + @Deprecated + public static int[] readInts() { + return readAllInts(); + } + + /** + * Reads all remaining tokens, parses them as doubles, and returns + * them as an array of doubles. + * @return all remaining doubles, as an array + * @throws InputMismatchException if any token cannot be parsed as a {@code double} + * @deprecated Replaced by {@link #readAllDoubles()}. + */ + @Deprecated + public static double[] readDoubles() { + return readAllDoubles(); + } + + /** + * Reads all remaining tokens and returns them as an array of strings. + * @return all remaining tokens, as an array of strings + * @deprecated Replaced by {@link #readAllStrings()}. + */ + @Deprecated + public static String[] readStrings() { + return readAllStrings(); + } + + + /** + * Interactive test of basic functionality. + * + * @param args the command-line arguments + */ + public static void main(String[] args) { + + StdOut.print("Type a string: "); + String s = StdIn.readString(); + StdOut.println("Your string was: " + s); + StdOut.println(); + + StdOut.print("Type an int: "); + int a = StdIn.readInt(); + StdOut.println("Your int was: " + a); + StdOut.println(); + + StdOut.print("Type a boolean: "); + boolean b = StdIn.readBoolean(); + StdOut.println("Your boolean was: " + b); + StdOut.println(); + + StdOut.print("Type a double: "); + double c = StdIn.readDouble(); + StdOut.println("Your double was: " + c); + StdOut.println(); + } + +} + +/****************************************************************************** + * Copyright 2002-2020, Robert Sedgewick and Kevin Wayne. + * + * This file is part of algs4.jar, which accompanies the textbook + * + * Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne, + * Addison-Wesley Professional, 2011, ISBN 0-321-57351-X. + * http://algs4.cs.princeton.edu + * + * + * algs4.jar is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * algs4.jar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with algs4.jar. If not, see http://www.gnu.org/licenses. + ******************************************************************************/ diff --git a/src/algs4/util/StdOut.java b/src/algs4/util/StdOut.java new file mode 100644 index 0000000..04cd7dc --- /dev/null +++ b/src/algs4/util/StdOut.java @@ -0,0 +1,339 @@ +/****************************************************************************** + * Compilation: javac StdOut.java + * Execution: java StdOut + * Dependencies: none + * + * Writes data of various types to standard output. + * + ******************************************************************************/ + +package algs4.util; + +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.io.UnsupportedEncodingException; +import java.util.Locale; + +/** + * This class provides methods for printing strings and numbers to standard output. + *

+ * Getting started. + * To use this class, you must have {@code StdOut.class} in your + * Java classpath. If you used our autoinstaller, you should be all set. + * Otherwise, either download + * stdlib.jar + * and add to your Java classpath or download + * StdOut.java + * and put a copy in your working directory. + *

+ * Here is an example program that uses {@code StdOut}: + *

+ *   public class TestStdOut {
+ *       public static void main(String[] args) {
+ *           int a = 17;
+ *           int b = 23;
+ *           int sum = a + b;
+ *           StdOut.println("Hello, World");
+ *           StdOut.printf("%d + %d = %d\n", a, b, sum);
+ *       }
+ *   }
+ *  
+ *

+ * Differences with System.out. + * The behavior of {@code StdOut} is similar to that of {@link System#out}, + * but there are a few technical differences: + *

    + *
  • {@code StdOut} coerces the character-set encoding to UTF-8, + * which is a standard character encoding for Unicode. + *
  • {@code StdOut} coerces the locale to {@link Locale#US}, + * for consistency with {@link StdIn}, {@link Double#parseDouble(String)}, + * and floating-point literals. + *
  • {@code StdOut} flushes standard output after each call to + * {@code print()} so that text will appear immediately in the terminal. + *
+ *

+ * Reference. + * For additional documentation, + * see Section 1.5 of + * Computer Science: An Interdisciplinary Approach + * by Robert Sedgewick and Kevin Wayne. + * + * @author Robert Sedgewick + * @author Kevin Wayne + */ +public final class StdOut { + + // force Unicode UTF-8 encoding; otherwise it's system dependent + private static final String CHARSET_NAME = "UTF-8"; + + // assume language = English, country = US for consistency with StdIn + private static final Locale LOCALE = Locale.US; + + // send output here + private static PrintWriter out; + + // this is called before invoking any methods + static { + try { + out = new PrintWriter(new OutputStreamWriter(System.out, CHARSET_NAME), true); + } + catch (UnsupportedEncodingException e) { + System.out.println(e); + } + } + + // don't instantiate + private StdOut() { } + + /** + * Terminates the current line by printing the line-separator string. + */ + public static void println() { + out.println(); + } + + /** + * Prints an object to this output stream and then terminates the line. + * + * @param x the object to print + */ + public static void println(Object x) { + out.println(x); + } + + /** + * Prints a boolean to standard output and then terminates the line. + * + * @param x the boolean to print + */ + public static void println(boolean x) { + out.println(x); + } + + /** + * Prints a character to standard output and then terminates the line. + * + * @param x the character to print + */ + public static void println(char x) { + out.println(x); + } + + /** + * Prints a double to standard output and then terminates the line. + * + * @param x the double to print + */ + public static void println(double x) { + out.println(x); + } + + /** + * Prints an integer to standard output and then terminates the line. + * + * @param x the integer to print + */ + public static void println(float x) { + out.println(x); + } + + /** + * Prints an integer to standard output and then terminates the line. + * + * @param x the integer to print + */ + public static void println(int x) { + out.println(x); + } + + /** + * Prints a long to standard output and then terminates the line. + * + * @param x the long to print + */ + public static void println(long x) { + out.println(x); + } + + /** + * Prints a short integer to standard output and then terminates the line. + * + * @param x the short to print + */ + public static void println(short x) { + out.println(x); + } + + /** + * Prints a byte to standard output and then terminates the line. + *

+ * To write binary data, see {@link BinaryStdOut}. + * + * @param x the byte to print + */ + public static void println(byte x) { + out.println(x); + } + + /** + * Flushes standard output. + */ + public static void print() { + out.flush(); + } + + /** + * Prints an object to standard output and flushes standard output. + * + * @param x the object to print + */ + public static void print(Object x) { + out.print(x); + out.flush(); + } + + /** + * Prints a boolean to standard output and flushes standard output. + * + * @param x the boolean to print + */ + public static void print(boolean x) { + out.print(x); + out.flush(); + } + + /** + * Prints a character to standard output and flushes standard output. + * + * @param x the character to print + */ + public static void print(char x) { + out.print(x); + out.flush(); + } + + /** + * Prints a double to standard output and flushes standard output. + * + * @param x the double to print + */ + public static void print(double x) { + out.print(x); + out.flush(); + } + + /** + * Prints a float to standard output and flushes standard output. + * + * @param x the float to print + */ + public static void print(float x) { + out.print(x); + out.flush(); + } + + /** + * Prints an integer to standard output and flushes standard output. + * + * @param x the integer to print + */ + public static void print(int x) { + out.print(x); + out.flush(); + } + + /** + * Prints a long integer to standard output and flushes standard output. + * + * @param x the long integer to print + */ + public static void print(long x) { + out.print(x); + out.flush(); + } + + /** + * Prints a short integer to standard output and flushes standard output. + * + * @param x the short integer to print + */ + public static void print(short x) { + out.print(x); + out.flush(); + } + + /** + * Prints a byte to standard output and flushes standard output. + * + * @param x the byte to print + */ + public static void print(byte x) { + out.print(x); + out.flush(); + } + + /** + * Prints a formatted string to standard output, using the specified format + * string and arguments, and then flushes standard output. + * + * + * @param format the format string + * @param args the arguments accompanying the format string + */ + public static void printf(String format, Object... args) { + out.printf(LOCALE, format, args); + out.flush(); + } + + /** + * Prints a formatted string to standard output, using the locale and + * the specified format string and arguments; then flushes standard output. + * + * @param locale the locale + * @param format the format string + * @param args the arguments accompanying the format string + */ + public static void printf(Locale locale, String format, Object... args) { + out.printf(locale, format, args); + out.flush(); + } + + /** + * Unit tests some of the methods in {@code StdOut}. + * + * @param args the command-line arguments + */ + public static void main(String[] args) { + + // write to stdout + StdOut.println("Test"); + StdOut.println(17); + StdOut.println(true); + StdOut.printf("%.6f\n", 1.0/7.0); + } + +} + +/****************************************************************************** + * Copyright 2002-2020, Robert Sedgewick and Kevin Wayne. + * + * This file is part of algs4.jar, which accompanies the textbook + * + * Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne, + * Addison-Wesley Professional, 2011, ISBN 0-321-57351-X. + * http://algs4.cs.princeton.edu + * + * + * algs4.jar is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * algs4.jar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with algs4.jar. If not, see http://www.gnu.org/licenses. + ******************************************************************************/ diff --git a/src/algs4/util/StdRandom.java b/src/algs4/util/StdRandom.java new file mode 100644 index 0000000..ac5c56c --- /dev/null +++ b/src/algs4/util/StdRandom.java @@ -0,0 +1,674 @@ +/****************************************************************************** + * Compilation: javac StdRandom.java + * Execution: java StdRandom + * Dependencies: StdOut.java + * + * A library of static methods to generate pseudo-random numbers from + * different distributions (bernoulli, uniform, gaussian, discrete, + * and exponential). Also includes a method for shuffling an array. + * + * + * % java StdRandom 5 + * seed = 1316600602069 + * 59 16.81826 true 8.83954 0 + * 32 91.32098 true 9.11026 0 + * 35 10.11874 true 8.95396 3 + * 92 32.88401 true 8.87089 0 + * 72 92.55791 true 9.46241 0 + * + * % java StdRandom 5 + * seed = 1316600616575 + * 96 60.17070 true 8.72821 0 + * 79 32.01607 true 8.58159 0 + * 81 59.49065 true 9.10423 1 + * 96 51.65818 true 9.02102 0 + * 99 17.55771 true 8.99762 0 + * + * % java StdRandom 5 1316600616575 + * seed = 1316600616575 + * 96 60.17070 true 8.72821 0 + * 79 32.01607 true 8.58159 0 + * 81 59.49065 true 9.10423 1 + * 96 51.65818 true 9.02102 0 + * 99 17.55771 true 8.99762 0 + * + * + * Remark + * ------ + * - Relies on randomness of nextDouble() method in java.util.Random + * to generate pseudo-random numbers in [0, 1). + * + * - This library allows you to set and get the pseudo-random number seed. + * + * - See http://www.honeylocust.com/RngPack/ for an industrial + * strength random number generator in Java. + * + ******************************************************************************/ + +package algs4.util; + +import java.util.Random; + +/** + * The {@code StdRandom} class provides static methods for generating + * random number from various discrete and continuous distributions, + * including uniform, Bernoulli, geometric, Gaussian, exponential, Pareto, + * Poisson, and Cauchy. It also provides method for shuffling an + * array or subarray and generating random permutations. + *

+ * By convention, all intervals are half open. For example, + * uniform(-1.0, 1.0) returns a random number between + * -1.0 (inclusive) and 1.0 (exclusive). + * Similarly, shuffle(a, lo, hi) shuffles the hi - lo + * elements in the array a[], starting at index lo + * (inclusive) and ending at index hi (exclusive). + *

+ * For additional documentation, + * see Section 2.2 of + * Computer Science: An Interdisciplinary Approach + * by Robert Sedgewick and Kevin Wayne. + * + * @author Robert Sedgewick + * @author Kevin Wayne + */ +public final class StdRandom { + + private static Random random; // pseudo-random number generator + private static long seed; // pseudo-random number generator seed + + // static initializer + static { + // this is how the seed was set in Java 1.4 + seed = System.currentTimeMillis(); + random = new Random(seed); + } + + // don't instantiate + private StdRandom() { } + + /** + * Sets the seed of the pseudo-random number generator. + * This method enables you to produce the same sequence of "random" + * number for each execution of the program. + * Ordinarily, you should call this method at most once per program. + * + * @param s the seed + */ + public static void setSeed(long s) { + seed = s; + random = new Random(seed); + } + + /** + * Returns the seed of the pseudo-random number generator. + * + * @return the seed + */ + public static long getSeed() { + return seed; + } + + /** + * Returns a random real number uniformly in [0, 1). + * + * @return a random real number uniformly in [0, 1) + */ + public static double uniform() { + return random.nextDouble(); + } + + /** + * Returns a random integer uniformly in [0, n). + * + * @param n number of possible integers + * @return a random integer uniformly between 0 (inclusive) and {@code n} (exclusive) + * @throws IllegalArgumentException if {@code n <= 0} + */ + public static int uniform(int n) { + if (n <= 0) throw new IllegalArgumentException("argument must be positive: " + n); + return random.nextInt(n); + } + + + /** + * Returns a random long integer uniformly in [0, n). + * + * @param n number of possible {@code long} integers + * @return a random long integer uniformly between 0 (inclusive) and {@code n} (exclusive) + * @throws IllegalArgumentException if {@code n <= 0} + */ + public static long uniform(long n) { + if (n <= 0L) throw new IllegalArgumentException("argument must be positive: " + n); + + // https://docs.oracle.com/javase/8/docs/api/java/util/Random.html#longs-long-long-long- + long r = random.nextLong(); + long m = n - 1; + + // power of two + if ((n & m) == 0L) { + return r & m; + } + + // reject over-represented candidates + long u = r >>> 1; + while (u + m - (r = u % n) < 0L) { + u = random.nextLong() >>> 1; + } + return r; + } + + /////////////////////////////////////////////////////////////////////////// + // STATIC METHODS BELOW RELY ON JAVA.UTIL.RANDOM ONLY INDIRECTLY VIA + // THE STATIC METHODS ABOVE. + /////////////////////////////////////////////////////////////////////////// + + /** + * Returns a random real number uniformly in [0, 1). + * + * @return a random real number uniformly in [0, 1) + * @deprecated Replaced by {@link #uniform()}. + */ + @Deprecated + public static double random() { + return uniform(); + } + + /** + * Returns a random integer uniformly in [a, b). + * + * @param a the left endpoint + * @param b the right endpoint + * @return a random integer uniformly in [a, b) + * @throws IllegalArgumentException if {@code b <= a} + * @throws IllegalArgumentException if {@code b - a >= Integer.MAX_VALUE} + */ + public static int uniform(int a, int b) { + if ((b <= a) || ((long) b - a >= Integer.MAX_VALUE)) { + throw new IllegalArgumentException("invalid range: [" + a + ", " + b + ")"); + } + return a + uniform(b - a); + } + + /** + * Returns a random real number uniformly in [a, b). + * + * @param a the left endpoint + * @param b the right endpoint + * @return a random real number uniformly in [a, b) + * @throws IllegalArgumentException unless {@code a < b} + */ + public static double uniform(double a, double b) { + if (!(a < b)) { + throw new IllegalArgumentException("invalid range: [" + a + ", " + b + ")"); + } + return a + uniform() * (b-a); + } + + /** + * Returns a random boolean from a Bernoulli distribution with success + * probability p. + * + * @param p the probability of returning {@code true} + * @return {@code true} with probability {@code p} and + * {@code false} with probability {@code 1 - p} + * @throws IllegalArgumentException unless {@code 0} ≤ {@code p} ≤ {@code 1.0} + */ + public static boolean bernoulli(double p) { + if (!(p >= 0.0 && p <= 1.0)) + throw new IllegalArgumentException("probability p must be between 0.0 and 1.0: " + p); + return uniform() < p; + } + + /** + * Returns a random boolean from a Bernoulli distribution with success + * probability 1/2. + * + * @return {@code true} with probability 1/2 and + * {@code false} with probability 1/2 + */ + public static boolean bernoulli() { + return bernoulli(0.5); + } + + /** + * Returns a random real number from a standard Gaussian distribution. + * + * @return a random real number from a standard Gaussian distribution + * (mean 0 and standard deviation 1). + */ + public static double gaussian() { + // use the polar form of the Box-Muller transform + double r, x, y; + do { + x = uniform(-1.0, 1.0); + y = uniform(-1.0, 1.0); + r = x*x + y*y; + } while (r >= 1 || r == 0); + return x * Math.sqrt(-2 * Math.log(r) / r); + + // Remark: y * Math.sqrt(-2 * Math.log(r) / r) + // is an independent random gaussian + } + + /** + * Returns a random real number from a Gaussian distribution with mean μ + * and standard deviation σ. + * + * @param mu the mean + * @param sigma the standard deviation + * @return a real number distributed according to the Gaussian distribution + * with mean {@code mu} and standard deviation {@code sigma} + */ + public static double gaussian(double mu, double sigma) { + return mu + sigma * gaussian(); + } + + /** + * Returns a random integer from a geometric distribution with success + * probability p. + * The integer represents the number of independent trials + * before the first success. + * + * @param p the parameter of the geometric distribution + * @return a random integer from a geometric distribution with success + * probability {@code p}; or {@code Integer.MAX_VALUE} if + * {@code p} is (nearly) equal to {@code 1.0}. + * @throws IllegalArgumentException unless {@code p >= 0.0} and {@code p <= 1.0} + */ + public static int geometric(double p) { + if (!(p >= 0)) { + throw new IllegalArgumentException("probability p must be greater than 0: " + p); + } + if (!(p <= 1.0)) { + throw new IllegalArgumentException("probability p must not be larger than 1: " + p); + } + // using algorithm given by Knuth + return (int) Math.ceil(Math.log(uniform()) / Math.log(1.0 - p)); + } + + /** + * Returns a random integer from a Poisson distribution with mean λ. + * + * @param lambda the mean of the Poisson distribution + * @return a random integer from a Poisson distribution with mean {@code lambda} + * @throws IllegalArgumentException unless {@code lambda > 0.0} and not infinite + */ + public static int poisson(double lambda) { + if (!(lambda > 0.0)) + throw new IllegalArgumentException("lambda must be positive: " + lambda); + if (Double.isInfinite(lambda)) + throw new IllegalArgumentException("lambda must not be infinite: " + lambda); + // using algorithm given by Knuth + // see http://en.wikipedia.org/wiki/Poisson_distribution + int k = 0; + double p = 1.0; + double expLambda = Math.exp(-lambda); + do { + k++; + p *= uniform(); + } while (p >= expLambda); + return k-1; + } + + /** + * Returns a random real number from the standard Pareto distribution. + * + * @return a random real number from the standard Pareto distribution + */ + public static double pareto() { + return pareto(1.0); + } + + /** + * Returns a random real number from a Pareto distribution with + * shape parameter α. + * + * @param alpha shape parameter + * @return a random real number from a Pareto distribution with shape + * parameter {@code alpha} + * @throws IllegalArgumentException unless {@code alpha > 0.0} + */ + public static double pareto(double alpha) { + if (!(alpha > 0.0)) + throw new IllegalArgumentException("alpha must be positive: " + alpha); + return Math.pow(1 - uniform(), -1.0/alpha) - 1.0; + } + + /** + * Returns a random real number from the Cauchy distribution. + * + * @return a random real number from the Cauchy distribution. + */ + public static double cauchy() { + return Math.tan(Math.PI * (uniform() - 0.5)); + } + + /** + * Returns a random integer from the specified discrete distribution. + * + * @param probabilities the probability of occurrence of each integer + * @return a random integer from a discrete distribution: + * {@code i} with probability {@code probabilities[i]} + * @throws IllegalArgumentException if {@code probabilities} is {@code null} + * @throws IllegalArgumentException if sum of array entries is not (very nearly) equal to {@code 1.0} + * @throws IllegalArgumentException unless {@code probabilities[i] >= 0.0} for each index {@code i} + */ + public static int discrete(double[] probabilities) { + if (probabilities == null) throw new IllegalArgumentException("argument array must not be null"); + double EPSILON = 1.0E-14; + double sum = 0.0; + for (int i = 0; i < probabilities.length; i++) { + if (!(probabilities[i] >= 0.0)) + throw new IllegalArgumentException("array entry " + i + " must be non-negative: " + probabilities[i]); + sum += probabilities[i]; + } + if (sum > 1.0 + EPSILON || sum < 1.0 - EPSILON) + throw new IllegalArgumentException("sum of array entries does not approximately equal 1.0: " + sum); + + // the for loop may not return a value when both r is (nearly) 1.0 and when the + // cumulative sum is less than 1.0 (as a result of floating-point roundoff error) + while (true) { + double r = uniform(); + sum = 0.0; + for (int i = 0; i < probabilities.length; i++) { + sum = sum + probabilities[i]; + if (sum > r) return i; + } + } + } + + /** + * Returns a random integer from the specified discrete distribution. + * + * @param frequencies the frequency of occurrence of each integer + * @return a random integer from a discrete distribution: + * {@code i} with probability proportional to {@code frequencies[i]} + * @throws IllegalArgumentException if {@code frequencies} is {@code null} + * @throws IllegalArgumentException if all array entries are {@code 0} + * @throws IllegalArgumentException if {@code frequencies[i]} is negative for any index {@code i} + * @throws IllegalArgumentException if sum of frequencies exceeds {@code Integer.MAX_VALUE} (231 - 1) + */ + public static int discrete(int[] frequencies) { + if (frequencies == null) throw new IllegalArgumentException("argument array must not be null"); + long sum = 0; + for (int i = 0; i < frequencies.length; i++) { + if (frequencies[i] < 0) + throw new IllegalArgumentException("array entry " + i + " must be non-negative: " + frequencies[i]); + sum += frequencies[i]; + } + if (sum == 0) + throw new IllegalArgumentException("at least one array entry must be positive"); + if (sum >= Integer.MAX_VALUE) + throw new IllegalArgumentException("sum of frequencies overflows an int"); + + // pick index i with probabilitity proportional to frequency + double r = uniform((int) sum); + sum = 0; + for (int i = 0; i < frequencies.length; i++) { + sum += frequencies[i]; + if (sum > r) return i; + } + + // can't reach here + assert false; + return -1; + } + + /** + * Returns a random real number from an exponential distribution + * with rate λ. + * + * @param lambda the rate of the exponential distribution + * @return a random real number from an exponential distribution with + * rate {@code lambda} + * @throws IllegalArgumentException unless {@code lambda > 0.0} + */ + public static double exp(double lambda) { + if (!(lambda > 0.0)) + throw new IllegalArgumentException("lambda must be positive: " + lambda); + return -Math.log(1 - uniform()) / lambda; + } + + /** + * Rearranges the elements of the specified array in uniformly random order. + * + * @param a the array to shuffle + * @throws IllegalArgumentException if {@code a} is {@code null} + */ + public static void shuffle(Object[] a) { + validateNotNull(a); + int n = a.length; + for (int i = 0; i < n; i++) { + int r = i + uniform(n-i); // between i and n-1 + Object temp = a[i]; + a[i] = a[r]; + a[r] = temp; + } + } + + /** + * Rearranges the elements of the specified array in uniformly random order. + * + * @param a the array to shuffle + * @throws IllegalArgumentException if {@code a} is {@code null} + */ + public static void shuffle(double[] a) { + validateNotNull(a); + int n = a.length; + for (int i = 0; i < n; i++) { + int r = i + uniform(n-i); // between i and n-1 + double temp = a[i]; + a[i] = a[r]; + a[r] = temp; + } + } + + /** + * Rearranges the elements of the specified array in uniformly random order. + * + * @param a the array to shuffle + * @throws IllegalArgumentException if {@code a} is {@code null} + */ + public static void shuffle(int[] a) { + validateNotNull(a); + int n = a.length; + for (int i = 0; i < n; i++) { + int r = i + uniform(n-i); // between i and n-1 + int temp = a[i]; + a[i] = a[r]; + a[r] = temp; + } + } + + /** + * Rearranges the elements of the specified array in uniformly random order. + * + * @param a the array to shuffle + * @throws IllegalArgumentException if {@code a} is {@code null} + */ + public static void shuffle(char[] a) { + validateNotNull(a); + int n = a.length; + for (int i = 0; i < n; i++) { + int r = i + uniform(n-i); // between i and n-1 + char temp = a[i]; + a[i] = a[r]; + a[r] = temp; + } + } + + /** + * Rearranges the elements of the specified subarray in uniformly random order. + * + * @param a the array to shuffle + * @param lo the left endpoint (inclusive) + * @param hi the right endpoint (exclusive) + * @throws IllegalArgumentException if {@code a} is {@code null} + * @throws IllegalArgumentException unless {@code (0 <= lo) && (lo < hi) && (hi <= a.length)} + * + */ + public static void shuffle(Object[] a, int lo, int hi) { + validateNotNull(a); + validateSubarrayIndices(lo, hi, a.length); + + for (int i = lo; i < hi; i++) { + int r = i + uniform(hi-i); // between i and hi-1 + Object temp = a[i]; + a[i] = a[r]; + a[r] = temp; + } + } + + /** + * Rearranges the elements of the specified subarray in uniformly random order. + * + * @param a the array to shuffle + * @param lo the left endpoint (inclusive) + * @param hi the right endpoint (exclusive) + * @throws IllegalArgumentException if {@code a} is {@code null} + * @throws IllegalArgumentException unless {@code (0 <= lo) && (lo < hi) && (hi <= a.length)} + */ + public static void shuffle(double[] a, int lo, int hi) { + validateNotNull(a); + validateSubarrayIndices(lo, hi, a.length); + + for (int i = lo; i < hi; i++) { + int r = i + uniform(hi-i); // between i and hi-1 + double temp = a[i]; + a[i] = a[r]; + a[r] = temp; + } + } + + /** + * Rearranges the elements of the specified subarray in uniformly random order. + * + * @param a the array to shuffle + * @param lo the left endpoint (inclusive) + * @param hi the right endpoint (exclusive) + * @throws IllegalArgumentException if {@code a} is {@code null} + * @throws IllegalArgumentException unless {@code (0 <= lo) && (lo < hi) && (hi <= a.length)} + */ + public static void shuffle(int[] a, int lo, int hi) { + validateNotNull(a); + validateSubarrayIndices(lo, hi, a.length); + + for (int i = lo; i < hi; i++) { + int r = i + uniform(hi-i); // between i and hi-1 + int temp = a[i]; + a[i] = a[r]; + a[r] = temp; + } + } + + /** + * Returns a uniformly random permutation of n elements. + * + * @param n number of elements + * @throws IllegalArgumentException if {@code n} is negative + * @return an array of length {@code n} that is a uniformly random permutation + * of {@code 0}, {@code 1}, ..., {@code n-1} + */ + public static int[] permutation(int n) { + if (n < 0) throw new IllegalArgumentException("n must be non-negative: " + n); + int[] perm = new int[n]; + for (int i = 0; i < n; i++) + perm[i] = i; + shuffle(perm); + return perm; + } + + /** + * Returns a uniformly random permutation of k of n elements. + * + * @param n number of elements + * @param k number of elements to select + * @throws IllegalArgumentException if {@code n} is negative + * @throws IllegalArgumentException unless {@code 0 <= k <= n} + * @return an array of length {@code k} that is a uniformly random permutation + * of {@code k} of the elements from {@code 0}, {@code 1}, ..., {@code n-1} + */ + public static int[] permutation(int n, int k) { + if (n < 0) throw new IllegalArgumentException("n must be non-negative: " + n); + if (k < 0 || k > n) throw new IllegalArgumentException("k must be between 0 and n: " + k); + int[] perm = new int[k]; + for (int i = 0; i < k; i++) { + int r = uniform(i+1); // between 0 and i + perm[i] = perm[r]; + perm[r] = i; + } + for (int i = k; i < n; i++) { + int r = uniform(i+1); // between 0 and i + if (r < k) perm[r] = i; + } + return perm; + } + + // throw an IllegalArgumentException if x is null + // (x can be of type Object[], double[], int[], ...) + private static void validateNotNull(Object x) { + if (x == null) { + throw new IllegalArgumentException("argument must not be null"); + } + } + + // throw an exception unless 0 <= lo <= hi <= length + private static void validateSubarrayIndices(int lo, int hi, int length) { + if (lo < 0 || hi > length || lo > hi) { + throw new IllegalArgumentException("subarray indices out of bounds: [" + lo + ", " + hi + ")"); + } + } + + /** + * Unit tests the methods in this class. + * + * @param args the command-line arguments + */ + public static void main(String[] args) { + int n = Integer.parseInt(args[0]); + if (args.length == 2) StdRandom.setSeed(Long.parseLong(args[1])); + double[] probabilities = { 0.5, 0.3, 0.1, 0.1 }; + int[] frequencies = { 5, 3, 1, 1 }; + String[] a = "A B C D E F G".split(" "); + + StdOut.println("seed = " + StdRandom.getSeed()); + for (int i = 0; i < n; i++) { + StdOut.printf("%2d ", uniform(100)); + StdOut.printf("%8.5f ", uniform(10.0, 99.0)); + StdOut.printf("%5b ", bernoulli(0.5)); + StdOut.printf("%7.5f ", gaussian(9.0, 0.2)); + StdOut.printf("%1d ", discrete(probabilities)); + StdOut.printf("%1d ", discrete(frequencies)); + StdOut.printf("%11d ", uniform(100000000000L)); + StdRandom.shuffle(a); + for (String s : a) + StdOut.print(s); + StdOut.println(); + } + } + +} + +/****************************************************************************** + * Copyright 2002-2020, Robert Sedgewick and Kevin Wayne. + * + * This file is part of algs4.jar, which accompanies the textbook + * + * Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne, + * Addison-Wesley Professional, 2011, ISBN 0-321-57351-X. + * http://algs4.cs.princeton.edu + * + * + * algs4.jar is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * algs4.jar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with algs4.jar. If not, see http://www.gnu.org/licenses. + ******************************************************************************/ diff --git a/src/algs4/util/Stopwatch.java b/src/algs4/util/Stopwatch.java new file mode 100644 index 0000000..b8d228b --- /dev/null +++ b/src/algs4/util/Stopwatch.java @@ -0,0 +1,110 @@ +/****************************************************************************** + * Compilation: javac Stopwatch.java + * Execution: java Stopwatch n + * Dependencies: none + * + * A utility class to measure the running time (wall clock) of a program. + * + * % java8 Stopwatch 100000000 + * 6.666667e+11 0.5820 seconds + * 6.666667e+11 8.4530 seconds + * + ******************************************************************************/ + +package algs4.util; + +/** + * The {@code Stopwatch} data type is for measuring + * the time that elapses between the start and end of a + * programming task (wall-clock time). + * + * See {@link StopwatchCPU} for a version that measures CPU time. + * For additional documentation, + * see Section 1.4 of + * Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne. + * + * @author Robert Sedgewick + * @author Kevin Wayne + */ + + +public class Stopwatch { + + private final long start; + + /** + * Initializes a new stopwatch. + */ + public Stopwatch() { + start = System.currentTimeMillis(); + } + + + /** + * Returns the elapsed CPU time (in seconds) since the stopwatch was created. + * + * @return elapsed CPU time (in seconds) since the stopwatch was created + */ + public double elapsedTime() { + long now = System.currentTimeMillis(); + return (now - start) / 1000.0; + } + + + /** + * Unit tests the {@code Stopwatch} data type. + * Takes a command-line argument {@code n} and computes the + * sum of the square roots of the first {@code n} positive integers, + * first using {@code Math.sqrt()}, then using {@code Math.pow()}. + * It prints to standard output the sum and the amount of time to + * compute the sum. Note that the discrete sum can be approximated by + * an integral - the sum should be approximately 2/3 * (n^(3/2) - 1). + * + * @param args the command-line arguments + */ + public static void main(String[] args) { + int n = Integer.parseInt(args[0]); + + // sum of square roots of integers from 1 to n using Math.sqrt(x). + Stopwatch timer1 = new Stopwatch(); + double sum1 = 0.0; + for (int i = 1; i <= n; i++) { + sum1 += Math.sqrt(i); + } + double time1 = timer1.elapsedTime(); + StdOut.printf("%e (%.2f seconds)\n", sum1, time1); + + // sum of square roots of integers from 1 to n using Math.pow(x, 0.5). + Stopwatch timer2 = new Stopwatch(); + double sum2 = 0.0; + for (int i = 1; i <= n; i++) { + sum2 += Math.pow(i, 0.5); + } + double time2 = timer2.elapsedTime(); + StdOut.printf("%e (%.2f seconds)\n", sum2, time2); + } +} + +/****************************************************************************** + * Copyright 2002-2020, Robert Sedgewick and Kevin Wayne. + * + * This file is part of algs4.jar, which accompanies the textbook + * + * Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne, + * Addison-Wesley Professional, 2011, ISBN 0-321-57351-X. + * http://algs4.cs.princeton.edu + * + * + * algs4.jar is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * algs4.jar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with algs4.jar. If not, see http://www.gnu.org/licenses. + ******************************************************************************/ diff --git a/src/algs4/util/StopwatchCPU.java b/src/algs4/util/StopwatchCPU.java new file mode 100644 index 0000000..4102749 --- /dev/null +++ b/src/algs4/util/StopwatchCPU.java @@ -0,0 +1,112 @@ +/****************************************************************************** + * Compilation: javac StopwatchCPU.java + * Execution: java StopwtachCPU n + * Dependencies: none + * + * A version of Stopwatch.java that measures CPU time on a single + * core or processor (instead of wall clock time). + * + * % java8 StopwatchCPU 100000000 + * 6.666667e+11 (1.05 seconds) + * 6.666667e+11 (7.50 seconds) + * + ******************************************************************************/ + +package algs4.util; + +import java.lang.management.ThreadMXBean; +import java.lang.management.ManagementFactory; + +/** + * The {@code StopwatchCPU} data type is for measuring + * the CPU time used during a programming task. + * + * See {@link Stopwatch} for a version that measures wall-clock time + * (the real time that elapses). + * + * @author Josh Hug + * @author Robert Sedgewick + * @author Kevin Wayne + */ + +public class StopwatchCPU { + private static final double NANOSECONDS_PER_SECOND = 1_000_000_000; + + private final ThreadMXBean threadTimer; + private final long start; + + /** + * Initializes a new stopwatch. + */ + public StopwatchCPU() { + threadTimer = ManagementFactory.getThreadMXBean(); + start = threadTimer.getCurrentThreadCpuTime(); + } + + /** + * Returns the elapsed CPU time (in seconds) since the stopwatch was created. + * + * @return elapsed CPU time (in seconds) since the stopwatch was created + */ + public double elapsedTime() { + long now = threadTimer.getCurrentThreadCpuTime(); + return (now - start) / NANOSECONDS_PER_SECOND; + } + + /** + * Unit tests the {@code StopwatchCPU} data type. + * Takes a command-line argument {@code n} and computes the + * sum of the square roots of the first {@code n} positive integers, + * first using {@code Math.sqrt()}, then using {@code Math.pow()}. + * It prints to standard output the sum and the amount of time to + * compute the sum. Note that the discrete sum can be approximated by + * an integral - the sum should be approximately 2/3 * (n^(3/2) - 1). + * + * @param args the command-line arguments + */ + public static void main(String[] args) { + int n = Integer.parseInt(args[0]); + + // sum of square roots of integers from 1 to n using Math.sqrt(x). + StopwatchCPU timer1 = new StopwatchCPU(); + double sum1 = 0.0; + for (int i = 1; i <= n; i++) { + sum1 += Math.sqrt(i); + } + double time1 = timer1.elapsedTime(); + StdOut.printf("%e (%.2f seconds)\n", sum1, time1); + + // sum of square roots of integers from 1 to n using Math.pow(x, 0.5). + StopwatchCPU timer2 = new StopwatchCPU(); + double sum2 = 0.0; + for (int i = 1; i <= n; i++) { + sum2 += Math.pow(i, 0.5); + } + double time2 = timer2.elapsedTime(); + StdOut.printf("%e (%.2f seconds)\n", sum2, time2); + } +} + +/****************************************************************************** + * Copyright 2002-2020, Robert Sedgewick and Kevin Wayne. + * + * This file is part of algs4.jar, which accompanies the textbook + * + * Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne, + * Addison-Wesley Professional, 2011, ISBN 0-321-57351-X. + * http://algs4.cs.princeton.edu + * + * + * algs4.jar is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * algs4.jar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with algs4.jar. If not, see http://www.gnu.org/licenses. + ******************************************************************************/ diff --git a/src/core/problem/Action.java b/src/core/problem/Action.java new file mode 100644 index 0000000..07cbd6a --- /dev/null +++ b/src/core/problem/Action.java @@ -0,0 +1,6 @@ +package core.problem; + +public abstract class Action { + public abstract void draw(); + public abstract int stepCost(); +} diff --git a/src/core/problem/Problem.java b/src/core/problem/Problem.java new file mode 100644 index 0000000..b6ac544 --- /dev/null +++ b/src/core/problem/Problem.java @@ -0,0 +1,143 @@ +package core.problem; + +import core.solver.Node; +import core.solver.heuristic.Predictor; + +import java.util.ArrayList; +import java.util.Deque; + +/** + * 所有问题的抽象超类 + * initialState + * goal + */ +public abstract class Problem { + //成员变量 + protected State initialState; + protected State goal; + protected int size; //问题的规模:15-puzzle为4;寻路问题为Grid的边长;野人传教士为野人与传教士的人数 + + public Problem(State initialState, State goal) { + this.initialState = initialState; + this.goal = goal; + } + + public Problem(State initialState, State goal, int size) { + this(initialState, goal); + this.size = size; + } + + public State getInitialState() { + return initialState; + } + + public State getGoal() { + return goal; + } + + public int getSize() { + return size; + } + + public void setSize(int size) { + this.size = size; + } + + public void setInitialState(State initialState) { + this.initialState = initialState; + } + + public void setGoal(State goal) { + this.goal = goal; + } + + /** + * 当前问题是否有解 + * @return 有解,true; 无解,false + * + */ + public abstract boolean solvable(); + + /** + * 从初始状态产生搜索树的根节点 + * @param predictor 启发函数 + * @return 当前问题的根结点 + */ + public final Node root(Predictor predictor) { + + return new Node(initialState, null, null, + 0, predictor.heuristics(initialState, goal)); + } + + /** + * 生成node的所有合法的后继结点 + * @param parent 父结点 + * @param predictor 启发函数 + * + * @return parent结点的所有子结点 + */ + public final Iterable childNodes(Node parent, Predictor predictor) { + ArrayList nodes = new ArrayList<>(); + //父结点的状态 + State parentState = parent.getState(); + //对于parentState上所有可能的action,但有的不可行 + for (Action action : parentState.actions()){ + //如果父结点状态下的动作是可行的 + if (applicable(parentState, action)){ + //得到后继状态 + State state = parentState.next(action); + //计算路径长度 = 父结点路径长度 + 进入后继状态所采取的动作的代价 + int pathCost = parent.getPathCost() + stepCost(state, action); + //使用predictor对state与goal的距离进行估值 + int heuristics = predictor.heuristics(state, goal); + //生成子结点 + Node child = new Node(state, parent, action, pathCost, heuristics); + nodes.add(child); + } + } + return nodes; + } + + /** + * + * @param state 当前状态 + * @param action 进入当前状态所采取的Action + * @return 进入当前状态的代价 + */ + public abstract int stepCost(State state, Action action); + + /** + * 在状态state上的action是否可用? + * @param state 当前状态 + * @param action 当前状态下所采用的动作 + * @return true:可用;false:不可用 + */ + protected abstract boolean applicable(State state, Action action); + + /** + * 判断某个状态state是否到达目标状态,多数情况下是判断跟目标状态是否相等。 + * + * @param state 要判断的状态 + * @return true:要判断的状态已经是目标状态;否则,false + */ + public boolean goal(State state){ + return state.equals(goal); + } + + /** + * 解路径的可视化 + * @param path 解路径 + */ + public abstract void showSolution(Deque path); + + /** + * 打印当前问题实例 + */ + public abstract void draw(); + + /** + * 打印解路径 + * @param path 解路径 + */ + public abstract void printPath(Deque path); +} diff --git a/src/core/problem/State.java b/src/core/problem/State.java new file mode 100644 index 0000000..b910910 --- /dev/null +++ b/src/core/problem/State.java @@ -0,0 +1,22 @@ +package core.problem; + +/** + * + */ +public abstract class State { + + public abstract void draw(); // 在Console上,输出该状态 + + /** + * 当前状态采用action而进入的下一个状态 + * @param action 当前状态下,一个可行的action + * @return 后继状态 + */ + public abstract State next(Action action); + + /** + * 当前状态下所有可能的Action,但不一定都可行 + * @return 所有可能的Action的可迭代集合 + */ + public abstract Iterable actions(); +} \ No newline at end of file diff --git a/src/core/runner/EngineFeeder.java b/src/core/runner/EngineFeeder.java new file mode 100644 index 0000000..03e8362 --- /dev/null +++ b/src/core/runner/EngineFeeder.java @@ -0,0 +1,85 @@ +package core.runner; + +import core.problem.Problem; +import core.problem.State; +import core.solver.Searcher; +import core.solver.heuristic.AbstractFrontier; +import core.solver.heuristic.BestFirstSearch; +import core.solver.heuristic.EvaluationType; +import core.solver.heuristic.Predictor; +import algs4.util.In; +import xu.problem.pathfinding.Position; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Scanner; +import java.util.Set; + +/** + * 为搜索算法提供各样素材。包括 + * 问题problem, + * 使用的Frontier, + * 使用的估值函数 h函数,启发式函数 + * IDA Star搜索算法的一个实现 + * + */ +public abstract class EngineFeeder { + + /** + * 从文件输入流中读入NPuzzle问题的实例 + * @param io 输入流 + * @return 文件中所有NPuzzle实例 + */ + public abstract ArrayList getProblems(In io); + public abstract ArrayList getProblems(Scanner scanner); + /** + * 生成采取某种估值机制的Frontier + * @param type 结点评估器的类型 + * @return 使用该评估机制的一个Frontier实例 + */ + public abstract AbstractFrontier getFrontier(EvaluationType type); + + /** + * 获得对状态进行估值的Predictor + * @param type 估值函数的类型 + * @return 启发函数 + */ + public abstract Predictor getPredictor(HeuristicType type); + + /** + * 生成IdaStar搜索的一个实例,用来做对比实验 + */ + public abstract Searcher getIdaStar(); + + /** + * 用来提交头歌评分的Searcher + * @return 小组目前最佳的搜索引擎 + */ + public abstract Searcher getScoreSearcher(); + + /** + * 用来做对比实验的AStar, 对所有问题都是一样的 + * 使用不同的启发函数的AStar + */ + public Searcher getAStar(HeuristicType type){ + //获取Frontier,其Node以g(n)+h(n)的升序排列 + AbstractFrontier frontier = getFrontier(EvaluationType.FULL); + //以HashSet作为Explored表 + Set explored = new HashSet<>(); + //根据explored和frontier生成AStar引擎,并使用类型为type的启发函数 + return new BestFirstSearch(explored, frontier, Position.predictor(type)); + } + + /** + * 用来做对比实验的Dijkstra,对所有的问题都是一样的 + * @return Dijkstra搜索算法 + */ + public Searcher getDijkstra(){ + //获取Frontier,其Node以g(n)+h(n)的升序排列 + AbstractFrontier frontier = getFrontier(EvaluationType.PATH_COST); + //以HashSet作为Explored表 + Set explored = new HashSet<>(); + //根据explored和frontier生成AStar引擎,并使用曼哈顿距离作为启发函数 + return new BestFirstSearch(explored, frontier, (state, goal) -> 0); + } +} diff --git a/src/core/runner/HeuristicType.java b/src/core/runner/HeuristicType.java new file mode 100644 index 0000000..f136399 --- /dev/null +++ b/src/core/runner/HeuristicType.java @@ -0,0 +1,16 @@ +package core.runner; + +public enum HeuristicType { + //Npuzzle的启发函数 + MISPLACED, // 不在位将牌 + MANHATTAN, // 曼哈顿距离 + DISJOINT_PATTERN, + + //PathFinding的启发函数 (8方向的情况) + PF_EUCLID, // 欧几里得距离 + PF_MANHATTAN, // 8方向移动时,不是admissible的 + PF_GRID, // 尽可能走对角线,然后平行走,>= EUCLID + + //野人传教士问题 + MC_HARMONY //去掉野人会吃人的约束 +} diff --git a/src/core/runner/ProblemType.java b/src/core/runner/ProblemType.java new file mode 100644 index 0000000..b9f39ed --- /dev/null +++ b/src/core/runner/ProblemType.java @@ -0,0 +1,8 @@ +package core.runner; + +public enum ProblemType { + NPUZZLE, // NPuzzle问题 + PATHFINDING, // 寻路问题 + SLIDING_BLOCKS, // 滑动积木块问题 + MISSIONARY_AND_CARNIVAL //野人传教士问题 +} diff --git a/src/core/runner/SearchRunner.java b/src/core/runner/SearchRunner.java new file mode 100644 index 0000000..fc9d0d2 --- /dev/null +++ b/src/core/runner/SearchRunner.java @@ -0,0 +1,98 @@ +package core.runner; + +import core.problem.Problem; +import core.solver.Node; +import algs4.util.In; +import core.solver.heuristic.BestFirstSearch; +import g08.problem.npuzzle.DecodeTalker; +import g08.problem.npuzzle.FeederG08; +import g08.problem.npuzzle.Npuzzle; +import xu.problem.pathfinding.FeederXu; + +import java.util.ArrayList; +import java.util.Deque; +import java.util.Scanner; + +public class SearchRunner { + + public static void xuPathfinding() + { + //从文件中读入问题的实例,寻路问题 + In problemInput = new In("resources/pathfinding.txt"); + + //生成一个具体的EngineFeeder:FeederXu,引擎饲养员徐老师:) + EngineFeeder feeder = new FeederXu(); + + //feeder从文件获取所有问题实例 + ArrayList problems = feeder.getProblems(problemInput); + + //从Feeder获取所使用的搜索引擎 AStar + BestFirstSearch astar = (BestFirstSearch) feeder.getScoreSearcher(); + + for (Problem problem : problems){ + //使用AStar引擎求解问题 + Deque path = astar.search(problem); + //解的可视化 + problem.showSolution(path); + //仅打印路径 + problem.printPath(path); + System.out.println(astar.expandedNode()); + System.out.println(); + } + + System.out.println("=============================================================="); + + //从Feeder获取所使用的搜索引擎 Dijkstra + BestFirstSearch dijkstra = (BestFirstSearch) feeder.getDijkstra(); + + for (Problem problem : problems){ + //使用AStar引擎求解问题 + Deque path = dijkstra.search(problem); + //解的可视化 + problem.showSolution(path); + //仅打印路径 + problem.printPath(path); + System.out.println(dijkstra.expandedNode()); + System.out.println(); + } + } + + public static void nPuzzle() + { + System.out.println("Npuzzle"); + + //从文件中读入问题的实例,npuzzle问题 + In problemInput = new In("resources/npuzzle.txt"); + EngineFeeder feeder = new FeederG08(); + ArrayList problems = feeder.getProblems(problemInput); + for(Problem problem:problems) + { + if(problem.solvable()) + { + System.out.println("solvable"); + DecodeTalker decodeTalker = new DecodeTalker(problem.getInitialState(),problem.getGoal()); + if(decodeTalker.ida_star()) + { + decodeTalker.draw(); + } + } + } + } + + + public static void main(String[] args) { + System.out.println("1. 寻路问题"); + System.out.println("2. Npuzzle"); + System.out.println("请输入:"); + Scanner sc = new Scanner(System.in); + int flag = sc.nextInt(); + if(flag==1) + { + xuPathfinding(); + } + else if(flag==2) + { + nPuzzle(); + } + } +} \ No newline at end of file diff --git a/src/core/solver/Node.java b/src/core/solver/Node.java new file mode 100644 index 0000000..d897f75 --- /dev/null +++ b/src/core/solver/Node.java @@ -0,0 +1,146 @@ +package core.solver; + +import core.problem.Action; +import core.problem.State; +import core.solver.heuristic.EvaluationType; +import core.solver.heuristic.Predictor; + +import java.util.Comparator; +import java.util.EnumMap; + +import static core.solver.heuristic.EvaluationType.*; + +public final class Node{ + + //不考虑路径代价的Node + + /** + * + * @param state 当前结点 + * @param parent 父结点 + * @param action 从父结点到当前结点所采取的Action + */ + public Node(State state, Node parent, Action action){ + this(state, parent, action, 0, 0); + } + + //考虑路径代价的Node + + /** + * + * @param state 当前结点 + * @param parent 父结点 + * @param action 从父结点到当前结点所采取的Action + * @param pathCost 从根结点到当前结点的耗散值 + * @param heuristic 从当前结点到目标结点的距离估计值 + */ + public Node(State state, Node parent, Action action, int pathCost, int heuristic) { + super(); + this.state = state; + this.parent = parent; + this.action = action; + this.pathCost = pathCost; + this.heuristic = heuristic; + } + + /** + * + * @param action:当前结点状态所使用的Action + * @param predictor:用于计算h值的启发函数 + * @param goal: 作为启发函数的参数,用于计算子结点状态的h值 + * @return 当前结点的子结点 + */ + public Node childNode(Action action, Predictor predictor, State goal) { + return new Node(state.next(action), this, action, + pathCost + action.stepCost(), + predictor.heuristics(state, goal)); + } + + private final State state; // the state in the state space to which the node corresponds + private final Node parent; // the node in the search tree which generated this node + + public Action getAction() { + return action; + } + + private final Action action; // the action that was applied to the parent to generate the node + private final int pathCost; // the cost of the path from the initial state to this node + private final int heuristic; // estimated cost of the cheapest path from the state of this node to a goal state + + //返回当前Node的f值 f = g + h + public int evaluation() + { + return pathCost + heuristic; + } + + public State getState() { + return state; + } + + public Node getParent() { + return parent; + } + + public int getPathCost() { + return pathCost; + } + + public int getHeuristic() { + return heuristic; + } + + /** + * Node的状态相同,即认为他们是相同的 + */ + @Override + public boolean equals(Object obj) { + if (obj == this) return true; + + if (obj instanceof Node) { + Node another = (Node) obj; + //两个Node对象的状态相同,则认为是相同的 + return this.getState().equals(another.getState()); + } + return false; + } + + public void draw() { + System.out.println(this); + } + + /** + * 不同估值函数的枚举映射表 + */ + private static final EnumMap> evaluators = new EnumMap<>(EvaluationType.class); + //枚举映射表的初始化 + static{ + //f = g + h FULL + evaluators.put(FULL, + Comparator.comparingInt(Node::evaluation) + ); + + //g PATH_COST + evaluators.put(PATH_COST, + Comparator.comparingInt(Node::getPathCost) + ); + + //h HEURISTIC + evaluators.put(HEURISTIC, + Comparator.comparingInt(Node::getHeuristic) + ); + } + + /** + * + * @param type 结点评估器的类型 + * @return 相关类型的结点评估器 + */ + public static Comparator evaluator(EvaluationType type) { + return evaluators.get(type); + } + + @Override + public String toString() { + return "[" + state.toString() + "⬅" + "[" + parent.getState().toString() + ", " + action.toString() + "], " + pathCost + ", " + heuristic + "]"; + } +} diff --git a/src/core/solver/Searcher.java b/src/core/solver/Searcher.java new file mode 100644 index 0000000..7409d39 --- /dev/null +++ b/src/core/solver/Searcher.java @@ -0,0 +1,29 @@ +package core.solver; + +import core.problem.Problem; +import java.util.ArrayDeque; +import java.util.Deque; + +public interface Searcher { + + /** + * @problem 要解决的问题 + * @return 当前问题的解路径。如果没有解,则返回null + */ + Deque search(Problem problem); + + /** + * 默认实现,从目标结点,反向回溯得到一条路径 + * @param node 目标结点 + * @return 倒推生成的从根结点到目标结点的路径,栈底是目标结点,栈顶是根结点 + */ + default Deque generatePath(Node node) { + Deque stack = new ArrayDeque<>(); + + while (node.getParent() != null) { + stack.push(node); + node = node.getParent(); + } + return stack; + } +} \ No newline at end of file diff --git a/src/core/solver/blinded/BreadthFirstSearch.java b/src/core/solver/blinded/BreadthFirstSearch.java new file mode 100644 index 0000000..1e6341a --- /dev/null +++ b/src/core/solver/blinded/BreadthFirstSearch.java @@ -0,0 +1,4 @@ +package core.solver.blinded; + +public class BreadthFirstSearch { +} diff --git a/src/core/solver/blinded/DepthFirstSearch.java b/src/core/solver/blinded/DepthFirstSearch.java new file mode 100644 index 0000000..a557779 --- /dev/null +++ b/src/core/solver/blinded/DepthFirstSearch.java @@ -0,0 +1,5 @@ +package core.solver.blinded; + +public class DepthFirstSearch { + +} diff --git a/src/core/solver/heuristic/AbstractFrontier.java b/src/core/solver/heuristic/AbstractFrontier.java new file mode 100644 index 0000000..7c5c44d --- /dev/null +++ b/src/core/solver/heuristic/AbstractFrontier.java @@ -0,0 +1,66 @@ +package core.solver.heuristic; + +import core.problem.State; +import core.solver.Node; + +import java.util.*; + +/** + * AbstractQueue的子类, + * 其存放的元素的类型为 core.solver.Node + */ +public abstract class AbstractFrontier extends AbstractQueue { + + public AbstractFrontier(Comparator evaluator) { + this.evaluator = evaluator; + } + + public Comparator getEvaluator() { + return evaluator; + } + + // 节点优先级比较器,在Node类中定义了三个不同的比较器(Dijkstra, Greedy Best-First, and Best-First) + // 不同的选择对应不同的算法。 + protected final Comparator evaluator; + + /** + * 获取 Frontier 中,状态为 s 的节点 + * @param s 状态 + * @return 存在: 相应的状态为 s 的节点; + * 不存在:null + */ + protected abstract Node getNode(State s); + + /** + * 如果Frontier中已经存在与node状态相同的结点, + * 则舍弃掉二者之间不好的那一个。 + * @param node 结点 + * @return 插入成功返回true + */ + public final boolean discardOrReplace(Node node){ + if (node == null) + throw new NullPointerException(); + + //结点node是否出现在frontier中; null: not revisited + Node oldNode = getNode(node.getState()); + //如果oldNode为null,则当前结点node的状态不在Frontier中,那么肯定在explored表中, + // 又因为h函数是consistent的,所以discard + //如果oldNode不为null,则在oldNode已经在Frontier中,并且旧的估值比新的大,即新生成的结点更好 + if (oldNode != null && evaluator.compare(oldNode, node) > 0){ + //则,用新节点替换旧节点 + replace(oldNode, node); + } + return true; + } + + /** + * 用节点 e 替换掉具有相同状态的旧节点 oldNode + * + * @param oldNode 被替换的结点 + * @param newNode 新结点 + */ + public void replace(Node oldNode, Node newNode) { + this.remove(oldNode); + this.add(newNode); + } +} diff --git a/src/core/solver/heuristic/BestFirstSearch.java b/src/core/solver/heuristic/BestFirstSearch.java new file mode 100644 index 0000000..06fe296 --- /dev/null +++ b/src/core/solver/heuristic/BestFirstSearch.java @@ -0,0 +1,78 @@ +package core.solver.heuristic; + +import java.util.*; + +import core.problem.Problem; +import core.problem.State; +import core.solver.*; + +/** + * 不能被继承的类,final类 + */ +public final class BestFirstSearch implements Searcher { + + //已经访问过的节点集合 + private final Set explored; + + //还未扩展的节点队列 + private final AbstractFrontier frontier; + + private final Predictor predictor; + /** + * 构造函数 + * @param explored 具体的状态类的Set hashSet + * @param frontier Node对象的一个优先队列,可以确定一个状态所对应的结点是否在frontier中, + */ + public BestFirstSearch(Set explored, AbstractFrontier frontier, Predictor predictor) { + this.explored = explored; + this.frontier = frontier; + this.predictor = predictor; + } + + @Override + public Deque search(Problem problem) + { + //如果可直接判断问题是否可解,无解时直接返回解路径为null + if (!problem.solvable()){ + return null; + } + frontier.clear(); + explored.clear(); + //搜索树的根节点 + Node root = problem.root(predictor); + this.frontier.add(root); + + while (true) { + + if (frontier.isEmpty()) + return null; //失败 + + Node node = frontier.poll(); //choose the lowest-cost node in frontier + //如果已经到达目标状态, + if (problem.goal(node.getState())) { + return generatePath(node); + } + //将当前结点放入explored表中 + explored.add(node.getState()); + + for (Node child : problem.childNodes(node, predictor)) { + // 如果新扩展的节点,没有在Explored和Fringe中出现过。 + // 因为两个node的状态相同,则视为二者相同(equals函数), + // 所以contains函数判断frontier中是否存在跟child的状态相同的结点 + if (!explored.contains(child.getState()) && !frontier.contains(child)) { + frontier.offer(child); + } + else { + //child出现在Explored或Fringe中 + //在启发函数满足单调条件的前提下,如果child是出现在Explored表里的节点,肯定不在Fringe中; + //而且到达这个节点的新路径肯定不会比旧路径更优 + frontier.discardOrReplace(child); + } + } + } + } + + public int expandedNode(){ + return explored.size(); + } +} \ No newline at end of file diff --git a/src/core/solver/heuristic/EvaluationType.java b/src/core/solver/heuristic/EvaluationType.java new file mode 100644 index 0000000..c95b37b --- /dev/null +++ b/src/core/solver/heuristic/EvaluationType.java @@ -0,0 +1,11 @@ +package core.solver.heuristic; + +/** + * Best-First搜索的三类不同的估值策略 + * 对所有问题都是通用的 + */ +public enum EvaluationType { + FULL, + PATH_COST, + HEURISTIC //对于不同的问题,启发策略又可能又多种。 +} diff --git a/src/core/solver/heuristic/Predictor.java b/src/core/solver/heuristic/Predictor.java new file mode 100644 index 0000000..b0749fc --- /dev/null +++ b/src/core/solver/heuristic/Predictor.java @@ -0,0 +1,18 @@ +package core.solver.heuristic; + +import core.problem.State; + +/** + * + * + */ +public interface Predictor { + /** + * + * @param + * state 被评估的状态 + * goal 目标状态 + * @return 该状态到目标状态的启发值 + */ + int heuristics(State state, State goal); +} diff --git a/src/g08/problem/npuzzle/DecodeTalker.java b/src/g08/problem/npuzzle/DecodeTalker.java new file mode 100644 index 0000000..ae37fd4 --- /dev/null +++ b/src/g08/problem/npuzzle/DecodeTalker.java @@ -0,0 +1,197 @@ +package g08.problem.npuzzle; + +import core.problem.State; + +import java.util.ArrayList; +import java.util.Stack; + +/** + * ClassName : DecodeTalker //类名 + * Description : //描述 + * Author : WLS //作者 + * Date: 2021-04-16 09:21 //时间 + */ +public class DecodeTalker { + private char dire[] = {'E','W','S','N'}; + private int dx[] = {0, 0, 1, -1}; + private int dy[] = {1, -1, 0, 0}; + private int[] curindex = new int[2]; + private Stack curs=new Stack<>(); + private int[][] inze; + private int[][] maze; + private int[][] goze; + private int size; + private Stack path=new Stack<>(); + + public DecodeTalker(State init, State goal) + { + char[] s1=init.toString().toCharArray(); + char[] s2=goal.toString().toCharArray(); + size = (int)Math.sqrt(s1.length); + maze=new int[size][size]; + goze=new int[size][size]; + inze=new int[size][size]; + int t=0; + for(int i=0;if) + return false; + for(int i=0;i<4;i++) + { + if((i^1)==prev)continue; + int x = curindex[0]+dx[i]; + int y = curindex[1]+dy[i]; + if(x<0||x>=size||y<0||y>=size)continue; + //int[] temp=curindex; + curs.push(new int[]{curindex[0], curindex[1]}); + path.push(dire[i]); + int t=maze[x][y]; + maze[x][y]=maze[curindex[0]][curindex[1]]; + maze[curindex[0]][curindex[1]]=t; + curindex[0]=x; + curindex[1]=y; + if(dfs(++g,i,f)) + { + return true; + } + curindex=curs.pop(); + int t2=maze[x][y]; + maze[x][y]=maze[curindex[0]][curindex[1]]; + maze[curindex[0]][curindex[1]]=t2; + path.pop(); + } + return false; + } + + public boolean ida_star() + { + for(int f=h();f<41;f++) + { + if(dfs(0,-1,f)) + { + return true; + } + } + return false; + } + + public void draw() + { + String S=""; + for(Character c : path) + { + S+=c; + } + System.out.println(S); + int x=0,y=0; + for(int i=0;i getProblems(In io) { + ArrayList problems = new ArrayList<>(); + while(io.hasNextLine()) + { + int size = io.readInt(); + int[][] initial = new int[size][size]; + for(int i=0;i getProblems(Scanner scanner) { + return null; + } + + @Override + public AbstractFrontier getFrontier(EvaluationType type) { + return new LinkedFrontier(Node.evaluator(type)); + } + + @Override + public Predictor getPredictor(HeuristicType type) { + return null; + } + + @Override + public Searcher getIdaStar() { + return null; + } + + @Override + public Searcher getScoreSearcher() { + return getAStar(HeuristicType.MANHATTAN); + } +} diff --git a/src/g08/problem/npuzzle/Maze.java b/src/g08/problem/npuzzle/Maze.java new file mode 100644 index 0000000..a3135ad --- /dev/null +++ b/src/g08/problem/npuzzle/Maze.java @@ -0,0 +1,65 @@ +package g08.problem.npuzzle; + +import core.problem.Action; +import core.problem.State; + +/** + * ClassName : Maze //类名 + * Description : //描述 + * Author : WLS //作者 + * Date: 2021-04-15 10:39 //时间 + */ +public class Maze extends State { + private int size; + private int[][] maze; + + public Maze(){} + + public Maze(int s, int[][] m) + { + size = s; + maze = m; + } + + public int[][] getMaze() + { + return maze; + } + + + @Override + public void draw() { + for(int i=0;i actions() { + return null; + } + + @Override + public String toString() + { + String string = ""; + for(int i=0;iinit[j]) + { + cnt++; + } + } + } + if(cnt%2==1) + { + System.out.println("unsolvable"); + return false; + } + + return true; + } + + @Override + public int stepCost(State state, Action action) { + return 0; + } + + @Override + protected boolean applicable(State state, Action action) { + return false; + } + + @Override + public void showSolution(Deque path) { + System.out.println("showSolution"); + } + + @Override + public void draw() { + initialState.draw(); + System.out.println(); + goal.draw(); + System.out.println("======================="); + } + + @Override + public void printPath(Deque path) { + System.out.println("printPath"); + } +} diff --git a/src/g08/solver/heuristic/LinkedFrontier.java b/src/g08/solver/heuristic/LinkedFrontier.java new file mode 100644 index 0000000..152a5ca --- /dev/null +++ b/src/g08/solver/heuristic/LinkedFrontier.java @@ -0,0 +1,89 @@ +package g08.solver.heuristic; + +import core.problem.State; +import core.solver.Node; +import core.solver.heuristic.AbstractFrontier; + +import java.util.Comparator; +import java.util.Iterator; +import java.util.LinkedList; + +/** + * 封装了LinkedList数据结构的Frontier + */ +public class LinkedFrontier extends AbstractFrontier { + //底层实现用的是LinkedList + private final LinkedList nodeList = new LinkedList<>(); + + public LinkedFrontier(Comparator evaluator) { + super(evaluator); + } + + /** + * 获取 Frontier 中,状态为 s 的节点 + * + * @param s 状态 + * @return 存在: 相应的状态为 s 的节点; + * 不存在:null + */ + @Override + protected Node getNode(State s) { + for (Node node: nodeList){ + if (node.getState().equals(s)){ + return node; + } + } + return null; + } + + @Override + public boolean remove(Object o) { + return nodeList.remove(o); + } + + /** + * 将结点node插入到当前有序链表中 + * @param node 要插入的结点 + * @return 插入成功返回true + */ + @Override + public boolean add(Node node) { + int j = 0; + + for (Node value : nodeList) { + if (evaluator.compare(value, node) >= 0) { + break; + } + j++; + } + + nodeList.add(j, node); + + return true; + } + + @Override + public Iterator iterator() { + return nodeList.iterator(); + } + + @Override + public int size() { + return nodeList.size(); + } + + @Override + public boolean offer(Node node) { + return this.add(node); + } + + @Override + public Node poll() { + return nodeList.poll(); + } + + @Override + public Node peek() { + return nodeList.peek(); + } +} diff --git a/src/xu/problem/pathfinding/Direction.java b/src/xu/problem/pathfinding/Direction.java new file mode 100644 index 0000000..fda99b4 --- /dev/null +++ b/src/xu/problem/pathfinding/Direction.java @@ -0,0 +1,60 @@ +package xu.problem.pathfinding; + +import java.util.EnumMap; + +public enum Direction { + N('↑'), //北 + NE('↗'), //东北 + E('→'), //东 + SE('↘'), //东南 + S('↓'), //南 + SW('↙'), //西南 + W('←'), //西 + NW('↖'); //西北 + + Direction(char symbol){ + this.symbol = symbol; + } + private final char symbol; + public char symbol(){ + return symbol; + } + + //各个方向移动的代价,直线为10,斜线为14 + private static final EnumMap DIRECTION_COST = new EnumMap<>(Direction.class); + static{ + int scale = Position.SCALE; + int diagonal = (int) (scale * Position.ROOT2); + + DIRECTION_COST.put(N, scale); + DIRECTION_COST.put(NE, diagonal); + DIRECTION_COST.put(E, scale); + DIRECTION_COST.put(SE, diagonal); + DIRECTION_COST.put(S, scale); + DIRECTION_COST.put(SW, diagonal); + DIRECTION_COST.put(W, scale); + DIRECTION_COST.put(NW, diagonal); + } + + //各个方向移动的坐标位移量 + private static final EnumMap DIRECTION_OFFSET = new EnumMap<>(Direction.class); + static{ + //列号(或横坐标)增加量;行号(或纵坐标)增加量 + DIRECTION_OFFSET.put(N, new int[]{0, -1}); + DIRECTION_OFFSET.put(NE, new int[]{1, -1}); + DIRECTION_OFFSET.put(E, new int[]{1, 0}); + DIRECTION_OFFSET.put(SE, new int[]{1, 1}); + DIRECTION_OFFSET.put(S, new int[]{0, 1}); + DIRECTION_OFFSET.put(SW, new int[]{-1, 1}); + DIRECTION_OFFSET.put(W, new int[]{-1, 0}); + DIRECTION_OFFSET.put(NW, new int[]{-1, -1}); + } + + public static int[] offset(Direction dir){ + return DIRECTION_OFFSET.get(dir); + } + + public static int cost(Direction dir){ + return DIRECTION_COST.get(dir); + } +} diff --git a/src/xu/problem/pathfinding/FeederXu.java b/src/xu/problem/pathfinding/FeederXu.java new file mode 100644 index 0000000..67d7232 --- /dev/null +++ b/src/xu/problem/pathfinding/FeederXu.java @@ -0,0 +1,109 @@ +package xu.problem.pathfinding; + +import algs4.util.In; +import core.problem.Problem; +import core.problem.State; +import core.runner.EngineFeeder; +import core.runner.HeuristicType; +import core.solver.Node; +import core.solver.Searcher; +import core.solver.heuristic.AbstractFrontier; +import core.solver.heuristic.BestFirstSearch; +import core.solver.heuristic.EvaluationType; +import core.solver.heuristic.Predictor; +import xu.solver.heuristic.LinkedFrontier; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Scanner; +import java.util.Set; + +/** + * 寻路问题的EngineFeeder + */ +public class FeederXu extends EngineFeeder { + /** + * 从文件输入流中读入NPuzzle问题的实例 + * + * @param io 输入流 + * @return 文件中所有NPuzzle实例 + */ + @Override + public ArrayList getProblems(In io) { + + ArrayList problems = new ArrayList<>(); + //地图的大小 + int size = io.readInt(); + //读入地图 + GridType[][] grids = new GridType[size][]; + for (int i = 0; i < size; i++){ + grids[i] = new GridType[size]; + for (int j = 0; j < size; j++){ + int cellType = io.readInt(); + grids[i][j] = GridType.values()[cellType]; + } + } + while (io.hasNextLine()){ + //读入初始状态 + int row = io.readInt(); + int col = io.readInt(); + Position initialState = new Position(row, col); + //读入目标状态 + row = io.readInt(); + col = io.readInt(); + Position goal = new Position(row, col); + //生成寻路问题的实例,并设置其地图 + PathFinding problem = new PathFinding(initialState, goal, size); + problem.setGrids(grids); + //添加到问题列表 + problems.add(problem); + } + return problems; + } + + @Override + public ArrayList getProblems(Scanner scanner) { + return null; + } + + /** + * 生成采取某种估值机制的Frontier + * + * @param type 结点评估器的类型 + * @return 使用该评估机制的一个Frontier实例 + */ + @Override + public AbstractFrontier getFrontier(EvaluationType type) { + return new LinkedFrontier(Node.evaluator(type)); + } + + /** + * 获得对状态进行估值的Predictor + * + * @param type 估值函数的类型 + * @return 估值函数 + */ + @Override + public Predictor getPredictor(HeuristicType type) { + return Position.predictor(type); + } + + /** + * 生成IdaStar搜索的一个实例 + */ + @Override + public Searcher getIdaStar() { + return null; + } + + /** + * 用来提交头歌评分的Searcher + * + * @return 搜索引擎 + */ + @Override + public Searcher getScoreSearcher() { + return getAStar(HeuristicType.PF_GRID); + } + +} diff --git a/src/xu/problem/pathfinding/GridType.java b/src/xu/problem/pathfinding/GridType.java new file mode 100644 index 0000000..2b7c13d --- /dev/null +++ b/src/xu/problem/pathfinding/GridType.java @@ -0,0 +1,23 @@ +package xu.problem.pathfinding; + +public enum GridType { + EMPTY('0'), // 空地 + GRASS('#'), // 草地,通过的代价高,普通代价的2倍 + //MUDDY, // 泥地,通过代价为3倍 + WALL('*'); // 石墙,无法通过 + + private final char symbol; + + GridType(char symbol){ + this.symbol = symbol; + } + + public char symbol(){ + return symbol; + } + + @Override + public String toString() { + return symbol + ""; + } +} diff --git a/src/xu/problem/pathfinding/Move.java b/src/xu/problem/pathfinding/Move.java new file mode 100644 index 0000000..348ed69 --- /dev/null +++ b/src/xu/problem/pathfinding/Move.java @@ -0,0 +1,43 @@ +package xu.problem.pathfinding; + +import core.problem.Action; + +public class Move extends Action { + + private final Direction direction; + + public Move(Direction direction) { + this.direction = direction; + } + + public Direction getDirection() { + return direction; + } + + @Override + public void draw() { + System.out.println(toString()); + } + + @Override + public int stepCost() { + return Direction.cost(direction); + } + + @Override + public String toString() { + return direction.symbol() + ""; + } + + @Override + public boolean equals(Object obj) { + if (obj == this) return true; + + if (obj instanceof Move) { + Move another = (Move) obj; + //两个Node对象的状态相同,则认为是相同的 + return this.direction.equals(another.direction); + } + return false; + } +} diff --git a/src/xu/problem/pathfinding/PathFinding.java b/src/xu/problem/pathfinding/PathFinding.java new file mode 100644 index 0000000..e3ca14c --- /dev/null +++ b/src/xu/problem/pathfinding/PathFinding.java @@ -0,0 +1,146 @@ +package xu.problem.pathfinding; + +import core.problem.Action; +import core.problem.Problem; +import core.problem.State; +import core.solver.Node; +import java.util.Deque; + +/** + * 寻路问题 + */ +public class PathFinding extends Problem { + + //地图信息 + GridType[][] grids; + + public PathFinding(State initialState, State goal) { + super(initialState, goal); + } + + public PathFinding(State initialState, State goal, int size) { + super(initialState, goal, size); + grids = new GridType[size][size]; + } + + public GridType[][] getGrids() { + return grids; + } + + public void setGrids(GridType[][] grids) { + for (int i = 0; i < size; i++){ + System.arraycopy(grids[i], 0, this.grids[i], 0, size); + } + } + + /** + * 当前问题是否有解 + * 因为只有通过搜索来判断,所以先默认为true + * @return 有解,true; 无解,false + */ + @Override + public boolean solvable() { + return true; + } + + @Override + public int stepCost(State state, Action action) { + Position position = (Position) state ; + GridType type = grids[position.getRow() - 1][position.getCol() - 1]; + if (type == GridType.EMPTY) + return action.stepCost(); + if (type == GridType.GRASS) + return action.stepCost() * 5; + return Integer.MIN_VALUE; + } + + @Override + protected boolean applicable(State state, Action action) { + int[] offsets = Direction.offset(((Move)action).getDirection()); + int row = ((Position)state).getRow() + offsets[1]; + int col = ((Position)state).getCol() + offsets[0]; + return row > 0 && row <= size && + col > 0 && col <= size && + grids[row - 1][col - 1] != GridType.WALL; + } + + @Override + public void showSolution(Deque path) { + //将地图转换为字符数组 + char[][] grids = new char[size][]; + for (int i = 0; i < size; i++){ + grids[i] = new char[size]; + for (int j = 0; j < size; j++) { + grids[i][j] = this.grids[i][j].symbol(); + } + } + //标记起点 + int row = ((Position)initialState).getRow(); + int col = ((Position)initialState).getCol(); + grids[row - 1][col - 1] = '@'; + //和终点 + row = ((Position)goal).getRow(); + col = ((Position)goal).getCol(); + grids[row - 1][col - 1] = '&'; + + //打印寻路问题。 + System.out.println(initialState + "→" + goal); + //将解路径中的动作符号写入字符数组grids + for (Node node : path) { + Position p = (Position) node.getState(); + Move move = (Move) node.getAction(); + Direction d = move.getDirection(); + grids[p.getRow() - 1][p.getCol() - 1] = d.symbol(); + } + + //打印字符数组 + drawGrid(grids); + } + + private void drawGrid(char[][] grids) { + for (int i = 0; i < size; i++){ + for (int j = 0; j < size; j++) { + System.out.print(grids[i][j] + " "); + } + System.out.println(); + } + } + + /** + * 打印当前问题的起点→终点 + * 和 地图 + */ + @Override + public void draw() { + System.out.println(initialState + "→" + goal); + for (GridType[] rows : grids){ + for (GridType type : rows){ + System.out.print(type.symbol() + " "); + } + System.out.println(); + } + } + + /** + * 打印解路径所采取的动作序列 + * @param path 解路径 + */ + @Override + public void printPath(Deque path) { + if (path == null){ + System.out.println("No Solution."); + return; + } + for (Node node : path) { + Move move = (Move) node.getAction(); + System.out.print(move.getDirection().name() + " "); + } + System.out.println(); + + } + + @Override + public String toString() { + return super.toString(); + } +} diff --git a/src/xu/problem/pathfinding/Point.java b/src/xu/problem/pathfinding/Point.java new file mode 100644 index 0000000..0507800 --- /dev/null +++ b/src/xu/problem/pathfinding/Point.java @@ -0,0 +1,107 @@ +package xu.problem.pathfinding; + +import java.util.ArrayList; +import java.util.Comparator; + +import static java.util.Comparator.*; + +public class Point implements Comparable{ + + public int getX() { + return x; + } + public void setX(int x) { + this.x = x; + } + public int getY() { + return y; + } + public void setY(int y) { + this.y = y; + } + public Point(int x, int y) { + super(); + this.x = x; + this.y = y; + } + private int x; + private int y; + @Override + public String toString() { + return "(" + x + "," + y + ")"; + } + + public static final Comparator RowColComparator = naturalOrder(); + + + @Override + public boolean equals(Object obj) { + if (obj == this) return true; + if (obj instanceof Point){ + Point p = (Point) obj; + return this.x == p.x && this.y == p.y; + } + return false; + } + + @Override + public int hashCode() { + return x << 3 | y; + } + + //根据x坐标比较 + public static final Comparator TestComparator = comparingInt(arg0 -> arg0.x); + + //根据到原点的曼哈顿距离进行比较 + public static final Comparator ManhattanComparator = comparingInt(arg0 -> arg0.manhattan(new Point(0, 0))); + + /** + * 当前点对象与参数p之间的曼哈顿距离 + * @param p 另一个点p + * @return 当前点对象与p的曼哈顿距离 + */ + public int manhattan(Point p){ + return Math.abs(this.x - p.x) + Math.abs(this.y - p.y); + } + + /** + * 当前点对象与参数p之间的欧几里得距离,取整 + * @param p 另一个点p + * @return 当前点对象与p的欧几里得距离 + */ + public double euclid(Point p){ + int x = this.x - p.x; + int y = this.y - p.y; + return Math.sqrt(x * x + y * y); + } + + /** + * 自然序,先比较横坐标,再比较纵坐标 + */ + @Override + public int compareTo(Point p) { + if (this.x == p.x) + return this.y - p.y; + + return this.x - p.x; + } + + public static void main(String[] args) { + ArrayList treeset = new ArrayList<>(); + Point p = new Point(3, 5); + treeset.add(p); + p = new Point(4, 5); + treeset.add(p); + p = new Point(2, 7); + treeset.add(p); + p = new Point(3, 7); + treeset.add(p); + p = new Point(3, 1); + treeset.add(p); + treeset.sort(ManhattanComparator); + + for (Point point : treeset) { + System.out.println(point); + } + } +} diff --git a/src/xu/problem/pathfinding/Position.java b/src/xu/problem/pathfinding/Position.java new file mode 100644 index 0000000..7a1417e --- /dev/null +++ b/src/xu/problem/pathfinding/Position.java @@ -0,0 +1,132 @@ +package xu.problem.pathfinding; + +import core.problem.Action; +import core.problem.State; +import core.runner.HeuristicType; +import core.solver.Node; +import core.solver.heuristic.Predictor; +import java.util.ArrayList; +import java.util.EnumMap; + +/** + * PathFinding问题的状态 + * 位置状态,表示寻路机器人在什么位置 + */ +public class Position extends State { + public static final int SCALE = 10; //单元格的边长 + public static final double ROOT2 = 1.4; //2的平方根 + + //可移动的方向:四个方向或者八个方向 + private static final int MOVETYPE = 1; //八个方向移动 + private static final Direction[][] directions = new Direction[2][]; + static{ + //四个方向移动 + directions[0] = new Direction[]{Direction.N, Direction.E, Direction.S, Direction.W}; + //八个方向移动 + directions[1] = Direction.values(); + } + + //机器人在场地中的位置 + private final Point point; + + public Position(int row, int col) { + this.point = new Point(row, col); + } + + @Override + public void draw() { + System.out.println(this); + } + + /** + * 当前状态采用action而进入的下一个状态 + * + * @param action 当前状态下,一个可行的action + * @return 下一个状态 + */ + @Override + public State next(Action action) { + //当前Action所带来的位移量 + Direction dir = ((Move)action).getDirection(); + int[] offsets = Direction.offset(dir); + //生成新状态所在的点 + int col = getCol() + offsets[0]; + int row = getRow() + offsets[1]; + + return new Position(row, col); + } + + @Override + public Iterable actions() { + ArrayList moves = new ArrayList<>(); + for (Direction d : directions[MOVETYPE]) + moves.add(new Move(d)); + return moves; + } + + //枚举映射,存放不同类型的启发函数 + private static final EnumMap predictors = new EnumMap<>(HeuristicType.class); + static{ + predictors.put(HeuristicType.PF_EUCLID, + (state, goal) -> ((Position)state).euclid((Position)goal)); + predictors.put(HeuristicType.PF_MANHATTAN, + (state, goal) -> ((Position)state).manhattan((Position)goal)); + predictors.put(HeuristicType.PF_GRID, + (state, goal) -> ((Position)state).gridDistance((Position)goal)); + } + public static Predictor predictor(HeuristicType type){ + return predictors.get(type); + } + + //两个点之间的Grid距离,尽量走对角线 + private int gridDistance(Position goal) { + int width = Math.abs(this.getCol() - goal.getCol()); + int height = Math.abs(this.getRow() - goal.getRow()); + if (width > height) { + return (width - height) * SCALE + height * (int) (SCALE * ROOT2); + } + else{ + return (height - width) * SCALE + width * (int) (SCALE * ROOT2); + } + } + + //两个点之间的曼哈顿距离乘以SCALE + private int manhattan(Position goal) { + return this.point.manhattan(goal.point) * SCALE; + } + + //两个点之间的欧几里德距离 + private int euclid(Position goal) { + return (int) (this.point.euclid(goal.point) * SCALE); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) return true; + + if (obj instanceof Position ) { + Position another = (Position) obj; + //两个Node对象的状态相同,则认为是相同的 + return this.point.equals(another.point); + } + return false; + } + + @Override + public int hashCode() { + return point.hashCode(); + } + + @Override + public String toString() { + return point.toString(); + } + + public int getRow() { + return point.getX(); + } + + public int getCol() { + return point.getY(); + } +} diff --git a/src/xu/solver/heuristic/LinkedFrontier.java b/src/xu/solver/heuristic/LinkedFrontier.java new file mode 100644 index 0000000..a3d862d --- /dev/null +++ b/src/xu/solver/heuristic/LinkedFrontier.java @@ -0,0 +1,89 @@ +package xu.solver.heuristic; + +import core.problem.State; +import core.solver.Node; +import core.solver.heuristic.AbstractFrontier; + +import java.util.Comparator; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.Collection; +/** + * 封装了LinkedList数据结构的Frontier + */ +public class LinkedFrontier extends AbstractFrontier { + //底层实现用的是LinkedList + private final LinkedList nodeList = new LinkedList<>(); + + public LinkedFrontier(Comparator evaluator) { + super(evaluator); + } + + /** + * 获取 Frontier 中,状态为 s 的节点 + * + * @param s 状态 + * @return 存在: 相应的状态为 s 的节点; + * 不存在:null + */ + @Override + protected Node getNode(State s) { + for (Node node: nodeList){ + if (node.getState().equals(s)){ + return node; + } + } + return null; + } + + @Override + public boolean remove(Object o) { + return nodeList.remove(o); + } + + /** + * 将结点node插入到当前有序链表中 + * @param node 要插入的结点 + * @return 插入成功返回true + */ + @Override + public boolean add(Node node) { + int j = 0; + + for (Node value : nodeList) { + if (evaluator.compare(value, node) >= 0) { + break; + } + j++; + } + + nodeList.add(j, node); + + return true; + } + + @Override + public Iterator iterator() { + return nodeList.iterator(); + } + + @Override + public int size() { + return nodeList.size(); + } + + @Override + public boolean offer(Node node) { + return this.add(node); + } + + @Override + public Node poll() { + return nodeList.poll(); + } + + @Override + public Node peek() { + return nodeList.peek(); + } +} diff --git a/test/xu/problem/pathfinding/PathFeederTest.java b/test/xu/problem/pathfinding/PathFeederTest.java new file mode 100644 index 0000000..738e16d --- /dev/null +++ b/test/xu/problem/pathfinding/PathFeederTest.java @@ -0,0 +1,29 @@ +package xu.problem.pathfinding; + +import algs4.util.In; +import core.problem.Problem; +import core.runner.EngineFeeder; +import org.junit.jupiter.api.Test; + + + +import java.util.ArrayList; + +class PathFeederTest { + + @Test + void getProblems() { + //生成一个具体的EngineFeeder:FeederXu,引擎饲养员徐老师:) + EngineFeeder feeder = new FeederXu(); + + //从文件中读入问题的实例,NPuzzle问题 + In problemInput = new In("resources/pathfinding.txt"); + //feeder从文件获取所有问题实例 + ArrayList problems = feeder.getProblems(problemInput); + + for (Problem problem : problems){ + problem.draw(); + } + + } +} \ No newline at end of file diff --git a/test/xu/problem/pathfinding/PathFindingTest.java b/test/xu/problem/pathfinding/PathFindingTest.java new file mode 100644 index 0000000..082d255 --- /dev/null +++ b/test/xu/problem/pathfinding/PathFindingTest.java @@ -0,0 +1,28 @@ +package xu.problem.pathfinding; + +import algs4.util.In; +import core.problem.Problem; +import core.runner.EngineFeeder; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; + +import static org.junit.jupiter.api.Assertions.*; + +class PathFindingTest { + + @Test + void applicable() { + //生成一个具体的EngineFeeder:FeederXu,引擎饲养员徐老师:) + EngineFeeder feeder = new FeederXu(); + + //从文件中读入问题的实例,NPuzzle问题 + In problemInput = new In("resources/pathfinding.txt"); + //feeder从文件获取所有问题实例 + ArrayList problems = feeder.getProblems(problemInput); + + Position position = new Position(7, 4); + assertFalse(((PathFinding)problems.get(0)).applicable(position, new Move(Direction.S))); + assertTrue(((PathFinding)problems.get(0)).applicable(position, new Move(Direction.E))); + } +} \ No newline at end of file diff --git a/test/xu/problem/pathfinding/PositionTest.java b/test/xu/problem/pathfinding/PositionTest.java new file mode 100644 index 0000000..f073a2c --- /dev/null +++ b/test/xu/problem/pathfinding/PositionTest.java @@ -0,0 +1,20 @@ +package xu.problem.pathfinding; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class PositionTest { + + @Test + void next() { + Position position = new Position(5, 6); + assertEquals(position.next(new Move(Direction.S)), new Position(6, 6)); + + Position next = (Position) position.next(new Move(Direction.E)); // (5,7) + assertEquals(next, new Position(5, 7)); + assertEquals(next.next(new Move(Direction.N)), new Position(4, 7)); + assertEquals(next.next(new Move(Direction.W)), new Position(5, 6)); + + } +} \ No newline at end of file diff --git a/test/xu/solver/heuristic/LinkedFrontierTest.java b/test/xu/solver/heuristic/LinkedFrontierTest.java new file mode 100644 index 0000000..f04b5bd --- /dev/null +++ b/test/xu/solver/heuristic/LinkedFrontierTest.java @@ -0,0 +1,65 @@ +package xu.solver.heuristic; + +import core.problem.State; +import core.solver.Node; +import core.solver.heuristic.EvaluationType; +import xu.problem.pathfinding.Direction; +import xu.problem.pathfinding.Move; +import xu.problem.pathfinding.Point; +import xu.problem.pathfinding.Position; + +import static org.junit.jupiter.api.Assertions.*; + +class LinkedFrontierTest { + + @org.junit.jupiter.api.Test + void offer() { + LinkedFrontier frontier = new LinkedFrontier(Node.evaluator(EvaluationType.FULL)); + State position = new Position(4, 4); + Node parent = new Node(position, null, null, 0, 15); + + position = new Position(5, 5); + Node node = new Node(position, parent, new Move(Direction.SE), 0, 15); + frontier.offer(node); + + position = new Position(5, 6); + node = new Node(position, node, new Move(Direction.S), 1, 13); + frontier.offer(node); + position = new Position(6, 6); + node = new Node(position, node, new Move(Direction.E), 2, 13); + frontier.offer(node); + position = new Position(7, 6); + node = new Node(position, node, new Move(Direction.E), 3, 9); + frontier.offer(node); + + for (Node node1: frontier){ + System.out.println(node1); + } + System.out.println(); + + position = new Position(9, 6); + node = new Node(position, node, new Move(Direction.E), 2, 13); + + System.out.println(frontier.getNode(node.getState())); + + position = new Position(6, 6); + node = new Node(position, node, new Move(Direction.W), 22, 13); + + System.out.println(frontier.contains(node)); + + System.out.println(); + + position = new Position(5, 6); + node = new Node(position, node, new Move(Direction.S), 3, 10); + frontier.discardOrReplace(node); + + for (Node node1: frontier){ + System.out.println(node1); + } + + System.out.println(); + while (!frontier.isEmpty()){ + frontier.poll().draw(); + } + } +} \ No newline at end of file