mirror of
https://github.com/iritmaximus/tira.git
synced 2026-10-12 19:13:47 +03:00
did things
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
import time
|
||||
import random
|
||||
|
||||
|
||||
class BellmanFord:
|
||||
def __init__(self, nodes):
|
||||
self.nodes = nodes
|
||||
self.edges = []
|
||||
|
||||
def add_edge(self, node_a, node_b, weight):
|
||||
self.edges.append((node_a, node_b, weight))
|
||||
|
||||
def find_distances(self, start_node):
|
||||
distances = {}
|
||||
for node in self.nodes:
|
||||
distances[node] = float("inf")
|
||||
distances[start_node] = 0
|
||||
|
||||
num_rounds = len(self.nodes) - 1
|
||||
for _ in range(num_rounds):
|
||||
for edge in self.edges:
|
||||
node_a, node_b, weight = edge
|
||||
new_distance = distances[node_a] + weight
|
||||
if new_distance < distances[node_b]:
|
||||
distances[node_b] = new_distance
|
||||
|
||||
return distances
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
start = time.time()
|
||||
ls = [x for x in range(1, 5000 + 1)]
|
||||
random.shuffle(ls)
|
||||
bf = BellmanFord(ls)
|
||||
for i in range(1, 5000 + 1):
|
||||
for j in range(1, i):
|
||||
if i - j < 10:
|
||||
bf.add_edge(j, i, random.randint(1, 1000))
|
||||
|
||||
distances = bf.find_distances(1)
|
||||
end = time.time()
|
||||
|
||||
print(f"Time: {end - start:.2f}s")
|
||||
@@ -0,0 +1,56 @@
|
||||
import math
|
||||
import heapq
|
||||
class BestRoute:
|
||||
def __init__(self, nodes: int):
|
||||
self.nodes = [x for x in range(1, nodes+1)]
|
||||
self.graph = {node: [] for node in self.nodes}
|
||||
|
||||
def add_road(self, node_a, node_b, weight):
|
||||
self.graph[node_a].append((node_b, weight))
|
||||
self.graph[node_b].append((node_a, weight))
|
||||
|
||||
def find_distances(self, start_node):
|
||||
distances = {}
|
||||
for node in self.nodes:
|
||||
distances[node] = float("inf")
|
||||
distances[start_node] = 0
|
||||
|
||||
queue = []
|
||||
heapq.heappush(queue, (0, start_node))
|
||||
|
||||
visited = set()
|
||||
while queue:
|
||||
node_a = heapq.heappop(queue)[1]
|
||||
if node_a in visited:
|
||||
continue
|
||||
visited.add(node_a)
|
||||
|
||||
for node_b, weight in self.graph[node_a]:
|
||||
new_distance = distances[node_a] + weight
|
||||
if new_distance < distances[node_b]:
|
||||
distances[node_b] = new_distance
|
||||
new_pair = (new_distance, node_b)
|
||||
heapq.heappush(queue, new_pair)
|
||||
|
||||
return distances
|
||||
|
||||
|
||||
def find_route(self, start_n, end_n):
|
||||
distances = self.find_distances(start_n)
|
||||
# print(distances, distances[end_n])
|
||||
if distances[end_n] == math.inf:
|
||||
return -1
|
||||
return distances[end_n]
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
routes = BestRoute(3)
|
||||
|
||||
routes.add_road(1, 2, 2)
|
||||
print(routes.find_route(1, 3)) # -1
|
||||
|
||||
routes.add_road(3, 1, 5)
|
||||
print(routes.find_route(1, 3)) # 5
|
||||
|
||||
routes.add_road(2, 3, 1)
|
||||
print(routes.find_route(1, 3)) # 3
|
||||
@@ -0,0 +1,53 @@
|
||||
import time
|
||||
import random
|
||||
import heapq
|
||||
|
||||
|
||||
class Dijkstra:
|
||||
def __init__(self, nodes):
|
||||
self.nodes = nodes
|
||||
self.graph = {node: [] for node in nodes}
|
||||
|
||||
def add_edge(self, node_a, node_b, weight):
|
||||
self.graph[node_a].append((node_b, weight))
|
||||
|
||||
def find_distances(self, start_node):
|
||||
distances = {}
|
||||
for node in self.nodes:
|
||||
distances[node] = float("inf")
|
||||
distances[start_node] = 0
|
||||
|
||||
queue = []
|
||||
heapq.heappush(queue, (0, start_node))
|
||||
|
||||
visited = set()
|
||||
while queue:
|
||||
node_a = heapq.heappop(queue)[1]
|
||||
if node_a in visited:
|
||||
continue
|
||||
visited.add(node_a)
|
||||
|
||||
for node_b, weight in self.graph[node_a]:
|
||||
new_distance = distances[node_a] + weight
|
||||
if new_distance < distances[node_b]:
|
||||
distances[node_b] = new_distance
|
||||
new_pair = (new_distance, node_b)
|
||||
heapq.heappush(queue, new_pair)
|
||||
|
||||
return distances
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
start = time.time()
|
||||
ls = [x for x in range(1, 5000 + 1)]
|
||||
random.shuffle(ls)
|
||||
d = Dijkstra(ls)
|
||||
for i in range(1, 5000 + 1):
|
||||
for j in range(1, i):
|
||||
if i - j < 10:
|
||||
d.add_edge(j, i, random.randint(1, 1000))
|
||||
|
||||
distances = d.find_distances(1)
|
||||
end = time.time()
|
||||
|
||||
print(f"Time: {end - start:.2f}s")
|
||||
@@ -0,0 +1,62 @@
|
||||
import math
|
||||
import heapq
|
||||
|
||||
class Dijkstra:
|
||||
def __init__(self, nodes):
|
||||
self.nodes = nodes
|
||||
self.graph = {node: [] for node in range(len(nodes))}
|
||||
|
||||
def add_edge(self, node_a, node_b, weight):
|
||||
self.graph[node_a].append((node_b, weight))
|
||||
|
||||
def find_distances(self, start_node):
|
||||
distances = {}
|
||||
for i in range(len(self.nodes)):
|
||||
distances[i] = float("inf")
|
||||
distances[start_node] = 0
|
||||
|
||||
queue = []
|
||||
heapq.heappush(queue, (0, start_node))
|
||||
|
||||
visited = set()
|
||||
while queue:
|
||||
node_a = heapq.heappop(queue)[1]
|
||||
if node_a in visited:
|
||||
continue
|
||||
visited.add(node_a)
|
||||
|
||||
for node_b, weight in self.graph[node_a]:
|
||||
new_distance = distances[node_a] + weight
|
||||
if new_distance < distances[node_b]:
|
||||
distances[node_b] = new_distance
|
||||
new_pair = (new_distance, node_b)
|
||||
heapq.heappush(queue, new_pair)
|
||||
|
||||
return distances
|
||||
|
||||
def find_steps(numbers):
|
||||
d = Dijkstra(numbers)
|
||||
for i in range(len(numbers)):
|
||||
# left
|
||||
if i-numbers[i] >= 0:
|
||||
d.add_edge(i, i - numbers[i], numbers[i])
|
||||
# right
|
||||
if i+numbers[i] < len(numbers):
|
||||
d.add_edge(i, i+numbers[i], numbers[i])
|
||||
|
||||
distances = d.find_distances(0)
|
||||
# print(distances, distances[len(numbers)-1])
|
||||
if distances[len(numbers)-1] == math.inf:
|
||||
return -1
|
||||
return distances[len(numbers)-1]
|
||||
|
||||
if __name__ == "__main__":
|
||||
print(find_steps([1, 1, 1, 1])) # 3
|
||||
print(find_steps([3, 2, 1])) # -1
|
||||
print(find_steps([3, 5, 2, 2, 2, 3, 5])) # 10
|
||||
print(find_steps([7, 5, 3, 1, 4, 2, 4, 6, 1])) # 32
|
||||
|
||||
numbers = []
|
||||
for i in range(10**5):
|
||||
numbers.append(1337 * i % 100 + 1)
|
||||
print(find_steps(numbers)) # 100055
|
||||
@@ -0,0 +1,90 @@
|
||||
import math
|
||||
class TrainPrices:
|
||||
def __init__(self):
|
||||
self.nodes = []
|
||||
self.graph = {}
|
||||
for a in self.nodes:
|
||||
for b in self.nodes:
|
||||
distance = 0 if a == b else float("inf")
|
||||
self.graph[(a, b)] = distance
|
||||
|
||||
def add_city(self, name):
|
||||
self.nodes.append(name)
|
||||
self.nodes.sort()
|
||||
for a in self.nodes:
|
||||
for b in self.nodes:
|
||||
distance = 0 if a == b else float("inf")
|
||||
self.graph[(a, b)] = distance
|
||||
|
||||
def add_train(self, a, b, w):
|
||||
self.graph[(a, b)] = min(self.graph[(a, b)], w)
|
||||
self.graph[(b, a)] = min(self.graph[(a, b)], w)
|
||||
|
||||
def find_prices(self):
|
||||
distances = self.graph.copy()
|
||||
|
||||
for k in self.nodes:
|
||||
for a in self.nodes:
|
||||
for b in self.nodes:
|
||||
distance = min(
|
||||
distances[(a, b)], distances[(a, k)] + distances[(k, b)]
|
||||
)
|
||||
distances[(a, b)] = distance
|
||||
|
||||
|
||||
result = []
|
||||
result.append([None] + [x for x in self.nodes])
|
||||
for x in self.nodes:
|
||||
row = [x]
|
||||
for y in self.nodes:
|
||||
row.append(-1 if distances[(x,y)] == math.inf else distances[(x,y)])
|
||||
result.append(row)
|
||||
|
||||
# print(distances)
|
||||
# for x in result:
|
||||
# print(x)
|
||||
return result
|
||||
|
||||
|
||||
class TrainPrices2:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def add_city(self, name):
|
||||
pass
|
||||
|
||||
def add_train(self, city1, city2, price):
|
||||
pass
|
||||
|
||||
def find_prices(self):
|
||||
pass
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
prices = TrainPrices()
|
||||
|
||||
prices.add_city("Helsinki")
|
||||
prices.add_city("Turku")
|
||||
prices.add_city("Tampere")
|
||||
prices.add_city("Oulu")
|
||||
|
||||
prices.add_train("Helsinki", "Tampere", 20)
|
||||
prices.add_train("Helsinki", "Turku", 10)
|
||||
prices.add_train("Tampere", "Turku", 50)
|
||||
|
||||
print(prices.find_prices())
|
||||
print()
|
||||
|
||||
|
||||
prices = TrainPrices()
|
||||
prices.add_city("Helsinki")
|
||||
prices.add_city("Oulu")
|
||||
prices.add_train("Helsinki", "Oulu", 14)
|
||||
print(prices.find_prices())
|
||||
|
||||
# metodin haluttu tulos:
|
||||
# [[None, 'Helsinki', 'Oulu', 'Tampere', 'Turku'],
|
||||
# ['Helsinki', 0, -1, 20, 10],
|
||||
# ['Oulu', -1, 0, -1, -1],
|
||||
# ['Tampere', 20, -1, 0, 30],
|
||||
# ['Turku', 10, -1, 30, 0]]
|
||||
@@ -0,0 +1,46 @@
|
||||
class UnionFind:
|
||||
def __init__(self, nodes):
|
||||
self.link = {node: None for node in nodes}
|
||||
self.size = {node: 1 for node in nodes}
|
||||
|
||||
def find(self, x):
|
||||
while self.link[x]:
|
||||
x = self.link[x]
|
||||
return x
|
||||
|
||||
def union(self, a, b):
|
||||
a = self.find(a)
|
||||
b = self.find(b)
|
||||
if a == b:
|
||||
return
|
||||
|
||||
if self.size[a] > self.size[b]:
|
||||
a, b = b, a
|
||||
self.link[a] = b
|
||||
self.size[b] += self.size[a]
|
||||
|
||||
|
||||
class Components:
|
||||
def __init__(self, n):
|
||||
self.uf = UnionFind([x for x in range(1, n + 1)])
|
||||
|
||||
def add_road(self, a, b):
|
||||
self.uf.union(a, b)
|
||||
|
||||
def count(self):
|
||||
return list(self.uf.link.values()).count(None)
|
||||
|
||||
if __name__ == "__main__":
|
||||
components = Components(5)
|
||||
|
||||
print(components.count()) # 5
|
||||
|
||||
components.add_road(1, 2)
|
||||
components.add_road(1, 3)
|
||||
print(components.count()) # 3
|
||||
|
||||
components.add_road(2, 3)
|
||||
print(components.count()) # 3
|
||||
|
||||
components.add_road(4, 5)
|
||||
print(components.count()) # 2
|
||||
@@ -0,0 +1,57 @@
|
||||
class UnionFind:
|
||||
def __init__(self, nodes):
|
||||
self.link = {node: None for node in nodes}
|
||||
self.size = {node: 1 for node in nodes}
|
||||
self.longest = 1
|
||||
|
||||
def find(self, x):
|
||||
while self.link[x]:
|
||||
x = self.link[x]
|
||||
return x
|
||||
|
||||
def union(self, a, b):
|
||||
a = self.find(a)
|
||||
b = self.find(b)
|
||||
if a == b:
|
||||
return
|
||||
|
||||
if self.size[a] > self.size[b]:
|
||||
a, b = b, a
|
||||
self.link[a] = b
|
||||
self.size[b] += self.size[a]
|
||||
self.longest = max(self.size[b], self.longest)
|
||||
|
||||
def get_max(self):
|
||||
return self.longest
|
||||
|
||||
|
||||
class MaxSet:
|
||||
def __init__(self, n):
|
||||
self.uf = UnionFind([x for x in range(1, n + 1)])
|
||||
|
||||
def merge(self, a, b):
|
||||
self.uf.union(a, b)
|
||||
|
||||
def get_max(self):
|
||||
return self.uf.get_max()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
max_set = MaxSet(5)
|
||||
print(max_set.get_max()) # 1
|
||||
|
||||
max_set.merge(1, 2)
|
||||
max_set.merge(3, 4)
|
||||
max_set.merge(3, 5)
|
||||
print(max_set.get_max()) # 3
|
||||
|
||||
max_set.merge(1, 5)
|
||||
print(max_set.get_max()) # 5
|
||||
|
||||
max_set.merge(2, 3)
|
||||
print(max_set.get_max()) # 5
|
||||
|
||||
max_set = MaxSet(10**5)
|
||||
for i in range(2, 10**5 + 1):
|
||||
max_set.merge(1, i)
|
||||
print(max_set.get_max())
|
||||
@@ -0,0 +1,62 @@
|
||||
class UnionFind:
|
||||
def __init__(self, nodes):
|
||||
self.link = {node: None for node in nodes}
|
||||
self.size = {node: 1 for node in nodes}
|
||||
|
||||
def find(self, x: int):
|
||||
while self.link.get(x):
|
||||
x = self.link.get(x)
|
||||
return x
|
||||
|
||||
def union(self, a, b):
|
||||
a = self.find(a)
|
||||
b = self.find(b)
|
||||
if a == b:
|
||||
return
|
||||
|
||||
if self.size[a] > self.size[b]:
|
||||
a, b = b, a
|
||||
self.link[a] = b
|
||||
self.size[b] += self.size[a]
|
||||
|
||||
|
||||
class NewRoads:
|
||||
def __init__(self, nodes):
|
||||
nodes = [x for x in range(1, nodes + 1)]
|
||||
self.nodes = nodes
|
||||
self.edges = []
|
||||
|
||||
def add_road(self, node_a, node_b, weight):
|
||||
self.edges.append((node_a, node_b, weight))
|
||||
|
||||
def min_cost(self):
|
||||
self.edges.sort(key=lambda x: x[2])
|
||||
|
||||
uf = UnionFind(self.nodes)
|
||||
edges_count = 0
|
||||
tree_weight = 0
|
||||
|
||||
for edge in self.edges:
|
||||
node_a, node_b, weight = edge
|
||||
if uf.find(node_a) != uf.find(node_b):
|
||||
uf.union(node_a, node_b)
|
||||
edges_count += 1
|
||||
tree_weight += weight
|
||||
|
||||
if edges_count != len(self.nodes) - 1:
|
||||
return -1
|
||||
return tree_weight
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
new_roads = NewRoads(4)
|
||||
|
||||
new_roads.add_road(1, 2, 2)
|
||||
new_roads.add_road(1, 3, 5)
|
||||
print(new_roads.min_cost()) # -1
|
||||
|
||||
new_roads.add_road(3, 4, 4)
|
||||
print(new_roads.min_cost()) # 11
|
||||
|
||||
new_roads.add_road(2, 3, 1)
|
||||
print(new_roads.min_cost()) # 7
|
||||
@@ -0,0 +1,60 @@
|
||||
class UnionFind:
|
||||
def __init__(self, nodes):
|
||||
self.link = {node: None for node in nodes}
|
||||
self.size = {node: 1 for node in nodes}
|
||||
|
||||
def find(self, x):
|
||||
while self.link[x]:
|
||||
x = self.link[x]
|
||||
return x
|
||||
|
||||
def union(self, a, b):
|
||||
a = self.find(a)
|
||||
b = self.find(b)
|
||||
if a == b:
|
||||
return
|
||||
|
||||
if self.size[a] > self.size[b]:
|
||||
a, b = b, a
|
||||
self.link[a] = b
|
||||
self.size[b] += self.size[a]
|
||||
|
||||
class Kruskal:
|
||||
def __init__(self, nodes):
|
||||
self.nodes = nodes
|
||||
self.edges = []
|
||||
|
||||
def add_edge(self, node_a, node_b, weight):
|
||||
self.edges.append((node_a, node_b, weight))
|
||||
|
||||
def construct(self):
|
||||
self.edges.sort(key=lambda x: -x[2])
|
||||
|
||||
uf = UnionFind(self.nodes)
|
||||
edges_count = 0
|
||||
tree_weight = 0
|
||||
|
||||
for edge in self.edges:
|
||||
node_a, node_b, weight = edge
|
||||
if uf.find(node_a) != uf.find(node_b):
|
||||
print(node_a, node_b)
|
||||
uf.union(node_a, node_b)
|
||||
edges_count += 1
|
||||
tree_weight += weight
|
||||
|
||||
if edges_count != len(self.nodes) - 1:
|
||||
return None
|
||||
return tree_weight
|
||||
|
||||
def main():
|
||||
nodes = [x for x in range(1,1000+1)]
|
||||
k = Kruskal(nodes)
|
||||
for i in nodes:
|
||||
for j in range(1,i):
|
||||
k.add_edge(j, i, min(i, j))
|
||||
|
||||
print(k.construct())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user