Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
nicolas.dupont
dCod at Runde
Commits
9eb04ea4
Commit
9eb04ea4
authored
Jun 18, 2019
by
Morten Brun
Browse files
added example notebook
parent
1009466c
Changes
4
Expand all
Hide whitespace changes
Inline
Side-by-side
lecturers/guttorm/python/evolution.ipynb
0 → 100644
View file @
9eb04ea4
This diff is collapsed.
Click to expand it.
lecturers/guttorm/python/thinkcomplexity.py
0 → 100644
View file @
9eb04ea4
# This Python file uses the following encoding: utf-8
from
__future__
import
print_function
,
division
import
matplotlib.pyplot
as
plt
import
networkx
as
nx
import
numpy
as
np
import
random
# colors from our friends at http://colorbrewer2.org
COLORS
=
[
'#8dd3c7'
,
'#ffffb3'
,
'#bebada'
,
'#fb8072'
,
'#80b1d3'
,
'#fdb462'
,
'#b3de69'
,
'#fccde5'
,
'#d9d9d9'
,
'#bc80bd'
,
'#ccebc5'
,
'#ffed6f'
]
def
all_pairs
(
nodes
):
"""Generates all pairs of nodes."""
for
i
,
u
in
enumerate
(
nodes
):
for
j
,
v
in
enumerate
(
nodes
):
if
i
<
j
:
yield
u
,
v
def
make_complete_graph
(
n
):
"""Makes a complete graph with `n` nodes."""
G
=
nx
.
Graph
()
nodes
=
range
(
n
)
G
.
add_nodes_from
(
nodes
)
G
.
add_edges_from
(
all_pairs
(
nodes
))
return
G
def
flip
(
p
):
"""Returns True with probability `p`."""
return
random
.
random
()
<
p
def
random_pairs
(
nodes
,
p
):
"""Generates random pairs of nodes.
Each possible edge is yielded with probability `p`.
"""
for
i
,
u
in
enumerate
(
nodes
):
for
j
,
v
in
enumerate
(
nodes
):
if
i
<
j
and
flip
(
p
):
yield
u
,
v
def
make_random_graph
(
n
,
p
):
"""Makes a random graph where each edge exists with probability 'p'."""
G
=
nx
.
Graph
()
nodes
=
range
(
n
)
G
.
add_nodes_from
(
nodes
)
G
.
add_edges_from
(
random_pairs
(
nodes
,
p
))
return
G
def
reachable_nodes
(
G
,
start
):
"""Finds all nodes reachable from `start`."""
seen
=
set
()
stack
=
[
start
]
while
stack
:
node
=
stack
.
pop
()
if
node
not
in
seen
:
seen
.
add
(
node
)
stack
.
extend
(
G
.
neighbors
(
node
))
return
seen
def
is_connected
(
G
):
"""Returns True if the graph is connected."""
start
=
next
(
G
.
nodes_iter
())
reachable
=
reachable_nodes
(
G
,
start
)
return
len
(
reachable
)
==
len
(
G
)
def
prob_connected
(
n
,
p
,
iters
=
100
):
count
=
0
for
i
in
range
(
iters
):
random_graph
=
make_random_graph
(
n
,
p
)
if
is_connected
(
random_graph
):
count
+=
1
return
count
/
iters
def
reachable_nodes_precheck
(
G
,
start
):
seen
=
set
()
stack
=
[
start
]
while
stack
:
node
=
stack
.
pop
()
if
node
not
in
seen
:
seen
.
add
(
node
)
neighbors
=
set
(
G
[
node
])
neighbors
-=
seen
stack
.
extend
(
neighbors
)
return
seen
def
adjacent_edges
(
nodes
,
halfk
):
n
=
len
(
nodes
)
for
i
,
u
in
enumerate
(
nodes
):
for
j
in
range
(
i
+
1
,
i
+
halfk
+
1
):
v
=
nodes
[
j
%
n
]
yield
u
,
v
def
make_ring_lattice
(
n
,
k
):
G
=
nx
.
Graph
()
nodes
=
range
(
n
)
G
.
add_nodes_from
(
nodes
)
G
.
add_edges_from
(
adjacent_edges
(
nodes
,
k
//
2
))
return
G
def
make_ws_graph
(
n
,
k
,
p
):
ws
=
make_ring_lattice
(
n
,
k
)
rewire
(
ws
,
p
)
return
ws
def
rewire
(
G
,
p
):
nodes
=
set
(
G
.
nodes
())
for
edge
in
G
.
edges
():
if
flip
(
p
):
u
,
v
=
edge
choices
=
nodes
-
{
u
}
-
set
(
G
[
u
])
new_v
=
choice
(
tuple
(
choices
))
G
.
remove_edge
(
u
,
v
)
G
.
add_edge
(
u
,
new_v
)
def
node_clustering
(
G
,
u
):
neighbors
=
G
[
u
]
k
=
len
(
neighbors
)
if
k
<
2
:
return
0
total
=
k
*
(
k
-
1
)
/
2
exist
=
0
for
v
,
w
in
all_pairs
(
neighbors
):
if
G
.
has_edge
(
v
,
w
):
exist
+=
1
return
exist
/
total
def
clustering_coefficient
(
G
):
cc
=
np
.
mean
([
node_clustering
(
G
,
node
)
for
node
in
G
])
return
cc
def
node_clustering
(
G
,
u
):
neighbors
=
G
[
u
]
k
=
len
(
neighbors
)
if
k
<
2
:
return
0
edges
=
[
G
.
has_edge
(
v
,
w
)
for
v
,
w
in
all_pairs
(
neighbors
)]
return
sum
(
edges
)
/
len
(
edges
)
def
path_lengths
(
G
):
length_map
=
nx
.
shortest_path_length
(
G
)
lengths
=
[
length_map
[
u
][
v
]
for
u
,
v
in
all_pairs
(
G
)]
return
lengths
def
characteristic_path_length
(
G
):
return
np
.
mean
(
path_lengths
(
G
))
def
run_one_graph
(
n
,
k
,
p
):
ws
=
make_ws_graph
(
n
,
k
,
p
)
mpl
=
characteristic_path_length
(
ws
)
cc
=
clustering_coefficient
(
ws
)
print
(
mpl
,
cc
)
return
mpl
,
cc
def
run_experiment
(
ps
,
n
=
1000
,
k
=
10
,
iters
=
20
):
res
=
{}
for
p
in
ps
:
print
(
p
)
res
[
p
]
=
[]
for
_
in
range
(
iters
):
res
[
p
].
append
(
run_one_graph
(
n
,
k
,
p
))
return
res
from
collections
import
deque
def
reachable_nodes_bfs
(
G
,
start
):
seen
=
set
()
queue
=
deque
([
start
])
while
queue
:
node
=
queue
.
popleft
()
if
node
not
in
seen
:
seen
.
add
(
node
)
queue
.
extend
(
G
.
neighbors
(
node
))
return
seen
def
reachable_nodes_bfs
(
G
,
start
):
seen
=
set
()
queue
=
deque
([
start
])
while
queue
:
node
=
queue
.
popleft
()
if
node
not
in
seen
:
seen
.
add
(
node
)
neighbors
=
set
(
G
[
node
])
neighbors
-=
seen
queue
.
extend
(
neighbors
)
return
seen
def
shortest_path_dijkstra
(
G
,
start
):
dist
=
{
start
:
0
}
queue
=
deque
([
start
])
while
queue
:
node
=
queue
.
popleft
()
new_dist
=
dist
[
node
]
+
1
neighbors
=
set
(
G
[
node
])
-
set
(
dist
)
for
n
in
neighbors
:
dist
[
n
]
=
new_dist
queue
.
extend
(
neighbors
)
return
dist
def
opposite_edges
(
nodes
):
"""Enumerates edges that connect opposite nodes."""
n
=
len
(
nodes
)
for
i
,
u
in
enumerate
(
nodes
):
j
=
i
+
n
//
2
v
=
nodes
[
j
%
n
]
yield
u
,
v
def
make_regular_graph
(
n
,
k
):
"""Makes graph with `n` nodes where all nodes have `k` neighbors.
Not possible if both `n` and `k` are odd.
"""
# a is the number of adjacent edges
# b is the number of opposite edges (0 or 1)
a
,
b
=
divmod
(
k
,
2
)
G
=
nx
.
Graph
()
nodes
=
range
(
n
)
G
.
add_nodes_from
(
nodes
)
G
.
add_edges_from
(
adjacent_edges
(
nodes
,
a
))
# if k is odd, add opposite edges
if
b
:
if
n
%
2
:
msg
=
"Can't make a regular graph if n and k are odd."
raise
ValueError
(
msg
)
G
.
add_edges_from
(
opposite_edges
(
nodes
))
return
G
def
plain_bfs
(
G
,
source
):
"""A fast BFS node generator"""
seen
=
set
()
nextlevel
=
{
source
}
while
nextlevel
:
thislevel
=
nextlevel
nextlevel
=
set
()
for
v
in
thislevel
:
if
v
not
in
seen
:
seen
.
add
(
v
)
nextlevel
.
update
(
G
[
v
])
return
seen
def
plain_shortest_path
(
G
,
source
):
"""A fast implementation of Dijkstra's algorithm with equal edge lengths."""
new_dist
=
0
dist
=
{}
nextlevel
=
{
source
}
while
nextlevel
:
thislevel
=
nextlevel
nextlevel
=
set
()
for
v
in
thislevel
:
if
v
not
in
dist
:
dist
[
v
]
=
new_dist
nextlevel
.
update
(
G
[
v
])
new_dist
+=
1
return
dist
def
bfs
(
top_node
,
visit
):
"""Breadth-first search on a graph, starting at top_node."""
visited
=
set
()
queue
=
[
top_node
]
while
len
(
queue
):
curr_node
=
queue
.
pop
(
0
)
# Dequeue
visit
(
curr_node
)
# Visit the node
visited
.
add
(
curr_node
)
# Enqueue non-visited and non-enqueued children
queue
.
extend
(
c
for
c
in
curr_node
.
children
if
c
not
in
visited
and
c
not
in
queue
)
def
shortest_path_dfs
(
G
,
start
):
dist
=
{
start
:
0
}
queue
=
deque
([
start
])
while
queue
:
node
=
queue
.
pop
()
new_dist
=
dist
[
node
]
+
1
neighbors
=
set
(
G
[
node
])
-
set
(
dist
)
for
n
in
neighbors
:
dist
[
n
]
=
new_dist
queue
.
extend
(
neighbors
)
return
dist
lecturers/guttorm/python/thinkplot.py
0 → 100644
View file @
9eb04ea4
This diff is collapsed.
Click to expand it.
lecturers/guttorm/python/thinkstats2.py
0 → 100644
View file @
9eb04ea4
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment