Dimana:
Dimana:
Dimana:
INITIALIZE:
τij = τ0 untuk semua edge (i,j) // Pheromone awal
best_solution = NULL
best_cost = ∞
FOR iteration = 1 to max_iterations:
FOR ant = 1 to num_ants:
solution = construct_solution(ant)
cost = evaluate(solution)
IF cost < best_cost:
best_cost = cost
best_solution = solution
update_pheromone(all_solutions)
RETURN best_solution
FUNCTION construct_solution(ant):
current = random_start_node()
solution = []
WHILE not_complete:
next = select_next_node(current, pheromone, heuristic)
solution.add(edge(current, next))
current = next
RETURN solution
FUNCTION select_next_node(current, τ, η):
FOR each allowed node j:
Pj = [τcurrent,jα × ηcurrent,jβ] / Σ
RETURN random_choice(probabilities)
FUNCTION update_pheromone(solutions):
// Evaporation
τij = (1 - ρ) × τij untuk semua edge
// Deposit
FOR each solution in solutions:
FOR each edge in solution:
τedge += Q / solution_cost
| Aspek | ACO Generic | ACO-MST |
|---|---|---|
| Goal | Various (TSP, VRP, etc) | Spanning Tree (connect all, no cycle) |
| Constraint | Problem-specific | NO CYCLE! |
| Edge Count | Varies | Exactly n-1 edges |
| Construction | Various strategies | Prim-like (grow tree from seed) |
| Edge Selection | From current node | From ANY node in tree to outside |
FUNCTION construct_MST_solution(ant):
current = random_start_node()
tree_nodes = {current}
tree_edges = []
WHILE |tree_nodes| < n:
// Find all candidate edges from tree to outside
candidates = []
FOR each node i in tree_nodes:
FOR each node j NOT in tree_nodes:
candidates.add(edge(i, j))
// Calculate probability for each candidate
FOR each edge(i,j) in candidates:
Pij = [τijα × ηijβ] / Σall candidates
// Select edge based on probability
selected_edge = weighted_random_choice(candidates, probabilities)
tree_edges.add(selected_edge)
tree_nodes.add(selected_edge.destination)
RETURN tree_edges
Original ACO: Bisa saja create cycle jika tidak careful
ACO-MST Improvement:
// Check: hanya pilih node yang BELUM di tree
FOR each node j NOT in tree_nodes: // ← CONSTRAINT!
candidates.add(edge(i, j))
Impact: Guaranteed no cycle!
Original ACO: Sequential node-by-node (like TSP)
ACO-MST Improvement:
// Select from ANY tree node, not just current
FOR each node i in tree_nodes: // ← EXPANDED CHOICE!
FOR each node j NOT in tree_nodes:
candidates.add(edge(i, j))
Impact: More exploration, better solutions!
Original ACO: Edge count varies by problem
ACO-MST Improvement:
WHILE |tree_edges| < n - 1: // ← EXACT COUNT!
// Add edge
tree_edges.add(selected_edge)
Impact: Always valid tree structure!
Enhancement: Limit max connections per node
// Only consider if node hasn't reached max degree
IF degree[i] < max_degree AND degree[j] < max_degree:
candidates.add(edge(i, j))
Application: Real-world constraints (router ports, etc)
Discovery: MST works better with different params than TSP
| Parameter | TSP (Complex) | MST (Simpler) | Reasoning |
|---|---|---|---|
| β (heuristic) | 2-3 | 1-2 | MST less greedy needed |
| ρ (evaporation) | 0.3-0.5 | 0.1-0.3 | MST needs less exploration |
Impact: Faster convergence to optimal!
| Step | ACO-TSP Construction | ACO-MST Construction |
|---|---|---|
| 1 | Start: Node A In tour: {A} |
Start: Node A In tree: {A} |
| 2 | From A, pick next Choices: B, C, D Pick B (greedy) |
From tree {A}, pick edge Choices: A-B, A-C, A-D Pick A-C (probabilistic) |
| 3 | From B, pick next Choices: C, D Pick D |
From tree {A,C}, pick edge Choices: A-B, A-D, C-B, C-D Pick C-B (best from tree) |
| 4 | From D, pick next Choices: C Pick C |
From tree {A,C,B}, pick edge Choices: A-D, C-D, B-D Pick B-D |
| Result | Path: A→B→D→C NOT a cycle yet! |
Tree: A-C, C-B, B-D Done! (n-1 edges) |
ACO-MST often finds OPTIMAL solution!
(Sometimes matches Kruskal exactly!)