Skip to content

Commit a116b83

Browse files
danieledlerAnton Eriksson
authored andcommitted
feat: Allow one-sided multilayer relax limit
Closes #68
1 parent 63de1fe commit a116b83

File tree

4 files changed

+36
-9
lines changed

4 files changed

+36
-9
lines changed

src/io/Config.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,13 +181,19 @@ Config Config::fromString(std::string flags, bool requireFileInput)
181181
"Optimize for the preferred number of modules by penalizing solutions the more they differ from the preferred number.", "n", "Algorithm", true);
182182

183183
api.addOptionArgument(conf.multilayerRelaxRate, "multilayer-relax-rate",
184-
"The probability to relax the constraint to move only in the current layer. If negative, the inter-links have to be provided.", "f", "Algorithm", true);
184+
"The probability to relax the constraint to move only in the current layer. Default 0.15", "f", "Algorithm", true);
185185

186186
api.addOptionArgument(conf.multilayerRelaxLimit, "multilayer-relax-limit",
187187
"The number of neighboring layers in each direction to relax to. If negative, relax to any layer.", "n", "Algorithm", true);
188188

189+
api.addOptionArgument(conf.multilayerRelaxLimitUp, "multilayer-relax-limit-up",
190+
"The number of neighboring layers with higher id to relax to. If negative, relax to any layer.", "n", "Algorithm", true);
191+
192+
api.addOptionArgument(conf.multilayerRelaxLimitDown, "multilayer-relax-limit-down",
193+
"The number of neighboring layers with lower id to relax to. If negative, relax to any layer.", "n", "Algorithm", true);
194+
189195
api.addOptionArgument(conf.multilayerJSRelaxRate, "multilayer-js-relax-rate",
190-
"The probability to relax the constraint to move only in the current layer and instead move to a random layer where the same physical node is present and proportional to the out-link similarity measured by the Jensen-Shannon divergence. If negative, the inter-links have to be provided.", "f", "Algorithm", true);
196+
"The probability to relax the constraint to move only in the current layer and instead move to a random layer where the same physical node is present and proportional to the out-link similarity measured by the Jensen-Shannon divergence. Default 0.15", "f", "Algorithm", true);
191197

192198
api.addOptionArgument(conf.multilayerJSRelaxLimit, "multilayer-js-relax-limit",
193199
"The minimum out-link similarity measured by the Jensen-Shannon divergence to relax to other layer. From 0 to 1. No limit if negative.", "f", "Algorithm", true);

src/io/Config.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,9 @@ struct Config
114114
double selfTeleportationProbability = -1;
115115
double markovTime = 1.0;
116116
double multilayerRelaxRate = 0.15;
117-
int multilayerRelaxLimit = -1;
117+
int multilayerRelaxLimit = -1; // Amount of layers allowed to jump up or down
118+
int multilayerRelaxLimitUp = -1; // One-sided limit to higher layers
119+
int multilayerRelaxLimitDown = -1; // One-sided limit to lower layers
118120
double multilayerJSRelaxRate = 0.15;
119121
int multilayerJSRelaxLimit = -1;
120122

@@ -228,6 +230,8 @@ struct Config
228230
markovTime(other.markovTime),
229231
multilayerRelaxRate(other.multilayerRelaxRate),
230232
multilayerRelaxLimit(other.multilayerRelaxLimit),
233+
multilayerRelaxLimitUp(other.multilayerRelaxLimitUp),
234+
multilayerRelaxLimitDown(other.multilayerRelaxLimitDown),
231235
multilayerJSRelaxRate(other.multilayerJSRelaxRate),
232236
multilayerJSRelaxLimit(other.multilayerJSRelaxLimit),
233237
twoLevel(other.twoLevel),
@@ -326,6 +330,8 @@ struct Config
326330
markovTime = other.markovTime;
327331
multilayerRelaxRate = other.multilayerRelaxRate;
328332
multilayerRelaxLimit = other.multilayerRelaxLimit;
333+
multilayerRelaxLimitUp = other.multilayerRelaxLimitUp;
334+
multilayerRelaxLimitDown = other.multilayerRelaxLimitDown;
329335
multilayerJSRelaxRate = other.multilayerJSRelaxRate;
330336
multilayerJSRelaxLimit = other.multilayerJSRelaxLimit;
331337
twoLevel = other.twoLevel;
@@ -423,6 +429,8 @@ struct Config
423429
markovTime = other.markovTime;
424430
multilayerRelaxRate = other.multilayerRelaxRate;
425431
multilayerRelaxLimit = other.multilayerRelaxLimit;
432+
multilayerRelaxLimitUp = other.multilayerRelaxLimitUp;
433+
multilayerRelaxLimitDown = other.multilayerRelaxLimitDown;
426434
multilayerJSRelaxRate = other.multilayerJSRelaxRate;
427435
multilayerJSRelaxLimit = other.multilayerJSRelaxLimit;
428436
twoLevel = other.twoLevel;
@@ -608,7 +616,7 @@ struct Config
608616
// bool printAsUndirected() const { return originallyUndirected; }
609617
bool printAsUndirected() const { return isUndirectedClustering(); }
610618

611-
bool useTeleportation() const { return directed; }
619+
// bool useTeleportation() const { return directed; }
612620

613621
bool is3gram() const { return inputFormat == "3gram"; }
614622
bool isPath() const { return inputFormat == "path"; }

src/io/Network.cpp

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -827,11 +827,24 @@ void Network::generateStateNetworkFromMultilayerWithSimulatedInterLinks()
827827
Log() << "Generating state network from multilayer networks with simulated inter-layer links...\n" << std::flush;
828828
double relaxRate = m_config.multilayerRelaxRate;
829829

830+
int maxRelaxLimit = m_networks.size();
831+
int relaxLimitSymmetric = m_config.multilayerRelaxLimit < 0 ? maxRelaxLimit : m_config.multilayerRelaxLimit;
832+
int relaxLimitDown = m_config.multilayerRelaxLimitDown < 0 ? relaxLimitSymmetric : std::min(relaxLimitSymmetric, m_config.multilayerRelaxLimitDown);
833+
int relaxLimitUp = m_config.multilayerRelaxLimitUp < 0 ? relaxLimitSymmetric : std::min(relaxLimitSymmetric, m_config.multilayerRelaxLimitUp);
834+
auto haveUpOrDownLimit = m_config.multilayerRelaxLimitDown >= 0 || m_config.multilayerRelaxLimitUp >= 0;
835+
830836
Log() << "-> " << m_networks.size() << " networks\n";
831837
Log() << "-> Relax rate: " << relaxRate << "\n";
838+
if (haveUpOrDownLimit) {
839+
Log() << "-> Relax limit up: " << relaxLimitUp << (relaxLimitUp == maxRelaxLimit ? " (no limit)\n" : "\n");
840+
Log() << "-> Relax limit down: " << relaxLimitDown << (relaxLimitDown == maxRelaxLimit ? " (no limit)\n" : "\n");
841+
} else if (m_config.multilayerRelaxLimit >= 0) {
842+
Log() << "-> Relax limit: " << m_config.multilayerRelaxLimit << "\n";
843+
}
832844

833-
auto withinRelaxLimit = [](auto& a, auto& b, auto& limit) {
834-
return limit < 0 || (a >= b ? (a - b) : (b - a)) <= (unsigned int)limit;
845+
auto withinRelaxLimit = [relaxLimitDown, relaxLimitUp](auto& layer1, auto& layer2) {
846+
int diff = layer1 - layer2;
847+
return layer1 >= layer2 ? diff <= relaxLimitDown : -diff <= relaxLimitUp;
835848
};
836849

837850
for (auto& it1 : m_networks) {
@@ -849,7 +862,7 @@ void Network::generateStateNetworkFromMultilayerWithSimulatedInterLinks()
849862

850863
for (auto& it2 : m_networks) {
851864
auto layer2 = it2.first;
852-
if (!withinRelaxLimit(layer1, layer2, m_config.multilayerRelaxLimit)) {
865+
if (!withinRelaxLimit(layer1, layer2)) {
853866
continue;
854867
}
855868
auto& network2 = it2.second;
@@ -862,7 +875,7 @@ void Network::generateStateNetworkFromMultilayerWithSimulatedInterLinks()
862875
}
863876
for (auto& it2 : m_networks) {
864877
auto layer2 = it2.first;
865-
if (!withinRelaxLimit(layer1, layer2, m_config.multilayerRelaxLimit)) {
878+
if (!withinRelaxLimit(layer1, layer2)) {
866879
continue;
867880
}
868881
auto& network2 = it2.second;

src/io/version.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,6 @@
2929

3030
namespace infomap {
3131

32-
const char* INFOMAP_VERSION = "1.0.0-beta.56";
32+
const char* INFOMAP_VERSION = "1.0.0-beta.57";
3333

3434
}

0 commit comments

Comments
 (0)