Created
July 10, 2021 10:14
-
-
Save jared-hughes/8a2867ab99d5ef45f2e4eccd6f125937 to your computer and use it in GitHub Desktop.
Network graph of n→n+φ(n), investigating different starting values from http://oeis.org/A074693, as suggested by tox#6692
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from sympy.ntheory import factorint | |
from sympy.ntheory.factor_ import totient | |
import functools | |
import itertools | |
import networkx as nx | |
from collections import deque | |
# pygraphviz is optional; you can use command-line graphviz instead if you want | |
import pygraphviz as pgv | |
@functools.lru_cache(maxsize=None) | |
def f(n): | |
return n+totient(n) | |
G = nx.DiGraph() | |
placed = set() | |
# We extend the graph in an interesting manner as a compromise between plugging in | |
# 1,2,3,4,5,6,... and 1,f(1),f(f(1)),f(f(f(1))),... | |
# It proceeds something like 1,f(1),2,f(f(1)),f(2),3,f(f(f(1))),f(f(2)),f(3),4... | |
# with duplicates removed. This is done using the queue (deque), | |
# where `0` signifies proceeding along the 1,2,3,... subsequence | |
# current filled max | |
current_max = 1 | |
heads_queue = deque([0]) | |
for _ in range(1000): | |
if len(heads_queue) == 0: | |
head = 0 | |
else: | |
head = heads_queue.popleft() | |
if head == 0: | |
while current_max in placed: | |
current_max += 1 | |
head = current_max | |
heads_queue.append(0) | |
if head in placed: | |
continue | |
res = f(head) | |
if res not in placed: | |
heads_queue.append(res) | |
placed.add(head) | |
ratio = res/head | |
label = "{:1.4}".format(ratio) | |
# HSV | |
color = f"{0.7*ratio%1} 1 0.7" | |
G.add_edge(head, res, label=label, color=color) | |
shapes = itertools.cycle(['ellipse', 'rectangle']) | |
for component in nx.weakly_connected_components(G): | |
shape = next(shapes) | |
for node in component: | |
G.nodes[node]['shape'] = shape | |
def factor_string(n): | |
factors = factorint(n) | |
# don't feel like setting up dot2tex, so HTML superscripts will have to do for now | |
return "<" + "·".join([ | |
f"{p}<SUP>{n}</SUP>" | |
for p, n in factors.items() | |
]) + ">" or "1" | |
for node in G: | |
G.nodes[node]['label'] = factor_string(node) | |
A = nx.nx_agraph.to_agraph(G) | |
A.write("graphviz.dot") | |
pgv.AGraph("graphviz.dot").draw("output.png", prog="dot") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment