(*^ ::[ Information = "This is a Mathematica Notebook file. It contains ASCII text, and can be transferred by email, ftp, or other text-file transfer utility. It should be read or edited using a copy of Mathematica or MathReader. If you received this as email, use your mail application or copy/paste to save everything from the line containing (*^ down to the line containing ^*) into a plain text file. On some systems you may have to give the file a name ending with ".ma" to allow Mathematica to recognize it as a Notebook. The line below identifies what version of Mathematica created this file, but it can be opened using any other version as well."; FrontEndVersion = "X Window System Mathematica Notebook Front End Version 2.2"; X11StandardFontEncoding; fontset = title, inactive, noPageBreakBelow, noPageBreakInGroup, nohscroll, preserveAspect, groupLikeTitle, center, M7, bold, R65535, B65535, e8, 24, fontName, "times"; fontset = subtitle, inactive, noPageBreakBelow, noPageBreakInGroup, nohscroll, preserveAspect, groupLikeTitle, center, M7, bold, e6, 18, fontName, "times"; fontset = subsubtitle, inactive, noPageBreakBelow, noPageBreakInGroup, nohscroll, preserveAspect, groupLikeTitle, center, M7, italic, e6, 14, fontName, "times"; fontset = section, inactive, noPageBreakBelow, nohscroll, preserveAspect, groupLikeSection, grayBox, M22, bold, B65535, a20, 18, fontName, "times"; fontset = subsection, inactive, noPageBreakBelow, nohscroll, preserveAspect, groupLikeSection, blackBox, M19, bold, R65535, a15, 14, fontName, "times"; fontset = subsubsection, inactive, noPageBreakBelow, nohscroll, preserveAspect, groupLikeSection, whiteBox, M18, bold, a12, 12, fontName, "times"; fontset = text, inactive, nohscroll, noKeepOnOnePage, preserveAspect, M7, 12, fontName, "times"; fontset = smalltext, inactive, nohscroll, noKeepOnOnePage, preserveAspect, M7, 10, fontName, "times"; fontset = input, noPageBreakInGroup, nowordwrap, preserveAspect, groupLikeInput, M42, N23, bold, 12, fontName, "courier"; fontset = output, output, inactive, noPageBreakInGroup, nowordwrap, preserveAspect, groupLikeOutput, M42, N23, L-5, 12, fontName, "courier"; fontset = message, inactive, noPageBreakInGroup, nowordwrap, preserveAspect, groupLikeOutput, M42, N23, 12, fontName, "courier"; fontset = print, inactive, noPageBreakInGroup, nowordwrap, preserveAspect, groupLikeOutput, M42, N23, 12, fontName, "courier"; fontset = info, inactive, noPageBreakInGroup, nowordwrap, preserveAspect, groupLikeOutput, M42, N23, 12, fontName, "courier"; fontset = postscript, PostScript, formatAsPostScript, output, inactive, noPageBreakInGroup, nowordwrap, preserveAspect, groupLikeGraphics, M7, l34, w282, h287, 12, fontName, "courier"; fontset = name, inactive, noPageBreakInGroup, nohscroll, preserveAspect, M7, italic, B65535, 10, fontName, "times"; fontset = header, inactive, nohscroll, noKeepOnOnePage, preserveAspect, M7, italic, 12, fontName, "times"; fontset = leftheader, 12, fontName, "times"; fontset = footer, inactive, nohscroll, noKeepOnOnePage, preserveAspect, center, M7, italic, 12, fontName, "times"; fontset = leftfooter, 12, fontName, "times"; fontset = help, inactive, nohscroll, noKeepOnOnePage, preserveAspect, M7, 12, fontName, "times"; fontset = clipboard, inactive, nohscroll, noKeepOnOnePage, preserveAspect, M7, 12, fontName, "times"; fontset = completions, inactive, nohscroll, noKeepOnOnePage, preserveAspect, M7, 12, fontName, "courier"; fontset = special1, inactive, nohscroll, noKeepOnOnePage, preserveAspect, M7, 12, fontName, "times"; fontset = special2, inactive, nohscroll, noKeepOnOnePage, preserveAspect, M7, 12, fontName, "times"; fontset = special3, inactive, nohscroll, noKeepOnOnePage, preserveAspect, M7, 12, fontName, "times"; fontset = special4, inactive, nohscroll, noKeepOnOnePage, preserveAspect, M7, 12, fontName, "times"; fontset = special5, inactive, nohscroll, noKeepOnOnePage, preserveAspect, M7, 12, fontName, "times";paletteColors = 128; showRuler; automaticGrouping; currentKernel; ] :[font = title; inactive; preserveAspect; startGroup] Rearrangement Of Polynomials Using Search Algorithms :[font = section; inactive; preserveAspect; startGroup] Introduction :[font = text; inactive; preserveAspect] Polynomials can be rearranged in a certain way so that the form obtained by the manipulation could match some desired form. One such rearrangement is assigning the multiplications in the polynomial to have some units of cost by some factor higher than the units of cost assigned to the additions in the polynomial. This way the optimal form in terms of cost would be Horner's form which would then have the least number of multiplications. :[font = text; inactive; preserveAspect] An nth order polynomial in its standard form has its structure such that the number of the multiplications are maximized. As the assigned cost of the multiplication was five times as much as the cost of the addition, the original structure of the polynomial had to be altered in such a way that the resulting form would mathematically be equivalent but at the same time, the form would be such that the number of multiplications in the polynomial get minimized. To accomplish the task, four search algorithms were used. The algorithms used were divided into two classes: informed and the uninformed search algorithms. The uninformed search algorithms have no available information to guess the location of the goal state and thus have to go exhaustively through the search tree. However, they can identify the goal state if they ever reach it. Search algorithms generate the new successor states using legal operations on the current state. The two uninformed search algorithms used include breadth first search and the depth first search. The informed search algorithms on the other hand include some sort of heuristic to help the navigation to the goal state. The two informed search algorithms used were hill climbing and simulated annealing. :[font = text; inactive; preserveAspect] The following polynomial will be used throughout the book to illustrate the working of the search algorithms :[font = input; initialization; preserveAspect; startGroup] *) polynomiallocal = A x + B x^2 + C x^3 + D x^4 + E x^5 (* :[font = output; output; inactive; preserveAspect; endGroup; endGroup] A*x + B*x^2 + C*x^3 + D*x^4 + E*x^5 ;[o] 2 3 4 5 A x + B x + C x + D x + E x :[font = section; inactive; preserveAspect; startGroup] Background :[font = text; inactive; preserveAspect] All the algorithms require a successor function to be passed in. If one is not passed in, then the default successor function will be used which also requires the rules to be passed in to be used by the default successor function. An evaluation function specific to the problem should be passed in otherwise the default evaluation function will be processed which is simply the number of leaves in the mathematical expression. :[font = text; inactive; preserveAspect] If the uninformed search algorithms are used, then the factor by which the cost has to be reduced should be passed in so that the goal state could be determined. :[font = text; inactive; preserveAspect] If the simulated annealing is used then the cooling schedule along with the maximum number of iterations should be provided. If they are not passed in, then the default cooling schedule along with the default number of iterations equal to twenty will be used by the algorithm. The exact names of the parameters can be determined by the usage statements. The examples of running along with some results are shown below the captions "Example". :[font = text; inactive; preserveAspect] The following statement will load all the required packages required to run the algorithms. :[font = input; initialization; preserveAspect] *) Needs[ "HeuristicSearch`Master`" ] (* :[font = text; inactive; preserveAspect; endGroup] The following section will provide some insight into the working of the four search algorithms. Discussion of informed search algorithms will follow the discussion of uninformed search algorithms. :[font = section; inactive; preserveAspect; startGroup] Breadth First Search :[font = text; inactive; preserveAspect] The breadth first search goes through the search tree and makes a list of nodes to be explored. Each time a node is plucked out of the list of nodes from the front. The node is checked to see if it is the goal state. If the plucked up node is the goal state, then the search stops and provides the node as the result. If the node is not the goal state, then its successors are found using the successor function. The successors of the node are then appended at the end of the list of nodes to be explored. In this way, the search goes breadth wise through the tree and explores the tree in the row wise fashion starting from the given problem. :[font = text; inactive; preserveAspect] The time complexity of the search technique is exponential. This is because for each new node, the algorithm generates a new set of successors to be evaluated. :[font = text; inactive; preserveAspect] The memory requirement of the algorithm is also exponential because the algorithm has to store all the nodes to be explored in the memory. :[font = text; inactive; preserveAspect] However, it should be noted that the algorithm is complete. :[font = subsection; inactive; preserveAspect; startGroup] Examples :[font = input; preserveAspect; startGroup] BreadthFirstSearch[polynomiallocal, EvaluationFunction -> InitEvalPoly, SuccessorFunction -> PolySuccessorFunction, CostReductionFactor -> 1.5 ] :[font = output; output; inactive; preserveAspect; endGroup] A*x + x^2*(B + C*x) + x^4*(D + E*x) ;[o] 2 4 A x + x (B + C x) + x (D + E x) :[font = input; preserveAspect; startGroup] BreadthFirstSearch[polynomiallocal, EvaluationFunction -> InitEvalPoly, SuccessorFunction -> PolySuccessorFunction, CostReductionFactor -> 2 ] :[font = output; output; inactive; preserveAspect; endGroup] x*(A + B*x) + x^3*(C + x*(D + E*x)) ;[o] 3 x (A + B x) + x (C + x (D + E x)) :[font = text; inactive; preserveAspect; endGroup; endGroup] Note: The cost has been reduced by the factor of 1.5 and 2 respectively. ;[s] 2:0,0;7,1;77,-1; 2:1,0,0 ,times,0,12,65535,0,0;1,0,0 ,times,0,12,0,0,0; :[font = section; inactive; preserveAspect; startGroup] Depth First Search :[font = text; inactive; preserveAspect] This algorithm differs from the breadth first search in the manner that it appends the newly explored nodes at the beginning of the list of nodes to be explored. In that way, the first successor of the newly explored node is explored next. Thus the search algorithm goes straight down the tree to look for the goal state. Once it reaches the leaf of the tree, it backs off and goes to the next successor in the last explored set of the successors. :[font = text; inactive; preserveAspect] The time complexity of the depth first search is same as the breadth first search in the worst case, because in the worst case, both of the search algorithms will have to go through the whole tree. The user can explore this fact by the running the two algorithms in the tree without a goal. This situation can be handled by varying the parameter associated with the goal function. :[font = text; inactive; preserveAspect] It should be noted that the space complexity of the algorithm is linear. However, the depth first search technique outperforms the breadth first search in the tree structures where there are many goal states. The other situation where the depth first search might outperform the breadth first search is when the goal state is situated in deepest of the layers of a tree. This situation is very similar to the situation encountered in the case of polynomials where more factored form is preferred over the less factored form. That is the reason why the depth first search performs much better than the breadth first search in the present case. :[font = subsection; inactive; preserveAspect; startGroup] Examples :[font = input; preserveAspect; startGroup] DepthFirstSearch[polynomiallocal, EvaluationFunction -> InitEvalPoly, SuccessorFunction -> PolySuccessorFunction, CostReductionFactor -> 1.5 ] :[font = output; output; inactive; preserveAspect; endGroup] x*(A + B*x + E*x^4 + x^2*(C + D*x)) ;[o] 4 2 x (A + B x + E x + x (C + D x)) :[font = input; preserveAspect; startGroup] DepthFirstSearch[polynomiallocal, EvaluationFunction -> InitEvalPoly, SuccessorFunction -> PolySuccessorFunction, CostReductionFactor -> 2 ] :[font = output; output; inactive; preserveAspect; endGroup] x*(A + B*x + x^2*(C + D*x + E*x^2)) ;[o] 2 2 x (A + B x + x (C + D x + E x )) :[font = text; inactive; preserveAspect; endGroup; endGroup] Note: The reduction in cost by the same factor is achieved the depth first search. ;[s] 2:0,0;6,1;84,-1; 2:1,0,0 ,times,0,12,65535,0,0;1,0,0 ,times,0,12,0,0,0; :[font = section; inactive; preserveAspect; startGroup] Hill Climbing :[font = text; inactive; preserveAspect] This is the search strategy that uses heuristic which in the present case is also the evaluation function. The evaluation function tells which state of the successor states is the one with minimum cost. The algorithm works as follows. It first takes the problem as the current state and finds the next one by taking the smallest cost state of the newly generated successor states. If the cost of the next state found by the above method is less than the cost of the current state, the current state is assigned the next state and the search goes on. If the next state has the cost greater than the cost of the current state, the search is stopped and the current node is returned as the result. :[font = text; inactive; preserveAspect] In the case of the polynomials, the hill climbing search outperforms other search strategies because of the way successor states are generated. Since all the newly generated states are further factored, the next state cannot have the cost greater than the current state. Also in this way, the algorithm does not have any local maximas to get stuck on and provides the form where the rule can no longer be applied on the resultant state. This method thus give the optimal form for the rule devised to reach the solution for the problem. It should however be noted that this optimal form is for the rule used in this context and could be drastically different for some other rule. Also if some other rule is used, there is a possibility that the algorithm might encounter the local maximas. This would happen if the new rule expands some terms in the polynomial before it gets to the form where the structure would be such that the cost could be minimized. :[font = subsection; inactive; preserveAspect; startGroup] Examples :[font = input; preserveAspect; startGroup] HillClimbing[polynomiallocal, EvaluationFunction -> InitEvalPoly, SuccessorFunction -> PolySuccessorFunction] :[font = output; output; inactive; preserveAspect; endGroup] {{x*(A + x*(B + x*(C + x*(D + E*x))))}} ;[o] {{x (A + x (B + x (C + x (D + E x))))}} :[font = text; inactive; preserveAspect; endGroup; endGroup] Note: The optimal form has been achieved using the hill climbing algorithm. ;[s] 2:0,0;6,1;76,-1; 2:1,0,0 ,times,0,12,65535,0,0;1,0,0 ,times,0,12,0,0,0; :[font = section; inactive; preserveAspect; startGroup] Simulated Annealing :[font = text; inactive; preserveAspect] Simulated annealing is the second algorithm used in this context which uses a heuristic for an intelligent search. Instead of starting again randomly when stuck on a local maximum, the algorithm allows some downhill steps to escape the local maximum. The innermost loop of the simulated annealing is quite similar to hill climbing. Instead of picking the best move, however, it picks a random move. If the move actually improves the situation, it is always executed. Otherwise, the algorithm makes the move with some probability less than one. The probability decreases exponentially with the "badness" of the move by the amount deltaE by which the evaluation is worsened. A second parameter temperature is also used to determine the probability. At higher values of temperature, "bad" moves are more likely to be allowed. A temperature tends to zero, they become more and more unlikely, until the algorithm behaves more or less like hill climbing. The schedule input determines the value of temperature as a function of how many cycles already have been completed. The algorithm was developed from an explicit analogy with annealing-the process of gradually cooling a liquid until it freezes. The evaluation function corresponds to the total energy of the atoms in the material. Schedule determines the rate at which the temperature is lowered. Individual moves in the state space correspond to random fluctuations due to thermal noise. One can prove that if the temperature is lowered sufficiently slowly, the material will attain a lowest-energy (perfectly) ordered configuration.This corresponds to the statement that if the schedule lowers the temperature slowly enough, the algorithm will find a global optimum. :[font = subsection; inactive; preserveAspect; startGroup] Examples :[font = input; preserveAspect; startGroup] SimulatedAnnealing[polynomiallocal, EvaluationFunction -> InitEvalPoly, SuccessorFunction -> PolySuccessorFunction, MaxIterations -> 100] :[font = output; output; inactive; preserveAspect; endGroup] {x*(A + D*x^3 + x*(B + x*(C + E*x^2)))} ;[o] 3 2 {x (A + D x + x (B + x (C + E x )))} :[font = input; preserveAspect; startGroup] SimulatedAnnealing[polynomiallocal, EvaluationFunction -> InitEvalPoly, SuccessorFunction -> PolySuccessorFunction, MaxIterations -> 500] :[font = output; output; inactive; preserveAspect; endGroup] {x*(A + D*x^3 + x*(B + x*(C + E*x^2)))} ;[o] 3 2 {x (A + D x + x (B + x (C + E x )))} :[font = text; inactive; preserveAspect; endGroup; endGroup] Note: Not a quite optimal form has been achieved because the default cooling function does not cool slowly enough. :[font = section; inactive; preserveAspect; startGroup] Reference Manual :[font = text; inactive; preserveAspect] The functions used by the four search algorithms which are also available for the public usage include following. :[font = text; inactive; preserveAspect] General Algorithm Usage Functions: The following functions could be found in the package named "GENERAL`GeneralSearch`" ;[s] 3:0,0;34,1;95,2;119,-1; 3:1,0,0 ,times,0,12,65535,0,0;1,0,0 ,times,0,12,0,0,0;1,0,0 ,times,0,12,0,0,65535; :[font = text; inactive; preserveAspect] DefaultEvaluationFunction TheSmallest RuleBasedSuccessorFunction GoalFun GoalTest ;[s] 1:0,0;81,-1; 1:1,0,0 ,times,0,12,0,65535,0; :[font = text; inactive; preserveAspect] Polynomial Manipulation Functions: The following functions could be found in the package named "GENERAL`PolySearchFunctions`" ;[s] 3:0,0;34,1;95,2;125,-1; 3:1,0,0 ,times,0,12,65535,0,0;1,0,0 ,times,0,12,0,0,0;1,0,0 ,times,0,12,0,0,65535; :[font = text; inactive; preserveAspect] EvalPoly InitEvalPoly PolySuccessorFunction ;[s] 1:0,0;43,-1; 1:1,0,0 ,times,0,12,0,65535,0; :[font = text; inactive; preserveAspect] For the complete usage information of the functions, use :[font = input; preserveAspect; endGroup] ?EvalPoly :[font = section; inactive; preserveAspect; startGroup] References :[font = text; inactive; preserveAspect] [1] S. Wolfram, Mathematica: A System for Doing Mathematics by Computer, Redwood City, CA: Addison-Wesley, second ed., 1991. ;[s] 3:0,0;16,1;72,2;124,-1; 3:1,0,0 ,times,0,12,0,0,0;1,0,0 ,times,2,12,0,0,0;1,0,0 ,times,0,12,0,0,0; :[font = text; inactive; preserveAspect; endGroup; endGroup] [2] S. Russel and P. Norvig, Artificial Intelligence: A Modern Approach. Englewood Cliffs, NJ: Prentice Hall, 1995. ;[s] 3:0,0;29,1;71,2;117,-1; 3:1,0,0 ,times,0,12,0,0,0;1,0,0 ,times,2,12,0,0,0;1,0,0 ,times,0,12,0,0,0; ^*)