├── COPYING ├── ChangeLog.md ├── HACKING.md ├── README.md ├── data ├── germany.lua └── hills.lua ├── src ├── a_star_search.lua ├── adt_search.lua ├── best_first_search.lua ├── breadth_first_search.lua ├── depth_first_search.lua ├── depth_limited_search.lua ├── genetic_algorithm.lua ├── gradient_ascent.lua ├── greedy_search.lua ├── hill_climbing.lua ├── iterative_deepening_search.lua ├── neural_network.lua ├── recursive_best_first_search.lua ├── simulated_annealing.lua └── uniform_cost_search.lua └── test ├── op_amp ├── OP07.cir ├── op_amp.lua ├── op_amp.sch └── output.net ├── prettyplot.m ├── unit_beyond_classical_search.lua ├── unit_problem_solving_searching.lua └── xorgate.lua /COPYING: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (C) 2014-2015 A.I. Maker 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 20 | BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 21 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | 25 | -------------------------------------------------------------------------------- /ChangeLog.md: -------------------------------------------------------------------------------- 1 | 01-May-2015 Alexandre Trilla 2 | 3 | * src/neural_network.lua: train. 4 | * src/neural_network.lua: 1e-6 J diff. 5 | * test/orgate.lua: created. 6 | 7 | 8 | 28-Apr-2015 Alexandre Trilla 9 | 10 | * src/neural_network.lua: predict vector iface. 11 | 12 | 13 | 27-Apr-2015 Alexandre Trilla 14 | 15 | * src/neural_network.lua: created. Init and prediction. 16 | 17 | 18 | 03-Apr-2015 Alexandre Trilla 19 | 20 | * src/gradient_ascent.lua: created. 21 | * test/unit_beyond_classical_search.lua 22 | 23 | 24 | 17-Mar-2015 Alexandre Trilla 25 | 26 | * test/op_amp/op_amp.lua: created. 27 | 28 | 29 | 14-Mar-2015 Alexandre Trilla 30 | 31 | * test/trt_amp.lua: created. 32 | 33 | 34 | 07-Mar-2015 Alexandre Trilla 35 | 36 | * src/genetic_algorithm.lua (sort_population): use table.sort. 37 | * test/unit_beyond_classical_search.lua 38 | 39 | 40 | 05-Mar-2015 Alexandre Trilla 41 | 42 | * src/genetic_algorithm.lua: created. 43 | * test/unit_beyond_classical_search.lua 44 | 45 | * src/a_star_search.lua: local funcitons. 46 | * src/breadth_first_search.lua 47 | * src/depth_first_search.lua 48 | * src/depth_limited_search.lua 49 | * src/greedy_search.lua 50 | * src/hill_climbing.lua 51 | * src/recursive_best_first_search.lua 52 | * src/uniform_cost_search.lua 53 | * test/unit_beyond_classical_search.lua 54 | 55 | 56 | 25-Feb-2015 Alexandre Trilla 57 | 58 | * src/simulated_annealing.lua: created. 59 | * test/unit_beyond_classical_search.lua 60 | 61 | 62 | 21-Feb-2015 Alexandre Trilla 63 | 64 | * test/unit_problem_solving_searching.lua: asserts. 65 | 66 | 67 | 20-Feb-2015 Alexandre Trilla 68 | 69 | * src/hill_climbing.lua: created. 70 | * test/unit_beyond_classical_search.lua 71 | 72 | 73 | 18-Feb-2015 Alexandre Trilla 74 | 75 | * src/recursive_best_first_search.lua: created. 76 | * test/unit_problem_solving_searching.lua 77 | 78 | 79 | 16-Feb-2015 Alexandre Trilla 80 | 81 | * src/greedy_search.lua: translated. 82 | * test/unit_problem_solving_searching.lua 83 | 84 | * src/a_star_search.lua: translated. 85 | * test/unit_problem_solving_searching.lua 86 | 87 | 88 | 15-Feb-2015 Alexandre Trilla 89 | 90 | * src/iterative_deepening_search.lua: translated. 91 | * test/unit_problem_solving_searching.lua 92 | 93 | 94 | 14-Feb-2015 Alexandre Trilla 95 | 96 | * src/depth_limited_search.lua: translated. 97 | * test/unit_problem_solving_searching.lua 98 | 99 | 100 | 12-Feb-2015 Alexandre Trilla 101 | 102 | * src/best_first_search.lua: translated from Octave. 103 | * src/depth_first_search.lua 104 | * src/uniform_cost_search.lua 105 | * test/unit_problem_solving_searching.lua 106 | 107 | 108 | 11-Feb-2015 Alexandre Trilla 109 | 110 | * src/adt_search.lua: former adt_search.m 111 | * src/breadth_first_search.lua 112 | * test/unit_breadth_first_search.lua 113 | 114 | 115 | 09-Feb-2015 Alexandre Trilla 116 | 117 | * src/breadth_first_search.m: included ins_fifo. 118 | 119 | * src/depth_first_search.m: included ins_lifo. 120 | 121 | * src/depth_limited_search.m: included recursive_dls. 122 | 123 | 124 | 31-Jan-2015 Alexandre Trilla 125 | 126 | * src/best_first_search.m: cost is vector: path and heuristic. 127 | * src/uniform_cost_search.m 128 | * src/greedy_search.m 129 | * src/a_star_search.m 130 | 131 | 132 | 30-Jan-2015 Alexandre Trilla 133 | 134 | * src/best_first_search.m: created. Based on UCS. 135 | * src/uniform_cost_search.m 136 | 137 | * src/greedy_search: created. 138 | 139 | * src/a_star_search.m: created. 140 | 141 | 142 | 26-Jan-2015 Alexandre Trilla 143 | 144 | * src/iterative_deepening_search.m: created. 145 | 146 | 147 | 18-Jan-2015 Alexandre Trilla 148 | 149 | * src/depth_first_search.m: use adt_search. 150 | * src/ins_lifo.m: created. 151 | 152 | 153 | 17-Jan-2015 Alexandre Trilla 154 | 155 | * src/adt_search.m : former adt_first_search.m. 156 | * src/breadth_first_search.m 157 | 158 | 159 | 13-Jan-2015 Alexandre Trilla 160 | 161 | * src/breadth_first_search.m: tree/graph algorithm versions. 162 | Coding style. 163 | * src/adt_first_search.m: created. Based on former BFS. 164 | * src/ins_fifo.m: created. 165 | 166 | * src/uniform_cost_search.m: tree/graph algorithm versions. 167 | Coding style. 168 | 169 | 170 | 07-Jan-2015 Alexandre Trilla 171 | 172 | * src/depth_limited_search.m: created. 173 | * src/recursive_dls.m 174 | 175 | * src/depth_first_search.m: created. 176 | 177 | * src/breadth_first_search.m: return failure state. 178 | 179 | * src/uniform_cost_search.m: return failure state. 180 | 181 | 182 | 04-Jan-2015 Alexandre Trilla 183 | 184 | * src/uniform_cost_search.m: created. 185 | 186 | 187 | 03-Jan-2015 Alexandre Trilla 188 | 189 | * src/breadth_first_search.m: coding style. 190 | 191 | 192 | 02-Jan-2015 Alexandre Trilla 193 | 194 | * src/breadth_first_search.m: created. 195 | 196 | * test/prettyplot.m: former ut file. 197 | 198 | 199 | 26-Dec-2014 Alexandre Trilla 200 | 201 | * src/ut_prettyplot.m: created. 202 | 203 | -------------------------------------------------------------------------------- /HACKING.md: -------------------------------------------------------------------------------- 1 | Hacking 2 | ======= 3 | 4 | File organisation 5 | ----------------- 6 | The file organisation of the open-source release of AIMA is shown as 7 | follows: 8 | 9 | * src: AIMA function library folder. 10 | + Search 11 | 12 | * test: unit testing folder. 13 | + Utility 14 | 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | AIMA - Artificial Intelligence, A Maker's Approach 2 | ================================================== 3 | 4 | The AIMA project develops open-source software for Artificial 5 | Intelligence. 6 | 7 | The AIMA software toolkit is a framework that facilitates the 8 | creation and evaluation of bespoke Artificial Intelligence (AI) 9 | functions. It is designed to be flexible and adaptable, covering the 10 | whole spectrum of required tasks from feature engineering to machine 11 | learning. 12 | 13 | 14 | Mission 15 | ------- 16 | To provide an open-source implementation of Russell and Norvig's 17 | "Artificial Intelligence, A Modern Approach" book as the main 18 | reference guide (hence the name of the project). 19 | 20 | 21 | Features 22 | -------- 23 | All algorithms described in the book (planned). 24 | 25 | 26 | Requirements 27 | ------------ 28 | Lua 5.2 29 | 30 | 31 | Development status 32 | ------------------ 33 | See TODO, CHANGES and ChangeLog. 34 | 35 | 36 | Bug tracking 37 | ------------ 38 | See FIXME. 39 | 40 | 41 | Developer guidelines 42 | -------------------- 43 | See INSTALL and HACKING. 44 | 45 | 46 | Documentation 47 | ------------- 48 | Embedded in the code. Use "help" command. FAQ, website and mailing list 49 | may be created if many users/developers join the project. 50 | 51 | In the meantime, for any comment or suggestion of any kind, please 52 | contact Alexandre Trilla . 53 | 54 | -------------------------------------------------------------------------------- /data/germany.lua: -------------------------------------------------------------------------------- 1 | -- Data based on the breadth-first search article on Wikipedia 2 | -- http://en.wikipedia.org/wiki/Breadth-first_search 3 | 4 | local _problem = {{0, 85, 217, 0, 0, 0, 0, 0, 0, 173}, 5 | {85, 0, 0, 0, 80, 0, 0, 0, 0, 0}, 6 | {217, 0, 0, 0, 0, 186, 103, 0, 0, 0}, 7 | {0, 0, 0, 0, 0, 0, 183, 0, 0, 0}, 8 | {0, 80, 0, 0, 0, 0, 0, 250, 0, 0}, 9 | {0, 0, 186, 0, 0, 0, 0, 0, 0, 0}, 10 | {0, 0, 103, 183, 0, 0, 0, 0, 167, 0}, 11 | {0, 0, 0, 0, 250, 0, 0, 0, 84, 0}, 12 | {0, 0, 0, 0, 0, 0, 167, 84, 0, 502}, 13 | {173, 0, 0, 0, 0, 0, 0, 0, 502, 0}} 14 | 15 | local _state = {Frankfurt = 1, 16 | Mannheim = 2, 17 | Wurzburg = 3, 18 | Stuttgart = 4, 19 | Karlsruhe = 5, 20 | Erfurt = 6, 21 | Nurnberg = 7, 22 | Ausburg = 8, 23 | Munchen = 9, 24 | Kassel = 10} 25 | 26 | return {problem = _problem, state = _state} 27 | 28 | -------------------------------------------------------------------------------- /data/hills.lua: -------------------------------------------------------------------------------- 1 | -- Data based on sinc(1.9:0.1:5.9) 2 | -- To be used for local search. 3 | 4 | return {-0.05177008647807719, -3.898171832519375e-17, 0.04683960205159358, 0.08504448034442179, 0.1119643945218444, 0.1261377881067762, 0.1273239544735163, 0.1164348813293319, 0.09537707681490445, 0.06682066312775996, 0.03391833252011936, 3.898171832519375e-17, -0.03173005300269242, -0.05846808023678991, -0.07803579012128542, -0.08903843866360674, -0.09094568176679733, -0.0840918587378508, -0.0695994884865519, -0.04923627809413893, -0.02522132418162723, -3.898171832519375e-17, 0.02399101568496267, 0.04454710875183993, 0.05988793195354462, 0.06880242987642339, 0.0707355302630646, 0.06581101988179623, 0.05479108668090257, 0.03897872015785989, 0.02007411516496862, 3.898171832519376e-17, -0.01928689496242097, -0.03598035706879377, -0.04858832215098909, -0.05606123915856718, -0.05787452476068922, -0.05405905204576122, -0.04517861533337574, -0.03225825116512535, -0.01667172276412648} 5 | 6 | -------------------------------------------------------------------------------- /src/a_star_search.lua: -------------------------------------------------------------------------------- 1 | ---------------------------------------------------------------------- 2 | -- File : a_star_search.lua 3 | -- Created : 16-Feb-2015 4 | -- By : Alexandre Trilla 5 | -- 6 | -- AIMA - Artificial Intelligence, A Maker's Approach 7 | -- 8 | -- Copyright (C) 2015 A.I. Maker 9 | ---------------------------------------------------------------------- 10 | -- 11 | -- This file is part of AIMA. 12 | -- 13 | -- AIMA is free software: you can redistribute it and/or modify it 14 | -- under the terms of the MIT/X11 License as published by the 15 | -- Massachusetts Institute of Technology. See the MIT/X11 License 16 | -- for more details. 17 | -- 18 | -- You should have received a copy of the MIT/X11 License along with 19 | -- this source code distribution of AIMA (see the COPYING file in the 20 | -- root directory). If not, see 21 | -- . 22 | ---------------------------------------------------------------------- 23 | 24 | -- A-star search algorithm. 25 | -- 26 | -- PRE: 27 | -- problem - must be the cost-weighted adjacency matrix (table). 28 | -- start - must be the starting node index (number). 29 | -- finish - must be the finishing node index (number). 30 | -- treegraph - must be the tree/graph version flag (boolean). 31 | -- True for graph search version. 32 | -- heuristic - heuristic vector (table). 33 | -- 34 | -- POST: 35 | -- solution - is the solution path. State set to zero if failure. 36 | 37 | 38 | require("best_first_search") 39 | 40 | local function eval_heuristic(cost) 41 | return cost[1] + cost[2] 42 | end 43 | 44 | function a_star_search(problem, start, finish, treegraph, heuristic) 45 | -- eval func returns heuristic + cost 46 | return best_first_search(problem, start, finish, treegraph, 47 | eval_heuristic, heuristic) 48 | end 49 | 50 | -------------------------------------------------------------------------------- /src/adt_search.lua: -------------------------------------------------------------------------------- 1 | ---------------------------------------------------------------------- 2 | -- File : adt_search.lua 3 | -- Created : 11-Feb-2015 4 | -- By : Alexandre Trilla 5 | -- 6 | -- AIMA - Artificial Intelligence, A Maker's Approach 7 | -- 8 | -- Copyright (C) 2015 A.I. Maker 9 | ---------------------------------------------------------------------- 10 | -- 11 | -- This file is part of AIMA. 12 | -- 13 | -- AIMA is free software: you can redistribute it and/or modify it 14 | -- under the terms of the MIT/X11 License as published by the 15 | -- Massachusetts Institute of Technology. See the MIT/X11 License 16 | -- for more details. 17 | -- 18 | -- You should have received a copy of the MIT/X11 License along with 19 | -- this source code distribution of AIMA (see the COPYING file in the 20 | -- root directory). If not, see 21 | -- . 22 | ---------------------------------------------------------------------- 23 | 24 | -- Abstract data type search algorithm. 25 | -- 26 | -- PRE: 27 | -- problem - cost-weighted adjacency matrix (table). 28 | -- start - starting node index (number). 29 | -- finish - finishing node index (number). 30 | -- treegraph - tree/graph version flag (boolean). 31 | -- True for graph search version. 32 | -- insert - function to manage the insertion into the frontier. 33 | -- 34 | -- POST: 35 | -- solution - solution path (table). State set to zero if failure. 36 | -- 37 | -- It is convenient to state the problem as an adjacency matrix 38 | -- because state references must be directly accessed. 39 | 40 | 41 | function adt_search(problem, start, finish, treegraph, insert) 42 | -- inits 43 | local node = {} 44 | node.state = start 45 | node.parent = {} 46 | node.cost = 0 47 | local solution = {} 48 | -- 49 | if (node.state == finish) then 50 | solution = node 51 | else 52 | local frontier = {node} 53 | local explored = {} 54 | local found = false 55 | while (not found) do 56 | if (#frontier == 0) then 57 | solution.state = 0 58 | found = true 59 | break 60 | end 61 | -- pop frontier 62 | node = frontier[1] 63 | table.remove(frontier, 1) 64 | -- explore 65 | if (treegraph) then 66 | table.insert(explored, node.state) 67 | end 68 | for i = 1, #problem do 69 | if (problem[node.state][i] > 0) then 70 | if (i ~= node.state) then 71 | -- by default, continue exploration 72 | local notExpl = true 73 | if (treegraph) then 74 | for j = 1, #explored do 75 | if (explored[j] == i) then 76 | notExpl = false 77 | break 78 | end 79 | end 80 | end 81 | if (notExpl) then 82 | inFront = false 83 | for j = 1, #frontier do 84 | if (frontier[j].state == i) then 85 | inFront = true 86 | break 87 | end 88 | end 89 | if (not inFront) then 90 | -- expand search space 91 | local child = {state = i} 92 | local path = {} 93 | for j = 1, #node.parent do 94 | table.insert(path, node.parent[j]) 95 | end 96 | table.insert(path, node.state) 97 | child.parent = path 98 | child.cost = node.cost + problem[node.state][i] 99 | -- check goal 100 | if (i == finish) then 101 | solution = child 102 | found = true 103 | break 104 | else 105 | insert(frontier, child) 106 | end 107 | end 108 | end 109 | end 110 | end 111 | end 112 | end 113 | end 114 | return solution 115 | end 116 | 117 | -------------------------------------------------------------------------------- /src/best_first_search.lua: -------------------------------------------------------------------------------- 1 | ---------------------------------------------------------------------- 2 | -- File : best_first_search.lua 3 | -- Created : 12-Feb-2015 4 | -- By : Alexandre Trilla 5 | -- 6 | -- AIMA - Artificial Intelligence, A Maker's Approach 7 | -- 8 | -- Copyright (C) 2015 A.I. Maker 9 | ---------------------------------------------------------------------- 10 | -- 11 | -- This file is part of AIMA. 12 | -- 13 | -- AIMA is free software: you can redistribute it and/or modify it 14 | -- under the terms of the MIT/X11 License as published by the 15 | -- Massachusetts Institute of Technology. See the MIT/X11 License 16 | -- for more details. 17 | -- 18 | -- You should have received a copy of the MIT/X11 License along with 19 | -- this source code distribution of AIMA (see the COPYING file in the 20 | -- root directory). If not, see 21 | -- . 22 | ---------------------------------------------------------------------- 23 | 24 | -- Best-first search algorithm. 25 | -- 26 | -- PRE: 27 | -- problem - cost-weighted adjacency matrix (table). 28 | -- start - starting node index (number). 29 | -- finish - finishing node index (number). 30 | -- treegraph - tree/graph version flag (boolean). 31 | -- True for graph search version. 32 | -- feval - evaluation function. 33 | -- heuristic - must be a heuristic at the node level (table). 34 | -- 35 | -- POST: 36 | -- solution - solution path (table). State set to zero if failure. 37 | -- 38 | -- In this implementation, cost is a vector: 39 | -- {path_cost, heuristic_cost}. 40 | 41 | 42 | function best_first_search(problem, start, finish, treegraph, feval, 43 | heuristic) 44 | -- inits 45 | local node = {} 46 | node.state = start 47 | node.parent = {} 48 | node.cost = {0, heuristic[start]} 49 | local solution = {} 50 | -- 51 | if (node.state == finish) then 52 | solution = node 53 | else 54 | local frontier = {node} 55 | local explored = {} 56 | local found = false 57 | while (not found) do 58 | if (#frontier == 0) then 59 | solution.state = 0 60 | found = true 61 | break 62 | end 63 | -- pop frontier, lowest cost node 64 | testNode = frontier[1] 65 | testIdx = 1 66 | for i = 2, #frontier do 67 | if (feval(frontier[i].cost) < feval(testNode.cost)) then 68 | testNode = frontier[i] 69 | testIdx = i 70 | end 71 | end 72 | table.remove(frontier, testIdx) 73 | node = testNode 74 | -- check 75 | if (node.state == finish) then 76 | solution = node 77 | break 78 | end 79 | -- explore 80 | if (treegraph) then 81 | table.insert(explored, node.state) 82 | end 83 | for i = 1, #problem do 84 | if (problem[node.state][i] > 0) then 85 | if (i ~= node.state) then 86 | local child = {state = i} 87 | local path = {} 88 | for j = 1, #node.parent do 89 | table.insert(path, node.parent[j]) 90 | end 91 | table.insert(path, node.state) 92 | child.parent = path 93 | child.cost = {node.cost[1] + problem[node.state][i], 94 | heuristic[i]} 95 | -- by default, continue exploration 96 | local notExpl = true 97 | if (treegraph) then 98 | for j = 1, #explored do 99 | if (explored[j] == i) then 100 | notExpl = false 101 | break 102 | end 103 | end 104 | end 105 | if (notExpl) then 106 | inFront = false 107 | for j = 1, #frontier do 108 | if (frontier[j].state == i) then 109 | inFront = true 110 | if (feval(frontier[j].cost) > feval(child.cost)) 111 | then 112 | frontier[j] = child 113 | end 114 | break 115 | end 116 | end 117 | if (not inFront) then 118 | table.insert(frontier, child) 119 | end 120 | end 121 | end 122 | end 123 | end 124 | end 125 | end 126 | return solution 127 | end 128 | 129 | -------------------------------------------------------------------------------- /src/breadth_first_search.lua: -------------------------------------------------------------------------------- 1 | ---------------------------------------------------------------------- 2 | -- File : breadth_first_search.lua 3 | -- Created : 11-Feb-2015 4 | -- By : Alexandre Trilla 5 | -- 6 | -- AIMA - Artificial Intelligence, A Maker's Approach 7 | -- 8 | -- Copyright (C) 2015 A.I. Maker 9 | ---------------------------------------------------------------------- 10 | -- 11 | -- This file is part of AIMA. 12 | -- 13 | -- AIMA is free software: you can redistribute it and/or modify it 14 | -- under the terms of the MIT/X11 License as published by the 15 | -- Massachusetts Institute of Technology. See the MIT/X11 License 16 | -- for more details. 17 | -- 18 | -- You should have received a copy of the MIT/X11 License along with 19 | -- this source code distribution of AIMA (see the COPYING file in the 20 | -- root directory). If not, see 21 | -- . 22 | ---------------------------------------------------------------------- 23 | 24 | -- Breadth-first search algorithm. 25 | -- 26 | -- PRE: 27 | -- problem - must be the cost-weighted adjacency matrix (table). 28 | -- start - must be the starting node index (number). 29 | -- finish - must be the finishing node index (number). 30 | -- treegraph - must be the tree/graph version flag (boolean). 31 | -- True for graph search version. 32 | -- 33 | -- POST: 34 | -- solution - is the solution path. State set to zero if failure. 35 | 36 | 37 | require("adt_search") 38 | 39 | local function ins_fifo(frontier, node) 40 | table.insert(frontier, node) 41 | end 42 | 43 | function breadth_first_search(problem, start, finish, treegraph) 44 | return adt_search(problem, start, finish, treegraph, ins_fifo) 45 | end 46 | 47 | -------------------------------------------------------------------------------- /src/depth_first_search.lua: -------------------------------------------------------------------------------- 1 | ---------------------------------------------------------------------- 2 | -- File : depth_first_search.lua 3 | -- Created : 12-Feb-2015 4 | -- By : Alexandre Trilla 5 | -- 6 | -- AIMA - Artificial Intelligence, A Maker's Approach 7 | -- 8 | -- Copyright (C) 2015 A.I. Maker 9 | ---------------------------------------------------------------------- 10 | -- 11 | -- This file is part of AIMA. 12 | -- 13 | -- AIMA is free software: you can redistribute it and/or modify it 14 | -- under the terms of the MIT/X11 License as published by the 15 | -- Massachusetts Institute of Technology. See the MIT/X11 License 16 | -- for more details. 17 | -- 18 | -- You should have received a copy of the MIT/X11 License along with 19 | -- this source code distribution of AIMA (see the COPYING file in the 20 | -- root directory). If not, see 21 | -- . 22 | ---------------------------------------------------------------------- 23 | 24 | -- Depth-first search algorithm. 25 | -- 26 | -- PRE: 27 | -- problem - cost-weighted adjacency matrix (table). 28 | -- start - starting node index (number). 29 | -- finish - finishing node index (number). 30 | -- treegraph - tree/graph version flag (boolean). 31 | -- True for graph search version. 32 | -- 33 | -- POST: 34 | -- solution - solution path (table). State set to zero if failure. 35 | 36 | 37 | require("adt_search") 38 | 39 | local function ins_lifo(frontier, node) 40 | table.insert(frontier, 1, node) 41 | end 42 | 43 | function depth_first_search(problem, start, finish, treegraph) 44 | return adt_search(problem, start, finish, treegraph, ins_lifo) 45 | end 46 | 47 | -------------------------------------------------------------------------------- /src/depth_limited_search.lua: -------------------------------------------------------------------------------- 1 | ---------------------------------------------------------------------- 2 | -- File : depth_limited_search.lua 3 | -- Created : 14-Feb-2015 4 | -- By : Alexandre Trilla 5 | -- 6 | -- AIMA - Artificial Intelligence, A Maker's Approach 7 | -- 8 | -- Copyright (C) 2015 A.I. Maker 9 | ---------------------------------------------------------------------- 10 | -- 11 | -- This file is part of AIMA. 12 | -- 13 | -- AIMA is free software: you can redistribute it and/or modify it 14 | -- under the terms of the MIT/X11 License as published by the 15 | -- Massachusetts Institute of Technology. See the MIT/X11 License 16 | -- for more details. 17 | -- 18 | -- You should have received a copy of the MIT/X11 License along with 19 | -- this source code distribution of AIMA (see the COPYING file in the 20 | -- root directory). If not, see 21 | -- . 22 | ---------------------------------------------------------------------- 23 | 24 | -- Recursive implementation of the depth-limited tree search 25 | -- algorithm. 26 | -- 27 | -- PRE: 28 | -- problem - cost-weighted adjacency matrix (table). 29 | -- start - starting node index (number). 30 | -- finish - finishing node index (number). 31 | -- limit - depth limit (number). 32 | -- 33 | -- POST: 34 | -- solution - solution path (table). State set to zero if standard 35 | -- failure (no solution). Minus one if cutoff failure (no solution 36 | -- within the depth limit). 37 | 38 | 39 | local function recursive_dls(node, problem, finish, limit) 40 | local solution = {} 41 | if (node.state == finish) then 42 | return node 43 | elseif (limit == 0) then 44 | solution.state = -1 45 | return solution 46 | else 47 | local cutoff = false 48 | for i = 1, #problem do 49 | if (problem[node.state][i] > 0) then 50 | if (i ~= node.state) then 51 | -- expand search space 52 | local child = {state = i} 53 | local path = {} 54 | for j = 1, #node.parent do 55 | table.insert(path, node.parent[j]) 56 | end 57 | table.insert(path, node.state) 58 | child.parent = path 59 | child.cost = node.cost + problem[node.state][i] 60 | local result = recursive_dls(child, problem, finish, 61 | limit - 1) 62 | if (result.state == -1) then 63 | cutoff = true 64 | elseif (result.state ~= 0) then 65 | return result 66 | end 67 | end 68 | end 69 | end 70 | if (cutoff) then 71 | solution.state = -1 72 | else 73 | solution.state = 0 74 | end 75 | return solution 76 | end 77 | end 78 | 79 | function depth_limited_search(problem, start, finish, limit) 80 | -- inits 81 | local node = {} 82 | node.state = start 83 | node.parent = {} 84 | node.cost = 0 85 | return recursive_dls(node, problem, finish, limit) 86 | end 87 | 88 | -------------------------------------------------------------------------------- /src/genetic_algorithm.lua: -------------------------------------------------------------------------------- 1 | ---------------------------------------------------------------------- 2 | -- File : genetic_algorithm.lua 3 | -- Created : 05-Mar-2015 4 | -- By : Alexandre Trilla 5 | -- 6 | -- AIMA - Artificial Intelligence, A Maker's Approach 7 | -- 8 | -- Copyright (C) 2015 A.I. Maker 9 | ---------------------------------------------------------------------- 10 | -- 11 | -- This file is part of AIMA. 12 | -- 13 | -- AIMA is free software: you can redistribute it and/or modify it 14 | -- under the terms of the MIT/X11 License as published by the 15 | -- Massachusetts Institute of Technology. See the MIT/X11 License 16 | -- for more details. 17 | -- 18 | -- You should have received a copy of the MIT/X11 License along with 19 | -- this source code distribution of AIMA (see the COPYING file in the 20 | -- root directory). If not, see 21 | -- . 22 | ---------------------------------------------------------------------- 23 | 24 | -- Genetic algorithm. 25 | -- 26 | -- PRE: 27 | -- population - set of individuals (table). 28 | -- fitness - evaluate individual (function). 29 | -- 30 | -- POST: 31 | -- solution - solution state (table). 32 | -- 33 | -- Each individual (state) is a binary array. 34 | -- Population is ordered from best to worst according to fitness. It 35 | -- must be greater than one. 36 | -- Fitness is normalised from 0 (bad) to 1 (good). 37 | 38 | 39 | local function sort_population(population, fitness) 40 | local function comp(x, y) 41 | return (fitness(x) < fitness(y)) 42 | end 43 | return table.sort(population, comp) 44 | end 45 | 46 | local function random_selection(population, fitness) 47 | local fit = {} 48 | local sumfit = 0 49 | for i = 1, #population do 50 | local fitIndi = fitness(population[i]) 51 | table.insert(fit, fitIndi) 52 | sumfit = sumfit + fitIndi 53 | end 54 | fit[1] = fit[1] / sumfit 55 | for i = 2, #fit do 56 | fit[i] = fit[i] / sumfit + fit[i-1] 57 | end 58 | local x, y 59 | local rx = math.random() 60 | local ry = math.random() 61 | for i = 1, #fit do 62 | if (rx < fit[i]) then 63 | x = population[i] 64 | break 65 | end 66 | end 67 | for i = 1, #fit do 68 | if (ry < fit[i]) then 69 | y = population[i] 70 | break 71 | end 72 | end 73 | return x, y 74 | end 75 | 76 | local function reproduce(x, y) 77 | local point = math.floor(math.random() * #x) + 1 78 | local child = {} 79 | for i = 1, point do 80 | child[i] = x[i] 81 | end 82 | for i = point + 1, #x do 83 | child[i] = y[i] 84 | end 85 | return child 86 | end 87 | 88 | local function mutate(x) 89 | for i = 1, #x do 90 | if (math.random() < 0.1) then 91 | x[i] = math.abs(x[i] - 1) 92 | end 93 | end 94 | end 95 | 96 | function genetic_algorithm(population, fitness) 97 | local solution 98 | for epoch = 1, 100 do 99 | sort_population(population, fitness) 100 | local new_population = {} 101 | for i = 1, #population do 102 | local x, y = random_selection(population, fitness) 103 | local child = reproduce(x, y) 104 | if (math.random() < 0.05) then 105 | mutate(child) 106 | end 107 | table.insert(new_population, child) 108 | end 109 | population = new_population 110 | end 111 | return population[1] 112 | end 113 | 114 | -------------------------------------------------------------------------------- /src/gradient_ascent.lua: -------------------------------------------------------------------------------- 1 | ---------------------------------------------------------------------- 2 | -- File : gradient_ascent.lua 3 | -- Created : 03-Apr-2015 4 | -- By : Alexandre Trilla 5 | -- 6 | -- AIMA - Artificial Intelligence, A Maker's Approach 7 | -- 8 | -- Copyright (C) 2015 A.I. Maker 9 | ---------------------------------------------------------------------- 10 | -- 11 | -- This file is part of AIMA. 12 | -- 13 | -- AIMA is free software: you can redistribute it and/or modify it 14 | -- under the terms of the MIT/X11 License as published by the 15 | -- Massachusetts Institute of Technology. See the MIT/X11 License 16 | -- for more details. 17 | -- 18 | -- You should have received a copy of the MIT/X11 License along with 19 | -- this source code distribution of AIMA (see the COPYING file in the 20 | -- root directory). If not, see 21 | -- . 22 | ---------------------------------------------------------------------- 23 | 24 | -- Gradient ascent algorithm. 25 | -- 26 | -- PRE: 27 | -- objfun - objective funciton to maximise (funciton). 28 | -- var - variables, starting point vector (table). 29 | -- step - step size (number). 30 | -- 31 | -- POST: 32 | -- Updates var with the max of objfun. 33 | -- 34 | -- Loop while evaluation increases. 35 | 36 | 37 | function gradient_ascent(objfun, var, step) 38 | local epsilon = 1e-4 39 | local feval = objfun(var) 40 | local grad = {} 41 | for i = 1, #var do 42 | table.insert(grad, 0) 43 | end 44 | local newvar = {} 45 | for i = 1, #var do 46 | table.insert(newvar, 0) 47 | end 48 | while (true) do 49 | local preveval = feval 50 | -- calc grad 51 | for i = 1, #var do 52 | local value = var[i] 53 | var[i] = value + epsilon 54 | local right = objfun(var) 55 | var[i] = value - epsilon 56 | local left = objfun(var) 57 | var[i] = value 58 | grad[i] = (right - left) / (2 * epsilon) 59 | end 60 | -- new var 61 | for i = 1, #var do 62 | newvar[i] = var[i] + step * grad[i] 63 | end 64 | -- eval 65 | feval = objfun(newvar) 66 | print(feval) 67 | if ((feval - preveval) > 1e-6) then 68 | -- update var 69 | for i = 1, #var do 70 | var[i] = newvar[i] 71 | end 72 | else 73 | break 74 | end 75 | end 76 | end 77 | 78 | -------------------------------------------------------------------------------- /src/greedy_search.lua: -------------------------------------------------------------------------------- 1 | ---------------------------------------------------------------------- 2 | -- File : greedy_search.lua 3 | -- Created : 16-Feb-2015 4 | -- By : Alexandre Trilla 5 | -- 6 | -- AIMA - Artificial Intelligence, A Maker's Approach 7 | -- 8 | -- Copyright (C) 2015 A.I. Maker 9 | ---------------------------------------------------------------------- 10 | -- 11 | -- This file is part of AIMA. 12 | -- 13 | -- AIMA is free software: you can redistribute it and/or modify it 14 | -- under the terms of the MIT/X11 License as published by the 15 | -- Massachusetts Institute of Technology. See the MIT/X11 License 16 | -- for more details. 17 | -- 18 | -- You should have received a copy of the MIT/X11 License along with 19 | -- this source code distribution of AIMA (see the COPYING file in the 20 | -- root directory). If not, see 21 | -- . 22 | ---------------------------------------------------------------------- 23 | 24 | -- Greedy search algorithm. 25 | -- 26 | -- PRE: 27 | -- problem - must be the cost-weighted adjacency matrix (table). 28 | -- start - must be the starting node index (number). 29 | -- finish - must be the finishing node index (number). 30 | -- treegraph - must be the tree/graph version flag (boolean). 31 | -- True for graph search version. 32 | -- heuristic - heuristic vector (table). 33 | -- 34 | -- POST: 35 | -- solution - is the solution path. State set to zero if failure. 36 | 37 | 38 | require("best_first_search") 39 | 40 | local function eval_heuristic(cost) 41 | return cost[2] 42 | end 43 | 44 | function greedy_search(problem, start, finish, treegraph, heuristic) 45 | -- eval func returns heuristic only 46 | return best_first_search(problem, start, finish, treegraph, 47 | eval_heuristic, heuristic) 48 | end 49 | 50 | -------------------------------------------------------------------------------- /src/hill_climbing.lua: -------------------------------------------------------------------------------- 1 | ---------------------------------------------------------------------- 2 | -- File : hill_climbing.lua 3 | -- Created : 20-Feb-2015 4 | -- By : Alexandre Trilla 5 | -- 6 | -- AIMA - Artificial Intelligence, A Maker's Approach 7 | -- 8 | -- Copyright (C) 2015 A.I. Maker 9 | ---------------------------------------------------------------------- 10 | -- 11 | -- This file is part of AIMA. 12 | -- 13 | -- AIMA is free software: you can redistribute it and/or modify it 14 | -- under the terms of the MIT/X11 License as published by the 15 | -- Massachusetts Institute of Technology. See the MIT/X11 License 16 | -- for more details. 17 | -- 18 | -- You should have received a copy of the MIT/X11 License along with 19 | -- this source code distribution of AIMA (see the COPYING file in the 20 | -- root directory). If not, see 21 | -- . 22 | ---------------------------------------------------------------------- 23 | 24 | -- Hill climbing algorithm. 25 | -- 26 | -- PRE: 27 | -- problem - must be an array of costs, index indicates state (table). 28 | -- start - must be the starting state index (number). 29 | -- 30 | -- POST: 31 | -- solution - is the solution state (number). 32 | 33 | 34 | local function eval_left(problem, current) 35 | if (problem[current - 1] > problem[current]) then 36 | return current - 1, true 37 | else 38 | return current, false 39 | end 40 | end 41 | 42 | local function eval_right(problem, current) 43 | if (problem[current + 1] > problem[current]) then 44 | return current + 1, true 45 | else 46 | return current, false 47 | end 48 | end 49 | 50 | function hill_climbing(problem, start) 51 | local current = start 52 | local neighbour 53 | local change 54 | while (true) do 55 | if (current == 1) then 56 | neighbour, change = eval_right(problem, current) 57 | elseif (current == #problem) then 58 | neighbour, change = eval_left(problem, current) 59 | else 60 | neighbour, change = eval_left(problem, current) 61 | if (change == false) then 62 | neighbour, change = eval_right(problem, current) 63 | end 64 | end 65 | if (change) then 66 | current = neighbour 67 | else 68 | return current 69 | end 70 | end 71 | end 72 | 73 | -------------------------------------------------------------------------------- /src/iterative_deepening_search.lua: -------------------------------------------------------------------------------- 1 | ---------------------------------------------------------------------- 2 | -- File : iterative_deepening_search.lua 3 | -- Created : 15-Feb-2015 4 | -- By : Alexandre Trilla 5 | -- 6 | -- AIMA - Artificial Intelligence, A Maker's Approach 7 | -- 8 | -- Copyright (C) 2015 A.I. Maker 9 | ---------------------------------------------------------------------- 10 | -- 11 | -- This file is part of AIMA. 12 | -- 13 | -- AIMA is free software: you can redistribute it and/or modify it 14 | -- under the terms of the MIT/X11 License as published by the 15 | -- Massachusetts Institute of Technology. See the MIT/X11 License 16 | -- for more details. 17 | -- 18 | -- You should have received a copy of the MIT/X11 License along with 19 | -- this source code distribution of AIMA (see the COPYING file in the 20 | -- root directory). If not, see 21 | -- . 22 | ---------------------------------------------------------------------- 23 | 24 | -- Iterative-deepening search algorithm. 25 | -- 26 | -- PRE: 27 | -- problem - must be the cost-weighted adjacency matrix (table). 28 | -- start - must be the starting node index (number). 29 | -- finish - must be the finishing node index (number). 30 | -- 31 | -- POST: 32 | -- solution - is the solution path. State set to zero if failure. 33 | 34 | 35 | require("depth_limited_search") 36 | 37 | function iterative_deepening_search(problem, start, finish) 38 | local limit = 1 39 | while (true) do 40 | local solution = 41 | depth_limited_search(problem, start, finish, limit) 42 | limit = limit + 1 43 | if (solution.state ~= -1) then 44 | return solution 45 | end 46 | end 47 | end 48 | 49 | -------------------------------------------------------------------------------- /src/neural_network.lua: -------------------------------------------------------------------------------- 1 | ---------------------------------------------------------------------- 2 | -- File : neural_network.lua 3 | -- Created : 26-Apr-2015 4 | -- By : Alexandre Trilla 5 | -- 6 | -- AIMA - Artificial Intelligence, A Maker's Approach 7 | -- 8 | -- Copyright (C) 2015 A.I. Maker 9 | ---------------------------------------------------------------------- 10 | -- 11 | -- This file is part of AIMA. 12 | -- 13 | -- AIMA is free software: you can redistribute it and/or modify it 14 | -- under the terms of the MIT/X11 License as published by the 15 | -- Massachusetts Institute of Technology. See the MIT/X11 License 16 | -- for more details. 17 | -- 18 | -- You should have received a copy of the MIT/X11 License along with 19 | -- this source code distribution of AIMA (see the COPYING file in the 20 | -- root directory). If not, see 21 | -- . 22 | ---------------------------------------------------------------------- 23 | 24 | -- Artificial neural network class (multilayer perceptron model). 25 | -- 26 | -- Activation function is assumed to be sigmoid. 27 | -- Tikhonov regularisation is set to 1. 28 | 29 | 30 | ann = {} 31 | 32 | 33 | -- PRE: 34 | -- IN - size of input layer (number). 35 | -- HID - size of hidden layer (number). 36 | -- OUT - size of output layer (number). 37 | -- 38 | -- POST: 39 | -- Returns an instance of an ANN (table). 40 | 41 | function ann:new(IN, HID, OUT) 42 | local newann = {Lin = IN, Lhid = HID, Lout = OUT} 43 | self.__index = self 44 | setmetatable(newann, self) 45 | newann:initw() 46 | return newann 47 | end 48 | 49 | 50 | -- POST: 51 | -- Initialises the model (the thetas). 52 | 53 | function ann:initw() 54 | local epsilonIN = math.sqrt(6) / math.sqrt(self.Lin + self.Lhid) 55 | local epsilonOUT = math.sqrt(6) / math.sqrt(self.Lhid + self.Lout) 56 | -- 57 | local function initmat(din, dout, value) 58 | math.randomseed(os.time()) 59 | local mat = {} 60 | for i = 1, dout do 61 | local aux = {} 62 | for j = 1, din do 63 | table.insert(aux, ((math.random() - 0.5) / 0.5 ) * value) 64 | end 65 | table.insert(mat, aux) 66 | end 67 | return mat 68 | end 69 | -- 70 | self.thetain = initmat(self.Lin + 1, self.Lhid, epsilonIN) 71 | self.thetaout = initmat(self.Lhid + 1, self.Lout, epsilonOUT) 72 | end 73 | 74 | 75 | -- PRE: 76 | -- input - feat [1,N] vector (table). 77 | -- 78 | -- POST: 79 | -- Returns output [1,K] vector (table). 80 | 81 | function ann:predict(input) 82 | local function matprod(m1, m2) 83 | local result = {} 84 | -- init 85 | for i = 1, #m1 do 86 | local row = {} 87 | for j = 1, #m2[1] do 88 | table.insert(row, 0) 89 | end 90 | table.insert(result, row) 91 | end 92 | -- multiply 93 | for i = 1, #m1 do 94 | for j = 1, #m2[1] do 95 | local prod = 0 96 | for k = 1, #m1[1] do 97 | prod = prod + m1[i][k] * m2[k][j] 98 | end 99 | result[i][j] = prod 100 | end 101 | end 102 | return result 103 | end 104 | -- 105 | local function sigmoid(x) 106 | local y = 1 / (1 + math.exp(-x)) 107 | return y 108 | end 109 | -- input must be a column [N,1] vector (table). 110 | -- step 1 111 | local aIN = {{1}} 112 | for i = 1, #input do 113 | table.insert(aIN, {input[i]}) 114 | end 115 | -- step 2 116 | local zHID = matprod(self.thetain, aIN) 117 | local aHID = {{1}} 118 | for i = 1, #zHID do 119 | table.insert(aHID, {sigmoid(zHID[i][1])}) 120 | end 121 | -- step 3 122 | local azOUT = matprod(self.thetaout, aHID) 123 | for i = 1, #azOUT do 124 | azOUT[i][1] = sigmoid(azOUT[i][1]) 125 | end 126 | local flatOUT = {} 127 | for i = 1, #azOUT do 128 | table.insert(flatOUT, azOUT[i][1]) 129 | end 130 | return flatOUT 131 | end 132 | 133 | 134 | -- PRE: 135 | -- feat - list of example feature vectors (table). 136 | -- targ - list of target value vectors (table). 137 | -- 138 | -- POST: 139 | -- Fits the neural network params to the given data. 140 | -- Returns training error (number). 141 | 142 | function ann:train(feat, targ) 143 | require("gradient_ascent") 144 | local function saveThetas() 145 | local thetas = {} 146 | -- theta in 147 | for i = 1, self.Lhid do 148 | for j = 1, (self.Lin + 1) do 149 | table.insert(thetas, self.thetain[i][j]) 150 | end 151 | end 152 | -- theta out 153 | for i = 1, self.Lout do 154 | for j = 1, (self.Lhid + 1) do 155 | table.insert(thetas, self.thetaout[i][j]) 156 | end 157 | end 158 | return thetas 159 | end 160 | local function loadThetas(thetas) 161 | -- theta in 162 | local index = 1 163 | for i = 1, self.Lhid do 164 | for j = 1, (self.Lin + 1) do 165 | self.thetain[i][j] = thetas[index] 166 | index = index + 1 167 | end 168 | end 169 | -- theta out 170 | for i = 1, self.Lout do 171 | for j = 1, (self.Lhid + 1) do 172 | self.thetaout[i][j] = thetas[index] 173 | index = index + 1 174 | end 175 | end 176 | end 177 | local function cost(thetas) 178 | local sqerr, pr 179 | local J = 0 180 | loadThetas(thetas) 181 | for m = 1, #feat do 182 | pr = self:predict(feat[m]) 183 | sqerr = 0 184 | for k = 1, #pr do 185 | sqerr = sqerr + math.pow(targ[m][k] - pr[k], 2) 186 | end 187 | J = J + sqerr 188 | end 189 | J = J / #feat 190 | -- Regularisation 191 | local R = 0 192 | for i = 1, #self.thetain do 193 | for j = 2, #self.thetain[1] do 194 | R = R + math.pow(self.thetain[i][j], 2) 195 | end 196 | end 197 | for i = 1, #self.thetaout do 198 | for j = 2, #self.thetaout[1] do 199 | R = R + math.pow(self.thetaout[i][j], 2) 200 | end 201 | end 202 | R = R * (0.01 / (self.Lin*self.Lhid + self.Lhid*self.Lout)) 203 | return -(J + R) 204 | end 205 | -- flatten thetas 206 | local flatTheta = saveThetas() 207 | gradient_ascent(cost, flatTheta, 1) 208 | -- deflat theta, restore model 209 | trerr = cost(flatTheta) 210 | loadThetas(flatTheta) 211 | -- return training err 212 | return trerr 213 | end 214 | 215 | -------------------------------------------------------------------------------- /src/recursive_best_first_search.lua: -------------------------------------------------------------------------------- 1 | ---------------------------------------------------------------------- 2 | -- File : recursive_best_first_search.lua 3 | -- Created : 18-Feb-2015 4 | -- By : Alexandre Trilla 5 | -- 6 | -- AIMA - Artificial Intelligence, A Maker's Approach 7 | -- 8 | -- Copyright (C) 2015 A.I. Maker 9 | ---------------------------------------------------------------------- 10 | -- 11 | -- This file is part of AIMA. 12 | -- 13 | -- AIMA is free software: you can redistribute it and/or modify it 14 | -- under the terms of the MIT/X11 License as published by the 15 | -- Massachusetts Institute of Technology. See the MIT/X11 License 16 | -- for more details. 17 | -- 18 | -- You should have received a copy of the MIT/X11 License along with 19 | -- this source code distribution of AIMA (see the COPYING file in the 20 | -- root directory). If not, see 21 | -- . 22 | ---------------------------------------------------------------------- 23 | 24 | -- Recursive best-first search algorithm. 25 | -- 26 | -- PRE: 27 | -- problem - cost-weighted adjacency matrix (table). 28 | -- start - starting node index (number). 29 | -- finish - finishing node index (number). 30 | -- heuristic - must be a heuristic at the node level (table). 31 | -- 32 | -- POST: 33 | -- solution - solution path (table). State set to zero if failure. 34 | -- 35 | -- In this implementation, cost is a vector: 36 | -- {path_cost, heuristic_cost}. 37 | 38 | 39 | local function rbfs(problem, node, finish, heuristic, flimit) 40 | if (node.state == finish) then 41 | return node 42 | else 43 | local successors = {} 44 | -- for each action in problem given state... 45 | for i = 1, #problem do 46 | if (problem[node.state][i] > 0) then 47 | if (i ~= node.state) then 48 | local child = {state = i} 49 | local path = {} 50 | for j = 1, #node.parent do 51 | table.insert(path, node.parent[j]) 52 | end 53 | table.insert(path, node.state) 54 | child.parent = path 55 | child.cost = {node.cost[1] + problem[node.state][i], 56 | heuristic[i]} 57 | table.insert(successors, child) 58 | end 59 | end 60 | end 61 | if (#successors == 0) then 62 | return {state = 0} 63 | end 64 | while (true) do 65 | -- 1st and 2nd lowest fval in successors 66 | local best = successors[1] 67 | local alternative = best 68 | if (#successors > 1) then 69 | alternative = successors[2] 70 | if ((best.cost[1] + best.cost[2]) > 71 | (alternative.cost[1] + alternative.cost[2])) then 72 | best, alternative = alternative, best 73 | end 74 | for i = 3, #successors do 75 | -- check best 76 | if ((successors[i].cost[1] + successors[i].cost[2]) < 77 | (best.cost[1] + best.cost[2])) then 78 | alternative = best 79 | best = successors[i] 80 | elseif ((successors[i].cost[1] + successors[i].cost[2]) < 81 | (alternative.cost[1] + alternative.cost[2])) then 82 | alternative = successors[i] 83 | end 84 | end 85 | end 86 | local bestf = best.cost[1] + best.cost[2] 87 | local alternativef = alternative.cost[1] + alternative.cost[2] 88 | local result 89 | if (bestf < flimit) then 90 | result = rbfs(problem, best, finish, heuristic, 91 | math.min(flimit, alternativef)) 92 | else 93 | node.cost[1] = best.cost[1] 94 | node.cost[2] = best.cost[2] 95 | return {state = 0} 96 | end 97 | if (result.state ~= 0) then 98 | return result 99 | end 100 | end 101 | end 102 | end 103 | 104 | function recursive_best_first_search(problem, start, finish, 105 | heuristic) 106 | -- inits 107 | local node = {} 108 | node.state = start 109 | node.parent = {} 110 | node.cost = {0, heuristic[start]} 111 | return rbfs(problem, node, finish, heuristic, math.huge) 112 | end 113 | 114 | -------------------------------------------------------------------------------- /src/simulated_annealing.lua: -------------------------------------------------------------------------------- 1 | ---------------------------------------------------------------------- 2 | -- File : simulated_annealing.lua 3 | -- Created : 25-Feb-2015 4 | -- By : Alexandre Trilla 5 | -- 6 | -- AIMA - Artificial Intelligence, A Maker's Approach 7 | -- 8 | -- Copyright (C) 2015 A.I. Maker 9 | ---------------------------------------------------------------------- 10 | -- 11 | -- This file is part of AIMA. 12 | -- 13 | -- AIMA is free software: you can redistribute it and/or modify it 14 | -- under the terms of the MIT/X11 License as published by the 15 | -- Massachusetts Institute of Technology. See the MIT/X11 License 16 | -- for more details. 17 | -- 18 | -- You should have received a copy of the MIT/X11 License along with 19 | -- this source code distribution of AIMA (see the COPYING file in the 20 | -- root directory). If not, see 21 | -- . 22 | ---------------------------------------------------------------------- 23 | 24 | -- Simulated annealing algorithm. 25 | -- 26 | -- PRE: 27 | -- problem - array of costs, index indicates state (table). 28 | -- start - starting state index (number). 29 | -- schedule - mapping from time to temperature (function). 30 | -- It must end with zero. 31 | -- 32 | -- POST: 33 | -- solution - solution state (number). 34 | 35 | 36 | function simulated_annealing(problem, start, schedule) 37 | local current = start 38 | local t = 0 39 | while (true) do 40 | t = t + 1 41 | local T = schedule(t) 42 | if (T == 0) then return current end 43 | local move = math.random() 44 | local successor = current 45 | if (move < 0.5) then 46 | if (current > 1) then 47 | successor = current - 1 48 | end 49 | else 50 | if (current < #problem) then 51 | successor = current + 1 52 | end 53 | end 54 | local delta = problem[successor] - problem[current] 55 | if (delta > 0) then 56 | current = successor 57 | else 58 | if (math.random() < math.exp(delta / T)) then 59 | current = successor 60 | end 61 | end 62 | end 63 | end 64 | 65 | -------------------------------------------------------------------------------- /src/uniform_cost_search.lua: -------------------------------------------------------------------------------- 1 | ---------------------------------------------------------------------- 2 | -- File : uniform_cost_search.lua 3 | -- Created : 12-Feb-2015 4 | -- By : Alexandre Trilla 5 | -- 6 | -- AIMA - Artificial Intelligence, A Maker's Approach 7 | -- 8 | -- Copyright (C) 2015 A.I. Maker 9 | ---------------------------------------------------------------------- 10 | -- 11 | -- This file is part of AIMA. 12 | -- 13 | -- AIMA is free software: you can redistribute it and/or modify it 14 | -- under the terms of the MIT/X11 License as published by the 15 | -- Massachusetts Institute of Technology. See the MIT/X11 License 16 | -- for more details. 17 | -- 18 | -- You should have received a copy of the MIT/X11 License along with 19 | -- this source code distribution of AIMA (see the COPYING file in the 20 | -- root directory). If not, see 21 | -- . 22 | ---------------------------------------------------------------------- 23 | 24 | -- Uniform-cost search algorithm. 25 | -- 26 | -- PRE: 27 | -- problem - cost-weighted adjacency matrix (table). 28 | -- start - starting node index (number). 29 | -- finish - finishing node index (number). 30 | -- treegraph - tree/graph version flag (boolean). 31 | -- True for graph search version. 32 | -- 33 | -- POST: 34 | -- solution - solution path (table). State set to zero if failure. 35 | 36 | 37 | require("best_first_search") 38 | 39 | local function eval_path(cost) 40 | return cost[1] 41 | end 42 | 43 | function uniform_cost_search(problem, start, finish, treegraph) 44 | -- heuristic is not taken into account 45 | zeros = {} 46 | for i = 1, #problem do 47 | zeros[i] = 0 48 | end 49 | return best_first_search(problem, start, finish, treegraph, 50 | eval_path, zeros) 51 | end 52 | 53 | -------------------------------------------------------------------------------- /test/op_amp/OP07.cir: -------------------------------------------------------------------------------- 1 | .SUBCKT OP07 3 2 7 4 6 2 | * INPUT 3 | RC1 7 80 8.842E+03 4 | RC2 7 90 8.842E+03 5 | Q1 80 102 10 QM1 6 | Q2 90 103 11 QM2 7 | RB1 2 102 5.000E+02 8 | RB2 3 103 5.000E+02 9 | DDM1 102 104 DM2 10 | DDM3 104 103 DM2 11 | DDM2 103 105 DM2 12 | DDM4 105 102 DM2 13 | C1 80 90 5.460E-12 14 | RE1 10 12 1.948E+03 15 | RE2 11 12 1.948E+03 16 | IEE 12 4 7.502E-06 17 | RE 12 0 2.666E+07 18 | CE 12 0 1.579E-12 19 | * INTERMEDIATE 20 | GCM 0 8 12 0 5.668E-11 21 | GA 8 0 80 90 1.131E-04 22 | R2 8 0 1.000E+05 23 | C2 1 8 3.000E-11 24 | GB 1 0 8 0 1.294E+03 25 | * OUTPUT 26 | RO1 1 6 2.575E+01 27 | RO2 1 0 3.425E+01 28 | RC 17 0 6.634E-06 29 | GC 0 17 6 0 1.507E+05 30 | D1 1 17 DM1 31 | D2 17 1 DM1 32 | D3 6 13 DM2 33 | D4 14 6 DM2 34 | VC 7 13 2.803E+00 35 | VE 14 4 2.803E+00 36 | IP 7 4 2.492E-03 37 | DSUB 4 7 DM2 38 | * MODELS 39 | .MODEL QM1 NPN (IS=8.000E-16 BF=3.125E+03) 40 | .MODEL QM2 NPN (IS=8.009E-16 BF=4.688E+03) 41 | .MODEL DM1 D (IS=1.486E-08) 42 | .MODEL DM2 D (IS=8.000E-16) 43 | .ENDS OP07 44 | -------------------------------------------------------------------------------- /test/op_amp/op_amp.lua: -------------------------------------------------------------------------------- 1 | ---------------------------------------------------------------------- 2 | -- File : op_amp.lua 3 | -- Created : 17-Mar-2015 4 | -- By : Alexandre Trilla 5 | -- 6 | -- AIMA - Artificial Intelligence, A Maker's Approach 7 | -- 8 | -- Copyright (C) 2015 A.I. Maker 9 | ---------------------------------------------------------------------- 10 | -- 11 | -- This file is part of AIMA. 12 | -- 13 | -- AIMA is free software: you can redistribute it and/or modify it 14 | -- under the terms of the MIT/X11 License as published by the 15 | -- Massachusetts Institute of Technology. See the MIT/X11 License 16 | -- for more details. 17 | -- 18 | -- You should have received a copy of the MIT/X11 License along with 19 | -- this source code distribution of AIMA (see the COPYING file in the 20 | -- root directory). If not, see 21 | -- . 22 | ---------------------------------------------------------------------- 23 | 24 | -- Component optimisation for an AC common-emitter amplifier with 25 | -- emitter degeneration. Obj: max symmetrix excursion without 26 | -- clipping. 27 | 28 | 29 | package.path = package.path .. ";../../src/?.lua;../../data/?.lua" 30 | 31 | require("genetic_algorithm") 32 | 33 | print("OP amp") 34 | print("------") 35 | 36 | local r = {10,12,15,18,22,27,33,39,47,56,68,82} 37 | local exp = {1, 10, 100, 1000, 10000} 38 | local rval = {} 39 | for i = 1, #exp do 40 | for j = 1, #r do 41 | table.insert(rval, r[j] * exp[i]) 42 | end 43 | end 44 | local population = {} 45 | math.randomseed(os.time()) 46 | for i = 1, 100 do 47 | local indiv = {} 48 | local r 49 | for j = 1, 12 do 50 | r = math.random() 51 | if (r < 0.5) then 52 | r = 0 53 | else 54 | r = 1 55 | end 56 | table.insert(indiv, r) 57 | end 58 | table.insert(population, indiv) 59 | end 60 | 61 | local function checkval(a, start) 62 | local rcount = 0 63 | for i = 1, 6 do 64 | rcount = rcount + a[start - 1 + i] * math.pow(2, 6 - i) 65 | end 66 | if (rcount > 60) then return -1 end 67 | if (rcount == 0) then return -1 end 68 | return rval[rcount] 69 | end 70 | 71 | -- define vo func 72 | local function vo(vi, Rf, Rg) 73 | return vi * (1 + Rf/Rg) 74 | end 75 | 76 | local function esmfit(Rf, Rg) 77 | local esmval = (20 - (vo(1, Rf, Rg) - vo(-1, Rf, Rg)))^2 78 | return 1/esmval 79 | end 80 | 81 | local function fitness(x) 82 | local vcc = 15 83 | local Rf = checkval(x, 1) 84 | if (Rf == -1) then return 0 end 85 | local Rg = checkval(x, 7) 86 | if (Rg == -1) then return 0 end 87 | -- calc fitness, return 88 | return esmfit(Rf, Rg) 89 | end 90 | 91 | -- exhaustive linear search 92 | local t1 = os.clock() 93 | eRf = rval[1] 94 | eRg = rval[1] 95 | efit = esmfit(eRf, eRg) 96 | for rf = 1, #rval do 97 | for rg = 1, #rval do 98 | local fit = esmfit(rval[rf], rval[rg]) 99 | if (fit > efit) then 100 | eRf = rval[rf] 101 | eRg = rval[rg] 102 | efit = fit 103 | end 104 | end 105 | end 106 | local t2 = os.clock() 107 | print("Exhaustive solution is state...") 108 | print("Rf: ", eRf) 109 | print("Rg: ", eRg) 110 | print("Fitness: ", efit) 111 | print("Elapsed: " .. t2 - t1) 112 | 113 | print("") 114 | 115 | t1 = os.clock() 116 | local solution = genetic_algorithm(population, fitness) 117 | t2 = os.clock() 118 | 119 | local Rf = checkval(solution, 1) 120 | local Rg = checkval(solution, 7) 121 | 122 | print("GA solution is state...") 123 | print("Rf: ", Rf) 124 | print("Rg: ", Rg) 125 | print("Fitness: ", fitness(solution)) 126 | 127 | print("Elapsed: " .. t2 - t1) 128 | 129 | print("") 130 | 131 | -------------------------------------------------------------------------------- /test/op_amp/op_amp.sch: -------------------------------------------------------------------------------- 1 | v 20110115 2 2 | C 40000 40000 0 0 0 title-B.sym 3 | C 44700 45900 1 0 0 vsin-1.sym 4 | { 5 | T 45400 46550 5 10 1 1 0 0 1 6 | refdes=Vin 7 | T 45400 46750 5 10 0 0 0 0 1 8 | device=vsin 9 | T 45400 46950 5 10 0 0 0 0 1 10 | footprint=none 11 | T 45400 46350 5 10 1 1 0 0 1 12 | value=sin 0 1 1k 13 | } 14 | C 50000 44300 1 180 0 vdc-1.sym 15 | { 16 | T 49300 43650 5 10 1 1 180 0 1 17 | refdes=Vcc 18 | T 49300 43450 5 10 0 0 180 0 1 19 | device=VOLTAGE_SOURCE 20 | T 49300 43250 5 10 0 0 180 0 1 21 | footprint=none 22 | T 49300 43850 5 10 1 1 180 0 1 23 | value=DC 15V 24 | } 25 | C 44900 44100 1 0 0 gnd-1.sym 26 | C 48100 45700 1 180 0 resistor-1.sym 27 | { 28 | T 47800 45300 5 10 0 0 180 0 1 29 | device=RESISTOR 30 | T 47900 45400 5 10 1 1 180 0 1 31 | refdes=Rf 32 | T 47900 45800 5 10 1 0 90 0 1 33 | value=330 34 | T 48100 45700 5 10 0 0 90 0 1 35 | model=RES 36 | } 37 | C 46500 44700 1 90 0 resistor-1.sym 38 | { 39 | T 46100 45000 5 10 0 0 90 0 1 40 | device=RESISTOR 41 | T 46200 44900 5 10 1 1 90 0 1 42 | refdes=Rg 43 | T 46700 45000 5 10 1 0 0 0 1 44 | value=39 45 | T 46500 44700 5 10 0 0 0 0 1 46 | model=RES 47 | } 48 | C 50000 46000 1 180 0 vdc-1.sym 49 | { 50 | T 49300 45350 5 10 1 1 180 0 1 51 | refdes=Vss 52 | T 49300 45150 5 10 0 0 180 0 1 53 | device=VOLTAGE_SOURCE 54 | T 49300 44950 5 10 0 0 180 0 1 55 | footprint=none 56 | T 49300 45550 5 10 1 1 180 0 1 57 | value=DC 15V 58 | } 59 | C 46400 46500 1 0 0 aop-spice-1.sym 60 | { 61 | T 47450 46650 5 8 0 0 0 0 1 62 | device=AOP-Standard 63 | T 47100 47300 5 10 1 1 0 0 1 64 | refdes=XOA1 65 | T 46400 46500 5 10 0 0 0 0 1 66 | value=OP07 67 | T 46400 46500 5 10 0 0 0 0 1 68 | model-name=OP07 69 | T 46400 46500 5 10 0 0 0 0 1 70 | file=OP07.cir 71 | } 72 | N 45000 47100 46400 47100 4 73 | { 74 | T 44900 47300 5 10 1 0 0 0 1 75 | netname=in 76 | } 77 | N 46400 46700 46400 45600 4 78 | N 46400 45600 47200 45600 4 79 | N 46400 44700 45000 44700 4 80 | N 45000 44400 45000 45900 4 81 | N 48100 45600 48100 46900 4 82 | N 47400 46900 48100 46900 4 83 | { 84 | T 47400 47000 5 10 1 0 0 0 1 85 | netname=out 86 | } 87 | N 49700 44300 49700 44800 4 88 | N 46400 44700 46400 44600 4 89 | N 46400 44600 49700 44600 4 90 | N 49700 46000 49700 48200 4 91 | N 49700 48200 46900 48200 4 92 | N 46900 48200 46900 47300 4 93 | N 49700 43100 46900 43100 4 94 | N 46900 43100 46900 46500 4 95 | -------------------------------------------------------------------------------- /test/op_amp/output.net: -------------------------------------------------------------------------------- 1 | * gnetlist -g spice-sdb op_amp.sch 2 | ********************************************************* 3 | * Spice file generated by gnetlist * 4 | * spice-sdb version 4.28.2007 by SDB -- * 5 | * provides advanced spice netlisting capability. * 6 | * Documentation at http://www.brorson.com/gEDA/SPICE/ * 7 | ********************************************************* 8 | *vvvvvvvv Included SPICE model from OP07.cir vvvvvvvv 9 | .SUBCKT OP07 3 2 7 4 6 10 | * INPUT 11 | RC1 7 80 8.842E+03 12 | RC2 7 90 8.842E+03 13 | Q1 80 102 10 QM1 14 | Q2 90 103 11 QM2 15 | RB1 2 102 5.000E+02 16 | RB2 3 103 5.000E+02 17 | DDM1 102 104 DM2 18 | DDM3 104 103 DM2 19 | DDM2 103 105 DM2 20 | DDM4 105 102 DM2 21 | C1 80 90 5.460E-12 22 | RE1 10 12 1.948E+03 23 | RE2 11 12 1.948E+03 24 | IEE 12 4 7.502E-06 25 | RE 12 0 2.666E+07 26 | CE 12 0 1.579E-12 27 | * INTERMEDIATE 28 | GCM 0 8 12 0 5.668E-11 29 | GA 8 0 80 90 1.131E-04 30 | R2 8 0 1.000E+05 31 | C2 1 8 3.000E-11 32 | GB 1 0 8 0 1.294E+03 33 | * OUTPUT 34 | RO1 1 6 2.575E+01 35 | RO2 1 0 3.425E+01 36 | RC 17 0 6.634E-06 37 | GC 0 17 6 0 1.507E+05 38 | D1 1 17 DM1 39 | D2 17 1 DM1 40 | D3 6 13 DM2 41 | D4 14 6 DM2 42 | VC 7 13 2.803E+00 43 | VE 14 4 2.803E+00 44 | IP 7 4 2.492E-03 45 | DSUB 4 7 DM2 46 | * MODELS 47 | .MODEL QM1 NPN (IS=8.000E-16 BF=3.125E+03) 48 | .MODEL QM2 NPN (IS=8.009E-16 BF=4.688E+03) 49 | .MODEL DM1 D (IS=1.486E-08) 50 | .MODEL DM2 D (IS=8.000E-16) 51 | .ENDS OP07 52 | *^^^^^^^^ End of included SPICE model from OP07.cir ^^^^^^^^ 53 | * 54 | *============== Begin SPICE netlist of main design ============ 55 | XOA1 in 2 1 3 out OP07 56 | Vss 0 3 DC 15V 57 | Rg 0 2 39 58 | Rf out 2 330 59 | Vcc 1 0 DC 15V 60 | Vin in 0 sin 0 1 1k 61 | .end 62 | -------------------------------------------------------------------------------- /test/prettyplot.m: -------------------------------------------------------------------------------- 1 | ## Copyright (C) 2014-2015 Alexandre Trilla 2 | ## 3 | ## This file is part of AIMA. 4 | ## 5 | ## AIMA is free software: you can redistribute it and/or modify it 6 | ## under the terms of the MIT/X11 License as published by the 7 | ## Massachusetts Institute of Technology. See the MIT/X11 License 8 | ## for more details. 9 | ## 10 | ## You should have received a copy of the MIT/X11 License along with 11 | ## this source code distribution of AIMA (see the COPYING file in the 12 | ## root directory). If not, see 13 | ## . 14 | 15 | ## -*- texinfo -*- 16 | ## @deftypefn {Utility Function} {} ut_prettyplot (@var{h}) 17 | ## Embellish the given plot for publication purposes. 18 | ## 19 | ## PRE: 20 | ## @var{h} must be a handle to the given plot. 21 | ## 22 | ## POST: 23 | ## Plot is enhanced with appropriate size and font. 24 | ## @end deftypefn 25 | 26 | ## Author: Alexandre Trilla 27 | 28 | function [] = prettyplot(h) 29 | 30 | W = 3; 31 | H = 2; 32 | set(h,'PaperUnits','inches') 33 | set(h,'PaperOrientation','portrait'); 34 | set(h,'PaperSize',[H,W]) 35 | set(h,'PaperPosition',[0,0,W,H]) 36 | 37 | FN = findall(h,'-property','FontName'); 38 | set(FN,'FontName','/usr/share/fonts/truetype/droid/DroidSans.ttf'); 39 | FS = findall(h,'-property','FontSize'); 40 | set(FS,'FontSize',8); 41 | 42 | print('whatever.eps', '-depsc', '-S450,300') 43 | 44 | endfunction 45 | 46 | -------------------------------------------------------------------------------- /test/unit_beyond_classical_search.lua: -------------------------------------------------------------------------------- 1 | ---------------------------------------------------------------------- 2 | -- File : unit_beyond_classical_search.lua 3 | -- Created : 20-Feb-2015 4 | -- By : Alexandre Trilla 5 | -- 6 | -- AIMA - Artificial Intelligence, A Maker's Approach 7 | -- 8 | -- Copyright (C) 2015 A.I. Maker 9 | ---------------------------------------------------------------------- 10 | -- 11 | -- This file is part of AIMA. 12 | -- 13 | -- AIMA is free software: you can redistribute it and/or modify it 14 | -- under the terms of the MIT/X11 License as published by the 15 | -- Massachusetts Institute of Technology. See the MIT/X11 License 16 | -- for more details. 17 | -- 18 | -- You should have received a copy of the MIT/X11 License along with 19 | -- this source code distribution of AIMA (see the COPYING file in the 20 | -- root directory). If not, see 21 | -- . 22 | ---------------------------------------------------------------------- 23 | 24 | -- Unit test for chapter 4 25 | 26 | 27 | package.path = package.path .. ";../src/?.lua;../data/?.lua" 28 | 29 | local hills = require("hills") 30 | require("hill_climbing") 31 | require("simulated_annealing") 32 | require("genetic_algorithm") 33 | require("gradient_ascent") 34 | 35 | print("Unit test chapter 4") 36 | print("") 37 | 38 | print("Hill climbing") 39 | print("-------------") 40 | local t1 = os.clock() 41 | local solution = hill_climbing(hills, 10) 42 | local t2 = os.clock() 43 | 44 | print("Starting on 10, solution is state...", solution) 45 | 46 | print("Elapsed: " .. t2 - t1) 47 | 48 | solution = hill_climbing(hills, 2) 49 | print("Starting on 2, solution is state...", solution) 50 | solution = hill_climbing(hills, 20) 51 | print("Starting on 20, solution is state...", solution) 52 | 53 | print("") 54 | 55 | print("Simulated annealing") 56 | print("-------------------") 57 | local t1 = os.clock() 58 | local function schedule(t) 59 | if (t > 100) then 60 | return 0 61 | else 62 | return math.exp(-t * 0.08) 63 | end 64 | end 65 | local solution = simulated_annealing(hills, 10, schedule) 66 | local t2 = os.clock() 67 | 68 | print("Starting on 10, solution is state...", solution) 69 | 70 | print("Elapsed: " .. t2 - t1) 71 | 72 | solution = simulated_annealing(hills, 2, schedule) 73 | print("Starting on 2, solution is state...", solution) 74 | solution = simulated_annealing(hills, 20, schedule) 75 | print("Starting on 20, solution is state...", solution) 76 | 77 | print("") 78 | 79 | print("Genetic algorithm") 80 | print("-----------------") 81 | population = {{1,1,0,1,1,0}, {1,0,0,0,0,1}, {0,0,0,0,1,1}, 82 | {1,0,1,0,1,0}, {0,0,0,1,0,1}, {1,1,1,0,0,0}} 83 | 84 | local function fitness(x) 85 | local state = 0 86 | for i = 1, #x do 87 | state = state + x[i] * math.pow(2, i - 1) 88 | end 89 | if (state == 0) then return 0 end 90 | if (state > 40) then return 0 end 91 | return hills[state] 92 | end 93 | 94 | local t1 = os.clock() 95 | local solution = genetic_algorithm(population, fitness) 96 | local t2 = os.clock() 97 | 98 | local statesol = 0 99 | for i = 1, #solution do 100 | statesol = statesol + solution[i] * math.pow(2, i - 1) 101 | end 102 | print("Solution is state...", statesol) 103 | 104 | print("Elapsed: " .. t2 - t1) 105 | 106 | print("") 107 | 108 | print("Gradient ascent") 109 | print("---------------") 110 | 111 | -- Band-pass filter at 1.5kHz 112 | 113 | function bpf(f) 114 | local L = 100e-3 115 | local C = 10e-6 116 | local R = 500 117 | local A = 1 / (1/(2*math.pi*f[1]*L) - 2*math.pi*f[1]*C) 118 | return math.abs((A/(R^2 + A^2))*math.sqrt(A^2+R^2)) 119 | end 120 | 121 | local sol = {500} 122 | local t1 = os.clock() 123 | gradient_ascent(bpf, sol, 1) 124 | local t2 = os.clock() 125 | 126 | print("Solution is state...", sol[1]) 127 | 128 | print("Elapsed: " .. t2 - t1) 129 | 130 | print("") 131 | 132 | -------------------------------------------------------------------------------- /test/unit_problem_solving_searching.lua: -------------------------------------------------------------------------------- 1 | ---------------------------------------------------------------------- 2 | -- File : unit_problem_solving_searching.lua 3 | -- Created : 11-Feb-2015 4 | -- By : Alexandre Trilla 5 | -- 6 | -- AIMA - Artificial Intelligence, A Maker's Approach 7 | -- 8 | -- Copyright (C) 2015 A.I. Maker 9 | ---------------------------------------------------------------------- 10 | -- 11 | -- This file is part of AIMA. 12 | -- 13 | -- AIMA is free software: you can redistribute it and/or modify it 14 | -- under the terms of the MIT/X11 License as published by the 15 | -- Massachusetts Institute of Technology. See the MIT/X11 License 16 | -- for more details. 17 | -- 18 | -- You should have received a copy of the MIT/X11 License along with 19 | -- this source code distribution of AIMA (see the COPYING file in the 20 | -- root directory). If not, see 21 | -- . 22 | ---------------------------------------------------------------------- 23 | 24 | -- Unit test for chapter 3. 25 | 26 | 27 | package.path = package.path .. ";../src/?.lua;../data/?.lua" 28 | 29 | local germany = require("germany") 30 | require("breadth_first_search") 31 | require("uniform_cost_search") 32 | require("depth_first_search") 33 | require("depth_limited_search") 34 | require("iterative_deepening_search") 35 | require("greedy_search") 36 | require("a_star_search") 37 | require("recursive_best_first_search") 38 | 39 | print("Unit test chapter 3") 40 | print("Search path from Frankfurt to Munchen") 41 | print("") 42 | 43 | print("Breadth-first search") 44 | print("--------------------") 45 | local t1 = os.clock() 46 | local solution = breadth_first_search(germany.problem, 47 | germany.state.Frankfurt, germany.state.Munchen, true) 48 | local t2 = os.clock() 49 | 50 | assert(solution.state == germany.state.Munchen, "Solution is Munchen") 51 | 52 | print("Path cost is... " .. solution.cost) 53 | 54 | for i = 1, #solution.parent do 55 | local cName = nil 56 | for city,id in pairs(germany.state) do 57 | if (id == solution.parent[i]) then 58 | print("Parent " .. i .. ": " .. city) 59 | break 60 | end 61 | end 62 | end 63 | 64 | print("Elapsed: " .. t2 - t1) 65 | 66 | print("") 67 | 68 | print("Uniform-cost search") 69 | print("-------------------") 70 | t1 = os.clock() 71 | solution = uniform_cost_search(germany.problem, 72 | germany.state.Frankfurt, germany.state.Munchen, true) 73 | t2 = os.clock() 74 | 75 | assert(solution.state == germany.state.Munchen, "Solution is Munchen") 76 | 77 | print("Path cost is... " .. solution.cost[1]) 78 | 79 | for i = 1, #solution.parent do 80 | local cName = nil 81 | for city,id in pairs(germany.state) do 82 | if (id == solution.parent[i]) then 83 | print("Parent " .. i .. ": " .. city) 84 | break 85 | end 86 | end 87 | end 88 | 89 | print("Elapsed: " .. t2 - t1) 90 | 91 | print("") 92 | 93 | print("Depth-first search") 94 | print("------------------") 95 | t1 = os.clock() 96 | solution = depth_first_search(germany.problem, 97 | germany.state.Frankfurt, germany.state.Munchen, true) 98 | t2 = os.clock() 99 | 100 | assert(solution.state == germany.state.Munchen, "Solution is Munchen") 101 | 102 | print("Path cost is... " .. solution.cost) 103 | 104 | for i = 1, #solution.parent do 105 | local cName = nil 106 | for city,id in pairs(germany.state) do 107 | if (id == solution.parent[i]) then 108 | print("Parent " .. i .. ": " .. city) 109 | break 110 | end 111 | end 112 | end 113 | 114 | print("Elapsed: " .. t2 - t1) 115 | 116 | print("") 117 | 118 | print("Depth-limited search") 119 | print("--------------------") 120 | t1 = os.clock() 121 | solution = depth_limited_search(germany.problem, 122 | germany.state.Frankfurt, germany.state.Munchen, 3) 123 | t2 = os.clock() 124 | 125 | assert(solution.state == germany.state.Munchen, "Solution is Munchen") 126 | 127 | print("Path cost is... " .. solution.cost) 128 | 129 | for i = 1, #solution.parent do 130 | local cName = nil 131 | for city,id in pairs(germany.state) do 132 | if (id == solution.parent[i]) then 133 | print("Parent " .. i .. ": " .. city) 134 | break 135 | end 136 | end 137 | end 138 | 139 | print("Elapsed: " .. t2 - t1) 140 | 141 | print("") 142 | 143 | print("Iterative-deepening search") 144 | print("--------------------------") 145 | t1 = os.clock() 146 | solution = iterative_deepening_search(germany.problem, 147 | germany.state.Frankfurt, germany.state.Munchen) 148 | t2 = os.clock() 149 | 150 | assert(solution.state == germany.state.Munchen, "Solution is Munchen") 151 | 152 | print("Path cost is... " .. solution.cost) 153 | 154 | for i = 1, #solution.parent do 155 | local cName = nil 156 | for city,id in pairs(germany.state) do 157 | if (id == solution.parent[i]) then 158 | print("Parent " .. i .. ": " .. city) 159 | break 160 | end 161 | end 162 | end 163 | 164 | print("Elapsed: " .. t2 - t1) 165 | 166 | print("") 167 | 168 | print("Greedy search") 169 | print("-------------") 170 | -- heuristic based on highway distances from ViaMichelin 171 | t1 = os.clock() 172 | solution = greedy_search(germany.problem, germany.state.Frankfurt, 173 | germany.state.Munchen, true, 174 | {378, 341, 265, 216, 282, 379, 150, 63, 0, 458}) 175 | t2 = os.clock() 176 | 177 | assert(solution.state == germany.state.Munchen, "Solution is Munchen") 178 | 179 | print("Path cost is... " .. solution.cost[1]) 180 | 181 | for i = 1, #solution.parent do 182 | local cName = nil 183 | for city,id in pairs(germany.state) do 184 | if (id == solution.parent[i]) then 185 | print("Parent " .. i .. ": " .. city) 186 | break 187 | end 188 | end 189 | end 190 | 191 | print("Elapsed: " .. t2 - t1) 192 | 193 | print("") 194 | 195 | print("A-star search") 196 | print("-------------") 197 | -- heuristic based on highway distances from ViaMichelin 198 | t1 = os.clock() 199 | solution = a_star_search(germany.problem, germany.state.Frankfurt, 200 | germany.state.Munchen, true, 201 | {378, 341, 265, 216, 282, 379, 150, 63, 0, 458}) 202 | t2 = os.clock() 203 | 204 | assert(solution.state == germany.state.Munchen, "Solution is Munchen") 205 | 206 | print("Path cost is... " .. solution.cost[1]) 207 | 208 | for i = 1, #solution.parent do 209 | local cName = nil 210 | for city,id in pairs(germany.state) do 211 | if (id == solution.parent[i]) then 212 | print("Parent " .. i .. ": " .. city) 213 | break 214 | end 215 | end 216 | end 217 | 218 | print("Elapsed: " .. t2 - t1) 219 | 220 | print("") 221 | 222 | print("Recursive best-first search") 223 | print("---------------------------") 224 | t1 = os.clock() 225 | solution = recursive_best_first_search(germany.problem, 226 | germany.state.Frankfurt, germany.state.Munchen, 227 | {378, 341, 265, 216, 282, 379, 150, 63, 0, 458}) 228 | t2 = os.clock() 229 | 230 | assert(solution.state == germany.state.Munchen, "Solution is Munchen") 231 | 232 | print("Path cost is... " .. solution.cost[1]) 233 | 234 | for i = 1, #solution.parent do 235 | local cName = nil 236 | for city,id in pairs(germany.state) do 237 | if (id == solution.parent[i]) then 238 | print("Parent " .. i .. ": " .. city) 239 | break 240 | end 241 | end 242 | end 243 | 244 | print("Elapsed: " .. t2 - t1) 245 | 246 | print("") 247 | 248 | -------------------------------------------------------------------------------- /test/xorgate.lua: -------------------------------------------------------------------------------- 1 | ---------------------------------------------------------------------- 2 | -- File : xorgate.lua 3 | -- Created : 01-May-2015 4 | -- By : Alexandre Trilla 5 | -- 6 | -- AIMA - Artificial Intelligence, A Maker's Approach 7 | -- 8 | -- Copyright (C) 2015 A.I. Maker 9 | ---------------------------------------------------------------------- 10 | -- 11 | -- This file is part of AIMA. 12 | -- 13 | -- AIMA is free software: you can redistribute it and/or modify it 14 | -- under the terms of the MIT/X11 License as published by the 15 | -- Massachusetts Institute of Technology. See the MIT/X11 License 16 | -- for more details. 17 | -- 18 | -- You should have received a copy of the MIT/X11 License along with 19 | -- this source code distribution of AIMA (see the COPYING file in the 20 | -- root directory). If not, see 21 | -- . 22 | ---------------------------------------------------------------------- 23 | 24 | -- OR gate built with ANN. 25 | 26 | package.path = package.path .. ";../src/?.lua;../data/?.lua" 27 | 28 | require "neural_network" 29 | 30 | local net = ann:new(2,4,1) 31 | local data = {{0,0},{0,1},{1,0},{1,1}} 32 | local t = {{0},{1},{1},{0}} 33 | 34 | net:train(data,t) 35 | 36 | print("0 0 -> ", net:predict({0,0})[1]) 37 | print("0 1 -> ", net:predict({0,1})[1]) 38 | print("1 0 -> ", net:predict({1,0})[1]) 39 | print("1 1 -> ", net:predict({1,1})[1]) 40 | 41 | 42 | --------------------------------------------------------------------------------