AntHocNet 2.0.0
Paper-faithful ant-colony ad hoc routing: the shared core and its adapters
Loading...
Searching...
No Matches
pheromone_table.h
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-only
2// Copyright (C) 2026 Daniel Henrique Joppi
3
4/**
5 * PheromoneTable: per-node routing state.
6 *
7 * Holds the regular and virtual pheromone maps keyed by (neighbor,
8 * destination), the neighbour set, and the per-table destination sets. This
9 * is a near-verbatim port of the original NS-2 class with two changes:
10 * - randomness is taken from an injected IRng (not libc rand());
11 * - the probabilistic selection helpers are const-correct and take the
12 * config so BETA is not a compile-time constant.
13 */
14#ifndef ANTHOCNET_CORE_PHEROMONE_TABLE_H
15#define ANTHOCNET_CORE_PHEROMONE_TABLE_H
16
17#include <map>
18#include <set>
19#include <utility>
20#include <vector>
21
25
26namespace anthocnet {
27namespace core {
28
30public:
31 using Key = std::pair<NodeAddress, NodeAddress>; // (neighbor, dest)
32 using PheromoneMap = std::map<Key, double>;
33 using NeighborSet = std::set<NodeAddress>;
34 using DestinationSet = std::set<NodeAddress>;
35
36 // --- entry management -------------------------------------------------
37 void addPheromoneRegular(NodeAddress dest, NodeAddress neighbor, double value);
38 void addPheromoneVirtual(NodeAddress dest, NodeAddress neighbor, double value);
41 double getPheromoneRegular(NodeAddress dest, NodeAddress neighbor) const;
42 double getPheromoneVirtual(NodeAddress dest, NodeAddress neighbor) const;
43
44 /// Best (largest) regular pheromone any neighbour holds for `dest`, or 0 if
45 /// none. Used to advertise this node's path goodness in hello adverts.
46 double bestRegular(NodeAddress dest) const;
47 /// Best (largest) virtual pheromone any neighbour holds for `dest`, or 0 if
48 /// none. Same units as bestRegular (the diffusion bootstrap re-inverts into
49 /// regular units), so the two are directly comparable — that comparison is
50 /// the proactive emission gate (#180).
51 double bestVirtual(NodeAddress dest) const;
52 void setPheromoneRegular(NodeAddress dest, NodeAddress neighbor, double value);
53 void setPheromoneVirtual(NodeAddress dest, NodeAddress neighbor, double value);
54
55 bool isEmptyRegular() const { return pheromoneRegular_.empty(); }
56 bool isEmptyVirtual() const { return pheromoneVirtual_.empty(); }
57
58 /// Size gauge (issue #133): current (neighbor, dest) entry counts. The
59 /// table grows with destinations x neighbours (regular + virtual) and only
60 /// evaporation / link-failure removal shrink it, so adapters export these
61 /// to observe growth over long runs. Read-only; no routing behaviour.
62 std::size_t numEntriesRegular() const { return pheromoneRegular_.size(); }
63 std::size_t numEntriesVirtual() const { return pheromoneVirtual_.size(); }
64 std::size_t numEntries() const {
65 return pheromoneRegular_.size() + pheromoneVirtual_.size();
66 }
67
68 // --- neighbour management --------------------------------------------
69 void addNeighbor(NodeAddress neighbor);
71 const NeighborSet& neighbors() const { return neighborTable_; }
72 std::size_t numNeighbors() const { return neighborTable_.size(); }
73 bool hasNeighbor() const { return !neighborTable_.empty(); }
74
75 const DestinationSet& regularDestinations() const { return destRegular_; }
76 const DestinationSet& virtualDestinations() const { return destVirtual_; }
77
78 // --- routing ----------------------------------------------------------
79 /// Stochastic next-hop choice. With isProactiveAnt the virtual table is
80 /// blended in (max of regular/virtual); otherwise only regular is used.
81 /// `beta` is the Eq.1 exponent (caller passes betaAnts or betaData).
82 /// `exclude` (e.g. the previous hop for data) is skipped unless it is the
83 /// only option, so a packet isn't sent back the way it came (A1).
84 /// Returns kInvalidAddress when no route exists.
85 NodeAddress nextNeighborNode(NodeAddress dest, bool isProactiveAnt, double beta,
86 IRng& rng, NodeAddress exclude = kInvalidAddress) const;
87
88 /// The probability distribution nextNeighborNode() samples from, for the
89 /// same arguments: one (neighbour, probability) pair per candidate, in
90 /// neighbour order, summing to 1 (empty when there is no route). Applies
91 /// the same A1 fallback (the excluded hop is reconsidered when it is the
92 /// only option). Read-only: for inspection and teaching (#546), never a
93 /// second routing path -- it consumes no randomness.
94 std::vector<std::pair<NodeAddress, double>> nextHopDistribution(
95 NodeAddress dest, bool isProactiveAnt, double beta,
96 NodeAddress exclude = kInvalidAddress) const;
97 /// Reactive lookup == nextNeighborNode(dest, false, beta).
98 NodeAddress lookup(NodeAddress dest, double beta, IRng& rng,
99 NodeAddress exclude = kInvalidAddress) const;
100
101 /// Uniformly pick a known regular destination, or kInvalidAddress if none.
103
104private:
105 double sumProbability(const PheromoneMap& table, NodeAddress dest, double beta,
106 NodeAddress exclude) const;
107 double sumMaxProbability(NodeAddress dest, double beta, NodeAddress exclude) const;
108
109 PheromoneMap pheromoneRegular_;
110 PheromoneMap pheromoneVirtual_;
111 NeighborSet neighborTable_;
112 DestinationSet destRegular_;
113 DestinationSet destVirtual_;
114};
115
116} // namespace core
117} // namespace anthocnet
118
119#endif // ANTHOCNET_CORE_PHEROMONE_TABLE_H
Source of randomness.
Definition ports.h:33
void addPheromoneRegular(NodeAddress dest, NodeAddress neighbor, double value)
const DestinationSet & regularDestinations() const
std::vector< std::pair< NodeAddress, double > > nextHopDistribution(NodeAddress dest, bool isProactiveAnt, double beta, NodeAddress exclude=kInvalidAddress) const
The probability distribution nextNeighborNode() samples from, for the same arguments: one (neighbour,...
std::pair< NodeAddress, NodeAddress > Key
void setPheromoneVirtual(NodeAddress dest, NodeAddress neighbor, double value)
void addNeighbor(NodeAddress neighbor)
void setPheromoneRegular(NodeAddress dest, NodeAddress neighbor, double value)
double bestVirtual(NodeAddress dest) const
Best (largest) virtual pheromone any neighbour holds for dest, or 0 if none.
std::set< NodeAddress > DestinationSet
NodeAddress nextNeighborNode(NodeAddress dest, bool isProactiveAnt, double beta, IRng &rng, NodeAddress exclude=kInvalidAddress) const
Stochastic next-hop choice.
const NeighborSet & neighbors() const
std::size_t numEntriesVirtual() const
std::map< Key, double > PheromoneMap
void removeNeighbor(NodeAddress neighbor)
double getPheromoneRegular(NodeAddress dest, NodeAddress neighbor) const
void addPheromoneVirtual(NodeAddress dest, NodeAddress neighbor, double value)
NodeAddress randomDestination(IRng &rng) const
Uniformly pick a known regular destination, or kInvalidAddress if none.
double bestRegular(NodeAddress dest) const
Best (largest) regular pheromone any neighbour holds for dest, or 0 if none.
void removePheromoneRegular(NodeAddress dest, NodeAddress neighbor)
std::set< NodeAddress > NeighborSet
NodeAddress lookup(NodeAddress dest, double beta, IRng &rng, NodeAddress exclude=kInvalidAddress) const
Reactive lookup == nextNeighborNode(dest, false, beta).
void removePheromoneVirtual(NodeAddress dest, NodeAddress neighbor)
std::size_t numEntriesRegular() const
Size gauge (issue #133): current (neighbor, dest) entry counts.
double getPheromoneVirtual(NodeAddress dest, NodeAddress neighbor) const
const DestinationSet & virtualDestinations() const
constexpr NodeAddress kInvalidAddress
"No such node / no route" sentinel, mirroring the legacy use of -1.
Definition types.h:27
std::int32_t NodeAddress
Network-layer node address.
Definition types.h:21
AntHistoryTracker: (src, seqNum) duplicate detection.
Definition ant_history.h:24