The AO* algorithm is an advanced search algorithm utilized in artificial intelligence, particularly in problem-solving and decision-making contexts. It is an extension of the A* algorithm, designed to handle more complex problems that require handling multiple paths and making decisions at each node.
This article will provide an overview of the AO* algorithm, its working principles, applications, advantages, and limitations.
Overview of AO* Algorithm
The AO algorithm* (short for “And-Or Star”) is a powerful best-first search method used to solve problems that can be represented as a directed acyclic graph (DAG). Unlike traditional algorithms like A*, which explore a single path, the AO* algorithm evaluates multiple paths simultaneously. This makes it more efficient for problems that involve AND-OR nodes. The AND nodes represent tasks where all child nodes must be satisfied, while OR nodes offer multiple alternative paths where only one child node needs to be satisfied to achieve the goal.
Example of AO* Algorithm
In the figure, we consider the process of buying a car. This process can be broken down into smaller tasks using an AND-OR graph. The AND section might include securing funds or applying for a loan, while the OR section could present different options for acquiring the car, such as purchasing with cash or financing. Each subproblem in the AND-OR graph must be solved before the main issue is resolved.

AND-OR Graph
The AO* algorithm uses knowledge-based search, where both the start and target states are predefined. By leveraging heuristics, it identifies the best path, significantly reducing time complexity. Compared to the A algorithm*, AO* is more efficient when solving problems represented as AND-OR graphs, as it evaluates multiple paths at once.
This combination of best-first search, DAG representation, and heuristic optimization makes the AO algorithm* ideal for tackling complex problems that can be divided into interdependent tasks. Incorporating these techniques ensures faster and more effective problem-solving.
Working Principles of AO* Algorithm
The AO* algorithm works by utilizing a tree structure where each node represents a state in the problem space. The key components of the algorithm are:
Node Types
- AND Nodes: Represent states where all child nodes must be satisfied to achieve a goal. If a task requires multiple conditions to be met, it would be represented as an AND node.
- OR Nodes: Represent states where at least one child node must be satisfied to achieve a goal. This type is useful in scenarios where multiple paths can lead to a solution.
Heuristic Function
The algorithm employs a heuristic function, similar to A*, to estimate the cost to reach the goal from any given node. This function helps in determining the most promising paths to explore. The heuristic function [Tex]h(n)[/Tex] estimates the cost to reach the goal from node [Tex]n[/Tex]:
[Tex]h(n) = \text{estimated cost to reach the goal from node } [/Tex]
Search Process
The search begins at the initial node and explores its child nodes based on the type (AND or OR). The costs associated with nodes are calculated using the following principles:
- For OR Nodes: The algorithm considers the lowest cost among the child nodes. The cost for an OR node can be expressed as:
[Tex]C(n) = \min \{ C(c_1), C(c_2), \ldots, C(c_k) \}[/Tex]
where [Tex]C(n)[/Tex] is the cost of node [Tex]n[/Tex] and [Tex]c_1, c_2, \ldots, c_k[/Tex]​ are the child nodes of [Tex]n[/Tex].
- For AND Nodes: The algorithm computes the cost of all child nodes and selects the maximum cost, as all conditions must be met. The cost for an AND node can be expressed as:
[Tex]C(n) = \max \{ C(c_1), C(c_2), \ldots, C(c_k) \}[/Tex]
where [Tex]C(n)[/Tex] is the cost of node [Tex]n[/Tex], and [Tex]c_1, c_2, \ldots, c_k[/Tex]​ are the child nodes of [Tex]n[/Tex].
Total Estimated Cost
The total estimated cost [Tex]f(n)[/Tex] at any node [Tex]n[/Tex] is given by:
[Tex]f(n)=C(n)+h(n)[/Tex]
where:
- [Tex]C(n)[/Tex] is the actual cost to reach node [Tex]n[/Tex] from the start node.
- [Tex]h(n)[/Tex] is the estimated cost from node [Tex]n[/Tex] to the goal.
In summary:
[Tex]f(n) = \text{Actual cost} + \text{Estimated cost}[/Tex]
The search continues recursively until the goal is reached or all possibilities are exhausted.
Comparison between A* Algorithm and AO* algorithm
Aspect | A Algorithm* | AO Algorithm* |
---|
Search Type | Best-first search | Best-first search |
Type of Search | Informed search using heuristics | Informed search using heuristics |
Solution Optimality | Always gives the optimal solution | Does not guarantee an optimal solution |
Path Exploration | Explores all possible paths | Stops exploring once a solution is found |
Memory Usage | Uses more memory | Uses less memory |
Endless Loop | May go into an endless loop without proper checks | Cannot go into an endless loop |
Example of AO* Algorithm with AND-OR Graph
In this example, we will demonstrate how the AO algorithm* works using an AND-OR graph. Each node in the graph is assigned a heuristic value, denoted as h(n), and the edge length is considered as 1.

AO* Algorithm – Question tree
Step 1: Initial Evaluation Using f(n) = g(n) + h(n)
Starting from node A, we use the evaluation function:
f(A -> B) = g(B) + h(B)
= 1 + 5 (g(n) = 1 is the default path cost)
= 6
For the path involving AND nodes (C and D):
f(A -> C + D) = g(C) + h(C) + g(D) + h(D)
= 1 + 2 + 1 + 4 (C & D are AND nodes)
= 8
Since f(A -> B) = 6 is smaller than f(A -> C + D) = 8, we select the path A -> B.

AO* Algorithm (Step-1)
Step 2: Explore Node B
Next, we explore node B, and calculate the values for nodes E and F:
f(B -> E) = g(E) + h(E)
= 1 + 7
= 8
f(B -> F) = g(F) + h(F)
= 1 + 9
= 10
So, by above calculation B⇢E path is chosen which is minimum path, i.e f(B⇢E) because B’s heuristic value is different from its actual value The heuristic is updated and the minimum cost path is selected. The minimum value in our situation is 8. Therefore, the heuristic for A must be updated due to the change in B’s heuristic.
So we need to calculate it again.
Thus, f(B -> E) = 8 is chosen as the optimal path. Since B’s heuristic value differs from its actual cost, we update the heuristic for A.
f(A -> B) = g(B) + updated h(B)
= 1 + 8
= 9

AO* Algorithm (Step-2)
Step 3: Compare and Explore Paths
Now, we compare f(A -> B) = 9 with f(A -> C + D) = 8. Since f(A -> C + D) is smaller, we explore this path and move to node C.
For node C:
f(C -> G) = g(G) + h(G)
= 1 + 3
= 4
f(C -> H + I) = g(H) + h(H) + g(I) + h(I)
= 1 + 0 + 1 + 0 (H & I are AND nodes)
= 2
f(C⇢H+I) is selected as the path with the lowest cost and the heuristic is also left unchanged because it matches the actual cost. Paths H & I are solved because the heuristic for those paths is 0, but Path A⇢D needs to be calculated because it has an AND.
The path f(C -> H + I) = 2 is selected. Since the heuristic for H and I matches the actual cost (both are 0), these paths are considered solved. Next, we calculate the value for A -> D as it also has an AND node.
For node D:
f(D -> J) = g(J) + h(J)
= 1 + 0
= 1
After updating the heuristic for D, we recalculate:
f(A -> C + D) = g(C) + h(C) + g(D) + h(D)
= 1 + 2 + 1 + 1
= 5
Now that f(A -> C + D) has the lowest cost, this becomes the solved path, and the AND-OR graph is now fully resolved.

AO* Algorithm (Step-3) -Geeksforgeeks
The key flow of the AO algorithm* involves first calculating heuristic values for each level, then updating these values from the leaf nodes upward to the root node. In this example, we systematically updated all the node values in the tree.
By optimizing your content with relevant keywords such as AO algorithm*, AND-OR graph, heuristics, and search problems in AI, you can significantly improve SEO rankings for AI-related topics.
Cost Optimization in AND-OR Graphs using AO Algorithm for Pathfinding
This example demonstrates the application of the AO* (AND-OR) algorithm to optimize pathfinding in a problem with complex dependencies. The algorithm explores paths defined by AND and OR conditions, calculating the least-cost solution by dynamically updating node costs. The AND conditions require all connected nodes to be considered, while the OR conditions allow selecting the least expensive option.
C++
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static Dictionary<string, int> Cost(Dictionary<string, int> H,
Dictionary<string, List<string>> condition,
int weight = 1)
{
Dictionary<string, int> cost = new Dictionary<string, int>();
if (condition.ContainsKey("AND"))
{
List<string> AND_nodes = condition["AND"];
string Path_A = string.Join(" AND ", AND_nodes);
int PathA = AND_nodes.Sum(node => H[node] + weight);
cost[Path_A] = PathA;
}
if (condition.ContainsKey("OR"))
{
List<string> OR_nodes = condition["OR"];
string Path_B = string.Join(" OR ", OR_nodes);
int PathB = OR_nodes.Min(node => H[node] + weight);
cost[Path_B] = PathB;
}
return cost;
}
static Dictionary<string, Dictionary<string, int>> UpdateCost(Dictionary<string, int> H, Dictionary<string, Dictionary<string, List<string>>> Conditions, int weight = 1)
{
List<string> Main_nodes = new List<string>(Conditions.Keys);
Main_nodes.Reverse();
Dictionary<string, Dictionary<string, int>> least_cost = new Dictionary<string, Dictionary<string, int>>();
foreach (string key in Main_nodes)
{
Dictionary<string, List<string>> condition = Conditions[key];
Console.WriteLine("{0}: {1} >>> {2}", key, condition, Cost(H, condition, weight));
Dictionary<string, int> c = Cost(H, condition, weight);
H[key] = c.Values.Min();
least_cost[key] = Cost(H, condition, weight);
}
return least_cost;
}
static string ShortestPath(string Start, Dictionary<string, Dictionary<string, int>> Updated_cost, Dictionary<string, int> H)
{
string Path = Start;
if (Updated_cost.ContainsKey(Start))
{
int Min_cost = Updated_cost[Start].Values.Min();
List<string> key = new List<string>(Updated_cost[Start].Keys);
List<int> values = new List<int>(Updated_cost[Start].Values);
int Index = values.IndexOf(Min_cost);
// FIND MINIMIMUM PATH KEY
List<string> Next = key[Index].Split().ToList();
// ADD TO PATH FOR OR PATH
if (Next.Count == 1)
{
Start = Next[0];
Path += "<--" + ShortestPath(Start, Updated_cost, H);
}
// ADD TO PATH FOR AND PATH
else
{
Path += "<--(" + key[Index] + ") ";
Start = Next[0];
Path += "[" + ShortestPath(Start, Updated_cost, H) + " + ";
Start = Next[Next.Count - 1];
Path += ShortestPath(Start, Updated_cost, H) + "]";
}
}
return Path;
}
static void Main(string[] args) {
var H = new Dictionary<string, int> {
{"A", -1},
{"B", 5},
{"C", 2},
{"D", 4},
{"E", 7},
{"F", 9},
{"G", 3},
{"H", 0},
{"I", 0},
{"J", 0},
};
var Conditions = new Dictionary<string, Dictionary<string, List<string>>> {
{"A", new Dictionary<string, List<string>> {
{"OR", new List<string>{"B"}},
{"AND", new List<string>{"C", "D"}},
}
},
{"B", new Dictionary<string, List<string>> {
{"OR", new List<string>{"E",
"F"}},
}
},
{"C", new Dictionary<string, List<string>> {
{"OR", new List<string>{"G"}},
{"AND", new List<string>{"H", "I"}},
}
},
{"D", new Dictionary<string, List<string>> {
{"OR", new List<string>{"J"}},
}
},
};
// weight
int weight = 1;
// Updated cost
Console.WriteLine("Updated Cost :");
var Updated_cost = UpdateCost(H, Conditions, weight: 1);
Console.WriteLine("*".PadLeft(75, '*'));
Console.WriteLine("Shortest Path :");
Console.WriteLine(ShortestPath("A", Updated_cost, H));
}
}
Java
import java.util.*;
public class Main {
public static Map<String, Integer>
Cost(Map<String, Integer> H,
Map<String, List<String> > condition, int weight)
{
Map<String, Integer> cost = new HashMap<>();
if (condition.containsKey("AND")) {
List<String> AND_nodes = condition.get("AND");
String Path_A = String.join(" AND ", AND_nodes);
int PathA
= AND_nodes.stream()
.mapToInt(
node -> H.get(node) + weight)
.sum();
cost.put(Path_A, PathA);
}
if (condition.containsKey("OR")) {
List<String> OR_nodes = condition.get("OR");
String Path_B = String.join(" OR ", OR_nodes);
int PathB
= OR_nodes.stream()
.mapToInt(
node -> H.get(node) + weight)
.min()
.getAsInt();
cost.put(Path_B, PathB);
}
return cost;
}
public static Map<String, Map<String, Integer> >
UpdateCost(
Map<String, Integer> H,
Map<String, Map<String, List<String> > > Conditions,
int weight)
{
List<String> Main_nodes
= new ArrayList<>(Conditions.keySet());
Collections.reverse(Main_nodes);
Map<String, Map<String, Integer> > least_cost
= new HashMap<>();
for (String key : Main_nodes) {
Map<String, List<String> > condition
= Conditions.get(key);
System.out.printf("%s: %s >>> %s%n", key,
condition,
Cost(H, condition, weight));
Map<String, Integer> c
= Cost(H, condition, weight);
H.put(key, Collections.min(c.values()));
least_cost.put(key, Cost(H, condition, weight));
}
return least_cost;
}
public static String ShortestPath(
String Start,
Map<String, Map<String, Integer> > Updated_cost,
Map<String, Integer> H)
{
String Path = Start;
if (Updated_cost.containsKey(Start)) {
int Min_cost = Collections.min(
Updated_cost.get(Start).values());
List<String> key = new ArrayList<>(
Updated_cost.get(Start).keySet());
List<Integer> values = new ArrayList<>(
Updated_cost.get(Start).values());
int Index = values.indexOf(Min_cost);
List<String> Next
= Arrays.asList(key.get(Index).split(" "));
if (Next.size() == 1) {
Start = Next.get(0);
Path += "<--"
+ ShortestPath(Start, Updated_cost,
H);
}
else {
Path += "<--(" + key.get(Index) + ") ";
Start = Next.get(0);
Path += "["
+ ShortestPath(Start, Updated_cost,
H)
+ " + ";
Start = Next.get(Next.size() - 1);
Path += ShortestPath(Start, Updated_cost, H)
+ "]";
}
}
return Path;
}
public static void main(String[] args)
{
Map<String, Integer> H = new HashMap<>();
H.put("A", -1);
H.put("B", 5);
H.put("C", 2);
H.put("D", 4);
H.put("E", 7);
H.put("F", 9);
H.put("G", 3);
H.put("H", 0);
H.put("I", 0);
H.put("J", 0);
Map<String, Map<String, List<String> > > Conditions
= new HashMap<>();
Map<String, List<String> > aConditions
= new HashMap<>();
aConditions.put("OR", Arrays.asList("B"));
aConditions.put("AND", Arrays.asList("C", "D"));
Conditions.put("A", aConditions);
Map<String, List<String> > bConditions
= new HashMap<>();
bConditions.put("OR", Arrays.asList("E", "F"));
Conditions.put("B", bConditions);
Map<String, List<String> > cConditions
= new HashMap<>();
cConditions.put("OR", Arrays.asList("G"));
cConditions.put("AND", Arrays.asList("H", "I"));
Conditions.put("C", cConditions);
Map<String, List<String> > dConditions
= new HashMap<>();
dConditions.put("OR", Arrays.asList("J"));
Conditions.put("D", dConditions);
// weight
int weight = 1;
// Updated cost
System.out.println("Updated Cost :");
Map<String, Map<String, Integer> > Updated_cost
= UpdateCost(H, Conditions, weight);
System.out.println("*".repeat(75));
System.out.println("Shortest Path :");
System.out.println(
ShortestPath("A", Updated_cost, H));
}
}
Python
def Cost(H, condition, weight = 1):
cost = {}
if 'AND' in condition:
AND_nodes = condition['AND']
Path_A = ' AND '.join(AND_nodes)
PathA = sum(H[node]+weight for node in AND_nodes)
cost[Path_A] = PathA
if 'OR' in condition:
OR_nodes = condition['OR']
Path_B = ' OR '.join(OR_nodes)
PathB = min(H[node]+weight for node in OR_nodes)
cost[Path_B] = PathB
return cost
# Update the cost
def update_cost(H, Conditions, weight=1):
Main_nodes = list(Conditions.keys())
Main_nodes.reverse()
least_cost = {}
for key in Main_nodes:
condition = Conditions[key]
print(key, ':', Conditions[key], '>>>', Cost(H, condition, weight))
c = Cost(H, condition, weight)
H[key] = min(c.values())
least_cost[key] = Cost(H, condition, weight)
return least_cost
# Print the shortest path
def shortest_path(Start, Updated_cost, H):
Path = Start
if Start in Updated_cost.keys():
Min_cost = min(Updated_cost[Start].values())
key = list(Updated_cost[Start].keys())
values = list(Updated_cost[Start].values())
Index = values.index(Min_cost)
# FIND MINIMUM PATH KEY
Next = key[Index].split()
# ADD TO PATH FOR OR PATH
if len(Next) == 1:
Start = Next[0]
Path += '<--' + shortest_path(Start, Updated_cost, H)
# ADD TO PATH FOR AND PATH
else:
Path += '<--('+key[Index]+') '
Start = Next[0]
Path += '[' + shortest_path(Start, Updated_cost, H) + ' + '
Start = Next[-1]
Path += shortest_path(Start, Updated_cost, H) + ']'
return Path
# Final Code with Visualization
import networkx as nx
import matplotlib.pyplot as plt
# Visualization of the graph based on the provided conditions
def visualize_graph(conditions, updated_cost, H):
G = nx.DiGraph()
# Add nodes and edges
for node, condition in conditions.items():
if 'AND' in condition:
for n in condition['AND']:
G.add_edge(node, n, label='AND', color='green')
if 'OR' in condition:
for n in condition['OR']:
G.add_edge(node, n, label='OR', color='blue')
pos = nx.spring_layout(G) # positions for all nodes
labels = nx.get_edge_attributes(G, 'label')
colors = [G[u][v]['color'] for u, v in G.edges]
# Draw the graph
plt.figure(figsize=(8, 6))
nx.draw(G, pos, with_labels=True, node_color='lightblue', node_size=2000, font_size=10, font_weight='bold', edge_color=colors, arrows=True)
nx.draw_networkx_edge_labels(G, pos, edge_labels=labels, font_color='red')
plt.title('AND-OR Path Graph')
plt.show()
# Example Usage:
H = {'A': -1, 'B': 5, 'C': 2, 'D': 4, 'E': 7, 'F': 9, 'G': 3, 'H': 0, 'I': 0, 'J': 0}
Conditions = {
'A': {'OR': ['B'], 'AND': ['C', 'D']},
'B': {'OR': ['E', 'F']},
'C': {'OR': ['G'], 'AND': ['H', 'I']},
'D': {'OR': ['J']}
}
# Weight
weight = 1
# Updated cost
print('Updated Cost:')
Updated_cost = update_cost(H, Conditions, weight)
print('*' * 75)
# Shortest Path
print('Shortest Path:\n', shortest_path('A', Updated_cost, H))
# Visualize the graph
visualize_graph(Conditions, Updated_cost, H)
JavaScript
// Cost to find the AND and OR path
function Cost(H, condition, weight = 1) {
let cost = {};
if ('AND' in condition) {
let AND_nodes = condition['AND'];
let Path_A = AND_nodes.join(' AND ');
let PathA = AND_nodes.reduce((total, node) => total + H[node] + weight, 0);
cost[Path_A] = PathA;
}
if ('OR' in condition) {
let OR_nodes = condition['OR'];
let Path_B = OR_nodes.join(' OR ');
let PathB = Math.min(...OR_nodes.map(node => H[node] + weight));
cost[Path_B] = PathB;
}
return cost;
}
// Update the cost
function update_cost(H, Conditions, weight=1) {
let Main_nodes = Object.keys(Conditions).reverse();
let least_cost = {};
for (let i = 0; i < Main_nodes.length; i++) {
let key = Main_nodes[i];
let condition = Conditions[key];
console.log(key + ' : ' + JSON.stringify(Conditions[key]) + ' >>> ' + JSON.stringify(Cost(H, condition, weight)));
let c = Cost(H, condition, weight);
H[key] = Math.min(...Object.values(c));
least_cost[key] = Cost(H, condition, weight);
}
return least_cost;
}
// Print the shortest path
function shortest_path(Start, Updated_cost, H) {
let Path = Start;
if (Start in Updated_cost) {
let Min_cost = Math.min(...Object.values(Updated_cost[Start]));
let keys = Object.keys(Updated_cost[Start]);
let values = Object.values(Updated_cost[Start]);
let Index = values.indexOf(Min_cost);
// FIND MINIMIMUM PATH KEY
let Next = keys[Index].split(' ');
// ADD TO PATH FOR OR PATH
if (Next.length == 1) {
Start = Next[0];
Path += '<--' + shortest_path(Start, Updated_cost, H);
}
// ADD TO PATH FOR AND PATH
else {
Path += '<--(' + keys[Index] + ') ';
Start = Next[0];
Path += '[' + shortest_path(Start, Updated_cost, H) + ' + ';
Start = Next[Next.length - 1];
Path += shortest_path(Start, Updated_cost, H) + ']';
}
}
return Path;
}
let H = {'A': -1, 'B': 5, 'C': 2, 'D': 4, 'E': 7, 'F': 9, 'G': 3, 'H': 0, 'I':0, 'J':0};
let Conditions = {
'A': {'OR': ['B'], 'AND': ['C', 'D']},
'B': {'OR': ['E', 'F']},
'C': {'OR': ['G'], 'AND': ['H', 'I']},
'D': {'OR': ['J']}
};
// weight
let weight = 1;
// Updated cost
console.log('Updated Cost:');
let Updated_cost = update_cost(H, Conditions, weight);
console.log('*'.repeat(75));
console.log('Shortest Path:\n' + shortest_path('A', Updated_cost, H));
Output:
Updated Cost:
D : {'OR': ['J']} >>> {'J': 1}
C : {'OR': ['G'], 'AND': ['H', 'I']} >>> {'H AND I': 2, 'G': 4}
B : {'OR': ['E', 'F']} >>> {'E OR F': 8}
A : {'OR': ['B'], 'AND': ['C', 'D']} >>> {'C AND D': 5, 'B': 9}
***************************************************************************
Shortest Path:
A<--(C AND D) [C<--(H AND I) [H + I] + D<--J]

The approach efficiently identifies the optimal path through iterative updates, leveraging the AO* strategy to handle branching and dependencies, commonly used in problem-solving graphs like decision trees or task scheduling.
AND-OR Pathfinding with Heuristic Optimization Using AO Algorithm*
This code demonstrates the AO* algorithm to find the optimal path in an AND-OR graph. It calculates the cost of different paths using heuristic values, identifies the least-cost paths based on AND/OR conditions, and visualizes the decision graph. The shortest path is derived by minimizing the cost through dynamic updates.
Python
# Cost to find the AND and OR path
def Cost(H, condition, weight=1):
cost = {}
if 'AND' in condition:
AND_nodes = condition['AND']
Path_A = ' AND '.join(AND_nodes)
PathA = sum(H[node] + weight for node in AND_nodes)
cost[Path_A] = PathA
if 'OR' in condition:
OR_nodes = condition['OR']
Path_B = ' OR '.join(OR_nodes)
PathB = min(H[node] + weight for node in OR_nodes)
cost[Path_B] = PathB
return cost
# Update the cost
def update_cost(H, Conditions, weight=1):
Main_nodes = list(Conditions.keys())
Main_nodes.reverse()
least_cost = {}
for key in Main_nodes:
condition = Conditions[key]
print(key, ':', Conditions[key], '>>>', Cost(H, condition, weight))
c = Cost(H, condition, weight)
H[key] = min(c.values())
least_cost[key] = Cost(H, condition, weight)
return least_cost
# Print the shortest path
def shortest_path(Start, Updated_cost, H):
Path = Start
if Start in Updated_cost.keys():
Min_cost = min(Updated_cost[Start].values())
key = list(Updated_cost[Start].keys())
values = list(Updated_cost[Start].values())
Index = values.index(Min_cost)
# FIND MINIMUM PATH KEY
Next = key[Index].split()
# ADD TO PATH FOR OR PATH
if len(Next) == 1:
Start = Next[0]
Path += ' = ' + shortest_path(Start, Updated_cost, H)
# ADD TO PATH FOR AND PATH
else:
Path += '=('+key[Index]+') '
Start = Next[0]
Path += '[' + shortest_path(Start, Updated_cost, H) + ' + '
Start = Next[-1]
Path += shortest_path(Start, Updated_cost, H) + ']'
return Path
# Additional Code for Visualization
import networkx as nx
import matplotlib.pyplot as plt
# Visualization of the graph based on the provided conditions
def visualize_graph(conditions, updated_cost, H):
G = nx.DiGraph()
# Add nodes and edges
for node, condition in conditions.items():
if 'AND' in condition:
for n in condition['AND']:
G.add_edge(node, n, label='AND', color='green')
if 'OR' in condition:
for n in condition['OR']:
G.add_edge(node, n, label='OR', color='blue')
pos = nx.spring_layout(G) # positions for all nodes
labels = nx.get_edge_attributes(G, 'label')
colors = [G[u][v]['color'] for u, v in G.edges]
# Draw the graph
plt.figure(figsize=(8, 6))
nx.draw(G, pos, with_labels=True, node_color='lightblue', node_size=2000, font_size=10, font_weight='bold', edge_color=colors, arrows=True)
nx.draw_networkx_edge_labels(G, pos, edge_labels=labels, font_color='red')
plt.title('AND-OR Path Graph with Heuristics')
plt.show()
# Example Usage:
# Heuristic values of Nodes
H1 = {'A': 1, 'B': 6, 'C': 2, 'D': 12, 'E': 2, 'F': 1, 'G': 5, 'H': 7, 'I': 7, 'J': 1, 'T': 3}
Conditions = {
'A': {'OR': ['D'], 'AND': ['B', 'C']},
'B': {'OR': ['G', 'H']},
'C': {'OR': ['J']},
'D': {'AND': ['E', 'F']},
'G': {'OR': ['I']}
}
# Weight
weight = 1
# Updated cost
print('Updated Cost:')
Updated_cost = update_cost(H1, Conditions, weight=1)
print('*' * 75)
# Shortest Path
print('Shortest Path:\n', shortest_path('A', Updated_cost, H1))
# Visualize the graph
visualize_graph(Conditions, Updated_cost, H1)
JavaScript
// Cost to find the AND and OR path
function Cost(H, condition, weight = 1) {
const cost = {};
if ('AND' in condition) {
const AND_nodes = condition['AND'];
const Path_A = AND_nodes.join(' AND ');
const PathA = AND_nodes.reduce((acc, node) => acc + H[node] + weight, 0);
cost[Path_A] = PathA;
}
if ('OR' in condition) {
const OR_nodes = condition['OR'];
const Path_B = OR_nodes.join(' OR ');
const PathB = Math.min(...OR_nodes.map((node) => H[node] + weight));
cost[Path_B] = PathB;
}
return cost;
}
// Update the cost
function update_cost(H, Conditions, weight = 1) {
const Main_nodes = Object.keys(Conditions).reverse();
const least_cost = {};
Main_nodes.forEach((key) => {
const condition = Conditions[key];
console.log(key, ':', Conditions[key], '>>>', Cost(H, condition, weight));
const c = Cost(H, condition, weight);
H[key] = Math.min(...Object.values(c));
least_cost[key] = Cost(H, condition, weight);
});
return least_cost;
}
// Print the shortest path
function shortest_path(Start, Updated_cost, H) {
let Path = Start;
if (Start in Updated_cost) {
const Min_cost = Math.min(...Object.values(Updated_cost[Start]));
const key = Object.keys(Updated_cost[Start]);
const values = Object.values(Updated_cost[Start]);
const Index = values.indexOf(Min_cost);
// FIND MINIMUM PATH KEY
const Next = key[Index].split(' ');
// ADD TO PATH FOR OR PATH
if (Next.length === 1) {
Start = Next[0];
Path += ' = ' + shortest_path(Start, Updated_cost, H);
}
// ADD TO PATH FOR AND PATH
else {
Path += '=(' + key[Index] + ') ';
Start = Next[0];
Path += '[' + shortest_path(Start, Updated_cost, H) + ' + ';
Start = Next[Next.length - 1];
Path += shortest_path(Start, Updated_cost, H) + ']';
}
}
return Path;
}
// Heuristic values of Nodes
const H1 = {
A: 1,
B: 6,
C: 2,
D: 12,
E: 2,
F: 1,
G: 5,
H: 7,
I: 7,
J: 1,
T: 3,
};
const Conditions = {
A: {
OR: ['D'],
AND: ['B', 'C']
},
B: {
OR: ['G', 'H']
},
C: {
OR: ['J']
},
D: {
AND: ['E', 'F']
},
G: {
OR: ['I']
},
};
// weight
const weight = 1;
// Updated cost
console.log('Updated Cost :');
const Updated_cost = update_cost(H1, Conditions, weight);
console.log('*'.repeat(75));
console.log('Shortest Path :\n', shortest_path('A', Updated_cost, H1));
// This code is contributed by rishabmalhdijo
Output:
Updated Cost:
G : {'OR': ['I']} >>> {'I': 8}
D : {'AND': ['E', 'F']} >>> {'E AND F': 5}
C : {'OR': ['J']} >>> {'J': 2}
B : {'OR': ['G', 'H']} >>> {'G OR H': 8}
A : {'OR': ['D'], 'AND': ['B', 'C']} >>> {'B AND C': 12, 'D': 6}
***************************************************************************
Shortest Path:
A = D=(E AND F) [E + F]

Real-Life Applications of AO* Algorithm in AI
- Vehicle Routing Problem: The AO* algorithm can be applied to determine the shortest routes for a fleet of vehicles, minimizing the total distance traveled and time taken while visiting a set of customers and returning to the depot.
- Portfolio Optimization: In financial portfolio optimization, the AO* algorithm can help choose the best set of investments that maximize returns and minimize risks. It explores different combinations of investments to find the optimal portfolio that satisfies both objectives.
In both cases, the AO* algorithm balances multiple conflicting goals, such as minimizing time and distance in vehicle routing or maximizing returns and minimizing risks in portfolio management. The algorithm starts with an initial solution and iteratively refines it, keeping the best solution that meets the objectives.
Advantages of AO* Algorithm in Artificial Intelligence
- Efficiency: AO* can efficiently handle complex decision trees by evaluating multiple paths simultaneously, which can significantly reduce the search space.
- Flexibility: The algorithm’s ability to deal with AND and OR nodes makes it versatile for various applications and problem types.
- Optimal Solutions: By using heuristic functions, AO* aims to find optimal solutions, similar to the A* algorithm.
Limitations of AO* Algorithm in AI
- Complexity: The algorithm can become computationally expensive, especially in highly complex graphs with many nodes and connections, as it must evaluate numerous possibilities.
- Memory Usage: AO* may require significant memory resources to store the nodes and paths being evaluated, which can be a limitation in resource-constrained environments.
- Dependency on Heuristics: The performance of AO* heavily relies on the quality of the heuristic function. A poorly designed heuristic can lead to suboptimal solutions and increased search times.
Conclusion
The AO* algorithm represents a powerful tool in the field of artificial intelligence for solving complex problems involving multiple decision paths. Its ability to handle AND and OR nodes allows for flexibility and efficiency in various applications, from gaming to robotics and natural language processing. However, practitioners must also be mindful of its limitations, particularly in terms of computational complexity and memory usage. Overall, AO* remains a valuable addition to the arsenal of algorithms available for AI problem-solving.
Similar Reads
Artificial Intelligence (AI) Algorithms
Artificial Intelligence (AI) is transforming industries and revolutionizing how we interact with technology. With a rising interest in Artificial Intelligence (AI) Algorithms, weâve created a comprehensive tutorial that covers core AI techniques, aimed at both beginners and experts in the field. The
9 min read
Mini-Max Algorithm in Artificial Intelligence
Mini-Max algorithm is a decision-making algorithm used in artificial intelligence, particularly in game theory and computer games. It is designed to minimize the possible loss in a worst-case scenario (hence "min") and maximize the potential gain (therefore "max"). Working of Min-Max Process in AIMi
7 min read
Local Search Algorithm in Artificial Intelligence
Local search algorithms are essential tools in artificial intelligence and optimization, employed to find high-quality solutions in large and complex problem spaces. Key algorithms include Hill-Climbing Search, Simulated Annealing, Local Beam Search, Genetic Algorithms, and Tabu Search. Each of thes
4 min read
Adversarial Search Algorithms in Artificial Intelligence (AI)
Adversarial search algorithms are the backbone of strategic decision-making in artificial intelligence, it enables the agents to navigate competitive scenarios effectively. This article offers concise yet comprehensive advantages of these algorithms from their foundational principles to practical ap
15+ min read
Informed Search Algorithms in Artificial Intelligence
Informed search algorithms, also known as heuristic search algorithms, are an essential component of Artificial Intelligence (AI). These algorithms use domain-specific knowledge to improve the efficiency of the search process, leading to faster and more optimal solutions compared to uninformed searc
10 min read
Artificial Intelligence(AI) in Tech
Artificial Intelligence is defined as an intelligent notion that is transforming technology and reshaping how organizations initiate, progress, and communicate with their customers. AI is termed as the replication of human intelligence processes in machines to make it possible for the machines to wo
5 min read
Iterative Deepening A* algorithm (IDA*) in Artificial intelligence
Iterative deepening A (IDA)** is a powerful graph traversal and pathfinding algorithm designed to find the shortest path in a weighted graph. This method combines features of iterative deepening depth-first search (IDDFS) and the A search algorithm* by using a heuristic function to estimate the rema
13 min read
Artificial General Intelligence Applications
Artificial General Intelligence offers the future scope to revolutionize virtually every aspect of human life - healthcare, finance, and transportation. Its ability to analyze data, make decisions, and adapt could revolutionize industries, improving efficiency and outcomes. Artificial General Intell
7 min read
Top 20 Applications of Artificial Intelligence (AI) in 2025
In 2025, the rapid advancements in technology have firmly established artificial intelligence (AI) as a cornerstone of innovation across various industries. From enhancing everyday experiences to driving groundbreaking discoveries, the application of AI continues to transform how we live and work. A
15+ min read
A* algorithm and its Heuristic Search Strategy in Artificial Intelligence
The A* (A-star) algorithm is a powerful and versatile search method used in computer science to find the most efficient path between nodes in a graph. Widely used in a variety of applications ranging from pathfinding in video games to network routing and AI, A* remains a foundational technique in th
8 min read