<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://en.formulasearchengine.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=93.173.53.113</id>
	<title>formulasearchengine - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://en.formulasearchengine.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=93.173.53.113"/>
	<link rel="alternate" type="text/html" href="https://en.formulasearchengine.com/wiki/Special:Contributions/93.173.53.113"/>
	<updated>2026-05-22T10:12:07Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.0-wmf.28</generator>
	<entry>
		<id>https://en.formulasearchengine.com/index.php?title=Histogram_matching&amp;diff=24925</id>
		<title>Histogram matching</title>
		<link rel="alternate" type="text/html" href="https://en.formulasearchengine.com/index.php?title=Histogram_matching&amp;diff=24925"/>
		<updated>2014-01-29T22:24:52Z</updated>

		<summary type="html">&lt;p&gt;93.173.53.113: /* References */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Technical|date=November 2009}}&lt;br /&gt;
{{graph search algorithm}}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;SMA*&#039;&#039;&#039; or &#039;&#039;&#039;Simplified Memory Bounded A*&#039;&#039;&#039; is a [[shortest path algorithm]] based on the [[A*]] algorithm. The main advantage of SMA* is that it uses a bounded memory, while the A* algorithm might need exponential memory. All other characteristics of SMA* are inherited from A*.&lt;br /&gt;
&lt;br /&gt;
== Process ==&lt;br /&gt;
&lt;br /&gt;
Like A*, it expands the most promising branches according to the heuristic. What sets SMA* apart is that it prunes nodes whose expansion has revealed less promising than expected. The approach allows the algorithm to explore branches and backtrack to explore other branches.&lt;br /&gt;
&lt;br /&gt;
Expansion and pruning of nodes is driven by keeping two values of &amp;lt;math&amp;gt;f&amp;lt;/math&amp;gt; for every node. Node &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; stores a value &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; which estimates the cost of reaching the goal by taking a path through that node. The lower the value, the higher the priority. As in A* this value is initialized to &amp;lt;math&amp;gt;f(x)+g(x)&amp;lt;/math&amp;gt;, but will then be updated to reflect changes to this estimate when its children are expanded. A fully expanded node will have an &amp;lt;math&amp;gt;f&amp;lt;/math&amp;gt; value at least as high as that of its successors. In addition, the node stores the &amp;lt;math&amp;gt;f&amp;lt;/math&amp;gt; value of the best forgotten successor. This value is restored if the forgotten successor is revealed to be the most promising successor.&lt;br /&gt;
&lt;br /&gt;
Starting with the first node, it maintains OPEN, ordered lexicographically by &amp;lt;math&amp;gt;f&amp;lt;/math&amp;gt; and depth. When chosing a node to expand, it choses the best according to that order. When selecting a node to prune, it choses the worst.&lt;br /&gt;
&lt;br /&gt;
== Properties ==&lt;br /&gt;
&lt;br /&gt;
SMA* has the following properties&lt;br /&gt;
&lt;br /&gt;
* It works with a [[heuristic]], just as A*&lt;br /&gt;
* It is complete if the allowed memory is high enough to store the shallowest solution&lt;br /&gt;
* It is optimal if the allowed memory is high enough to store the shallowest optimal solution, otherwise it will return the best solution that fits in the allowed memory&lt;br /&gt;
* It avoids repeated states as long as the memory bound allows it&lt;br /&gt;
* It will use all memory available&lt;br /&gt;
* Enlarging the memory bound of the algorithm will only speed up the calculation&lt;br /&gt;
* When enough memory is available to contain the entire search tree, then calculation has an optimal speed&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
&lt;br /&gt;
The implementation of SMA* is very similar to the one of A*, the only difference is that when there isn&#039;t any space left, nodes with the highest f-cost are pruned from the queue. Because those nodes are deleted, the SMA* also has to remember the f-cost of the best forgotten child with the parent node. When it seems that all explored paths are worse than such a forgotten path, the path is re-generated.&amp;lt;ref&amp;gt;{{cite conference | last = Russell | first = S. | year = 1992 | id = {{citeseerx|10.1.1.105.7839}} | title = Efficient memory-bounded search methods | booktitle = Proceedings of the 10th European Conference on Artificial intelligence | location = Vienna, Austria | editor-first = B. | editor-last = Neumann | publisher = John Wiley &amp;amp; Sons, New York, NY | pages = 1–5 }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pseudo code:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;&lt;br /&gt;
function SMA-star(problem): path&lt;br /&gt;
  queue: set of nodes, ordered by f-cost;&lt;br /&gt;
begin&lt;br /&gt;
  queue.insert(problem.root-node);&lt;br /&gt;
&lt;br /&gt;
  while True do begin&lt;br /&gt;
    if queue.empty() then return failure; //there is no solution that fits in the given memory&lt;br /&gt;
    node := queue.begin(); // min-f-cost-node&lt;br /&gt;
    if problem.is-goal(node) then return success;&lt;br /&gt;
    &lt;br /&gt;
    s := next-successor(node)&lt;br /&gt;
    if !problem.is-goal(s) &amp;amp;&amp;amp; depth(s) == max_depth then&lt;br /&gt;
        f(s) := inf; &lt;br /&gt;
        // there is no memory left to go past s, so the entire path is useless&lt;br /&gt;
    else&lt;br /&gt;
        f(s) := max(f(node), g(s) + h(s));&lt;br /&gt;
        // f-value of the successor is the maximum of&lt;br /&gt;
        //      f-value of the parent and &lt;br /&gt;
        //      heuristic of the successor + path length to the successor&lt;br /&gt;
    endif&lt;br /&gt;
    if no more successors then&lt;br /&gt;
       update node-s f-cost and those of its ancestors if needed&lt;br /&gt;
    &lt;br /&gt;
    if node.successors ⊆ queue then queue.remove(node); &lt;br /&gt;
    // all children have already been added to the queue via a shorter way&lt;br /&gt;
    if memory is full then begin&lt;br /&gt;
      badNode := shallowest node with highest f-cost;&lt;br /&gt;
      for parent in badNode.parents do begin&lt;br /&gt;
        parent.successors.remove(badNode);&lt;br /&gt;
        if needed then queue.insert(parent); &lt;br /&gt;
      endfor&lt;br /&gt;
    endif&lt;br /&gt;
&lt;br /&gt;
    queue.insert(s);&lt;br /&gt;
  endwhile&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
{{Reflist}}&lt;br /&gt;
&lt;br /&gt;
{{DEFAULTSORT:Sma}}&lt;br /&gt;
[[Category:Graph algorithms]]&lt;br /&gt;
[[Category:Routing algorithms]]&lt;br /&gt;
[[Category:Search algorithms]]&lt;br /&gt;
[[Category:Game artificial intelligence]]&lt;br /&gt;
[[Category:Articles with example pseudocode]]&lt;/div&gt;</summary>
		<author><name>93.173.53.113</name></author>
	</entry>
</feed>