Skip to content
Snippets Groups Projects
Commit 6d61161b authored by Dennis Ahrens's avatar Dennis Ahrens
Browse files

A bunch of stuff added

parent d6ad719f
Branches
No related tags found
No related merge requests found
import math
calls = 0
def magic(a, n):
global calls
calls += 1
if n == 0:
return 1
elif n % 2 == 0:
return magic(a, n / 2) ** 2
else:
return a * (magic(a, (n-1) / 2) ** 2)
def magic_loop(a, n):
"""no paradigm..."""
if n == 0:
return 1
result = a
for _ in range(n - 1):
result = result * a
return result
def call_magic(a, n):
"""Call magic and tell something about the recursion depth."""
global calls
calls = 0
print("magic({},{})={} {} with {} calls log2(n) = {}".format(
a, n, magic(a, n), magic_loop(a, n), calls,
math.log2(n) if n > 0 else 0)
)
if __name__ == '__main__':
print("""
Magic computes the result of a^n with O(log(n)).
It uses the paradigm "divide and conquer".
""")
for n in range(200):
if n % 10 == 0:
call_magic(2, n)
from collections import namedtuple
from itertools import combinations
from pprint import pprint
from math import ceil
class Item(namedtuple('Item', ['name', 'volume', 'gain'])):
__slots__ = []
@property
def relative_gain(self):
return round(self.gain / self.volume, 2)
def __str__(self):
return '{} V={} G={} RG={}'.format(self.name, self.volume, self.gain, self.relative_gain)
def approx_knapsack(volume, items):
items.sort(key=lambda i: i.relative_gain, reverse=True)
knapsack = []
cost = 0
for item in items:
if cost + item.volume <= volume:
knapsack.append(item)
cost += item.volume
return knapsack
def optimized_approx_knapsack(volume, items, epsilon):
assert 1 >= epsilon > 0, "Please select a sane epsilon"
l = ceil(1/epsilon)
print("l = 1/epsilon = ", l)
items.sort(key=lambda i: i.relative_gain, reverse=True)
start_configurations = [[i] for i in items]
for set_count in range(2, l + 1):
start_configurations.extend([list(c) for c in combinations(items, set_count)])
print("We have the following start configurations:")
pprint(start_configurations)
best_knapsack = []
best_gain = 0
tested_knapsacks = 0
for cfg in start_configurations:
knapsack = cfg
cost = sum([i.volume for i in knapsack])
if cost > volume:
print("skip knapsack")
continue
tested_knapsacks += 1
for item in items:
if item in knapsack:
continue
if cost + item.volume <= volume:
knapsack.append(item)
cost += item.volume
new_gain = sum([i.gain for i in knapsack])
if new_gain > best_gain:
print("Ok: {} vs {}\n{}\nis better than\n{}".format(new_gain, best_gain, knapsack, best_knapsack))
best_gain = new_gain
best_knapsack = knapsack
print("We searched for the best knapsack with {} start configs, and the winner with gain {} is:".format(tested_knapsacks, best_gain))
pprint(best_knapsack)
items = [
Item('A', 191, 201),
Item('B', 239, 141),
Item('C', 148, 48),
Item('D', 153, 232),
Item('E', 66, 50),
Item('F', 137, 79),
Item('G', 249, 38),
Item('H', 54, 73)
]
ks = approx_knapsack(645, items)
pprint(ks)
print(sum([i.volume for i in ks]), "\n")
optimized_approx_knapsack(645, items, 0.1)
from pprint import pprint
from collections import namedtuple
def print_item_list(l):
pprint([str(i) for i in l])
class Item(namedtuple('Item', ['name', 'volume', 'gain'])):
__slots__ = []
@property
def relative_gain(self):
return round(self.gain / self.volume, 2)
def __str__(self):
return '{} V={} G={} RG={}'.format(
self.name, self.volume, self.gain, self.relative_gain
)
class Node:
def __init__(self, items, available, max_volume):
self.items = items
self.available = available
self.max_volume = max_volume
@property
def volume(self):
return sum([i.volume for i in self.items])
@property
def gain(self):
return sum([i.gain for i in self.items])
@property
def is_final(self):
return len(self.available) == 0
@property
def max_relative_gain(self):
if self.available:
return self.available[0].relative_gain
@property
def capacity(self):
return self.max_volume - self.volume
@property
def is_valid(self):
return self.capacity >= 0
@property
def max_expected_gain(self):
if len(self.available) == 0 or self.is_final:
return self.gain
return round(self.gain + (self.capacity * self.max_relative_gain), 2)
def expand(self):
children = [
Node(self.items + [item], self.available[idx+1:], self.max_volume)
for idx, item in enumerate(self.available)
]
self.available = []
return children
def __str__(self):
return "{}{}(G={} V={}/{}=>{} MAXG={}({}))".format(
"".join([i.name for i in self.items]).ljust(5),
"f" if self.is_final else "e",
self.gain,
self.volume,
self.max_volume,
self.capacity,
self.max_expected_gain,
self.max_relative_gain
)
def branch_n_bound_knapsack(volume, items):
items.sort(key=lambda i: i.relative_gain, reverse=True)
# build the initial list of nodes...
nodes = list(Node([], items, volume).expand())
print("expanded the root node")
for i in range(2, 99999):
# determine the current best node
best_node = sorted(nodes, key=lambda n: n.max_expected_gain).pop()
if best_node.is_final:
print("the best node: {}".format(best_node))
return best_node
print("\nexpandation no. {} on node {}".format(i, best_node))
children = [
child for child in best_node.expand()
if child.is_valid
]
if children:
nodes.extend(children)
print("expanded {} new nodes".format(len(children)))
else:
nodes.append(best_node)
print("no new nodes")
if not best_node.is_final:
print("Endless loop? we skip now...")
return best_node
branch_n_bound_knapsack(600, [
Item('A', 191, 201),
Item('B', 239, 141),
Item('C', 148, 48),
Item('D', 153, 232),
Item('E', 66, 50),
Item('F', 137, 79),
Item('G', 249, 38),
Item('H', 54, 73),
])
from collections import deque
import math
def get_neighbors(node, edges):
for n1, n2, distance in edges:
if n1 == node:
yield n2, distance
elif n2 == node:
yield n1, distance
def dijkstra(nodes, edges, source, target):
""" Calculates the shortest path from source taking the given nodes into account """
assert source in nodes
assert target in nodes
inf = float('inf')
dist = {node: inf for node in nodes}
previous = {node: None for node in nodes}
dist[source] = 0
queue = [node for node in nodes]
iterations = 0
while queue:
iterations += 1
queue.sort(key=lambda node: dist[node], reverse=True)
print(queue)
node = queue.pop()
print('Iteration {}: queue length is {} we now test {}'.format(iterations, len(queue), node))
if dist[node] == inf or node == target:
break
for neighbor, distance in get_neighbors(node, edges):
if neighbor not in queue: continue
cost = dist[node] + distance
if cost < dist[neighbor]:
dist[neighbor] = cost
previous[neighbor] = node
dq = deque()
while previous[target]:
dq.appendleft(target)
target = previous[target]
dq.appendleft(target)
return list(dq)
def bee_line(source_coord, target_coord):
lat1, lon1 = source_coord
lat2, lon2 = target_coord
R = 6373.0
dlon = lon2 - lon1
dlat = lat2 - lat1
a = math.sin(dlat / 2)**2 + math.cos(lat1) * math.cos(lat2) * math.sin(dlon / 2)**2
c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
return R * c
def astar(nodes, edges, coordinates, source, target):
""" Calculates the shortest path from source taking the given nodes into account """
assert source in nodes
assert target in nodes
inf = float('inf')
dist = {node: inf for node in nodes}
bee_line_dest = {
node: bee_line(coordinates[node], coordinates[target])
for node in nodes if node != target
}
bee_line_dest[target]= 0
print(bee_line_dest)
previous = {node: None for node in nodes}
dist[source] = 0
queue = [node for node in nodes]
iterations = 0
while queue:
iterations += 1
queue.sort(key=lambda node: dist[node], reverse=True)
node = queue.pop()
print('Iteration {}: queue length is {} we now test {}'.format(iterations, len(queue), node))
if dist[node] == inf or node == target:
break
for neighbor, distance in get_neighbors(node, edges):
if neighbor not in queue: continue
cost = dist[node] + distance + bee_line_dest[neighbor]
if cost < dist[neighbor]:
dist[neighbor] = cost
previous[neighbor] = node
dq = deque()
while previous[target]:
dq.appendleft(target)
target = previous[target]
dq.appendleft(target)
return list(dq)
def show_path(path, edges):
path_cost = 0
for idx in range(len(path) - 1):
source = path[idx]
target = path[idx + 1]
cost = sum([
cost for n1, n2, cost in edges
if (n1 == source and n2 == target) or (n2 == source and n1 == target )
])
print('{}: from {} to {} takes {} minutes'.format(idx, source, target, cost))
path_cost += cost
print('Overall costs: {}'.format(path_cost))
if __name__ == '__main__':
nodes = set(['H', 'HI', '', 'BS', 'UE', 'LG', 'HH', 'ELZ', 'MI', 'OS', 'NI', 'VER', 'HB'])
edges = [
('HB', 'HH', 52),
('HB', 'VER', 20),
('HB', 'H', 59),
('HB', 'OS', 51),
('OS', 'MI', 39),
('MI', 'NI', 48),
('MI', 'ELZ', 111),
('MI', 'H', 32),
('NI', 'VER', 14),
('NI', 'H', 26),
('VER', 'UE', 139),
('VER', 'HH', 71),
('H', 'ELZ', 21),
('H', '', 34),
('H', 'HI', 25),
('H', 'BS', 31),
('H', 'UE', 41),
('H', 'HH', 75),
('ELZ', '', 50),
('', 'HI', 28),
('HI', 'BS', 25),
('BS', 'UE', 110),
('UE', 'LG', 14),
('LG', 'HH', 28)
]
path = dijkstra(nodes, edges, 'OS', 'LG')
print(path)
show_path(path, edges)
coordinates = {
'H': (52.3765, 9.7388),
'HI': (52.1597, 9.9502),
'': (51.5366, 9.9246),
'BS': (52.2525, 10.5360),
'UE': (52.9694, 10.5511),
'LG': (53.2391, 10.3875),
'HH': (53.5528, 10.0048),
'ELZ': (52.1203, 9.7443),
'MI': (52.3061, 52.2728),
'OS': (52.2728, 52.6451),
'NI': (52.6451, 9.2143),
'VER': (52.9208, 9.2357),
'HB': (53.0831, 8.8112)
}
astar_path = astar(nodes, edges, coordinates, 'OS', 'LG')
print(astar_path)
show_path(astar_path, edges)
from random import sample
ITEMS = set([2,10,100,9,1,65,5,11,88,77])
def las_vegas(k, items):
if len(items) == 1:
return list(items).pop()
random_element = sample(items, 1)[0]
smaller = set()
larger = set()
for item in items:
if item == random_element:
continue
if item < random_element:
smaller.add(item)
else:
larger.add(item)
if len(smaller) > k:
return las_vegas(k, smaller)
elif len(smaller) == k:
return random_element
else:
return las_vegas(k - len(smaller) - 1, larger)
for i in range(100):
print(i, las_vegas(3, ITEMS))
from random import random
from math import sqrt, pi
def monte_carlo_pi():
inside = 0
i = 0
while True:
i += 1
if sqrt(random()**2 + random()**2) < 1:
inside += 1
if i % 1000000 == 0:
print(i)
print(pi)
print(4 * (inside / i))
monte_carlo_pi()
power.py 0 → 100644
def power(n, x):
y = 1
i = n
while not i == 0:
y = y * x * x
i -= 2
return y
print(power(12, 6), 6**12)
# the one below does not terminate at all.
print(power(11, 6), 6**12)
import pprint
import copy
BOARD_SIZE = 8
def get_fresh_board():
return [[False for _ in range(BOARD_SIZE)] for _ in range(BOARD_SIZE)]
the_board = get_fresh_board()
pprint.pprint(the_board)
def get_threat_fields(x, y):
""" Returns a list of tuples (x, y) that are threatend from a queen at x, y. """
pass
def set_queen(x, y, board):
""" Returns True when succesfully placed queen, otherwise False. """
def queens(board, k=4, queens=[]):
if k == 0:
return queens
for x in range(BOARD_SIZE):
for y in range(BOARD_SIZE):
pass
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment