Arbitrages: First working version
This commit is contained in:
83
Arbitrages/cs412_arbitrages_a.py
Normal file
83
Arbitrages/cs412_arbitrages_a.py
Normal file
@@ -0,0 +1,83 @@
|
||||
"""
|
||||
name: Nicholas Tamassia
|
||||
|
||||
Honor Code and Acknowledgments:
|
||||
|
||||
This work complies with the JMU Honor Code.
|
||||
|
||||
Comments here on your code and submission.
|
||||
"""
|
||||
|
||||
import math
|
||||
from collections import defaultdict
|
||||
|
||||
|
||||
def find_arbitrage(graph: dict[str, dict[str, float]]) -> list[str] | None:
|
||||
weights: dict[str, float] = {c: math.inf for c in graph}
|
||||
prev: dict[str, str | None] = {c: None for c in graph}
|
||||
start: str = list(graph.keys())[0]
|
||||
|
||||
weights[start] = 0
|
||||
for _ in range(len(graph) - 1):
|
||||
for src in graph:
|
||||
for dest, rate in graph[src].items():
|
||||
weight: float = -math.log(rate)
|
||||
if weights[src] + weight < weights[dest]:
|
||||
weights[dest] = weights[src] + weight
|
||||
prev[dest] = src
|
||||
|
||||
node: str | None = None
|
||||
for src in graph:
|
||||
for dest, rate in graph[src].items():
|
||||
weight: float = -math.log(rate)
|
||||
if weights[src] + weight < weights[dest]:
|
||||
node = dest
|
||||
prev[dest] = src
|
||||
break
|
||||
if node is not None:
|
||||
break
|
||||
|
||||
if node is None:
|
||||
return
|
||||
|
||||
for _ in range(len(graph)):
|
||||
node = prev[node]
|
||||
|
||||
path = [node]
|
||||
while True:
|
||||
node = prev[node]
|
||||
path.append(node)
|
||||
if node == path[0]:
|
||||
break
|
||||
|
||||
path.reverse()
|
||||
|
||||
return path
|
||||
|
||||
|
||||
def main():
|
||||
n: int = int(input().strip())
|
||||
graph: dict[str, dict[str, float]] = defaultdict(dict)
|
||||
|
||||
for _ in range(n):
|
||||
vals: list[str] = input().strip().split()
|
||||
src: str = vals[0]
|
||||
dest: str = vals[1]
|
||||
rate: float = float(vals[2])
|
||||
graph[src][dest] = rate
|
||||
|
||||
path = find_arbitrage(graph)
|
||||
if path is not None:
|
||||
print("Arbitrage Detected")
|
||||
print(" => ".join(path))
|
||||
|
||||
factor = 1.0
|
||||
for i in range(len(path) - 1):
|
||||
factor *= graph[path[i]][path[i + 1]]
|
||||
print(f"{factor:.5f} factor increase")
|
||||
else:
|
||||
print("No Arbitrage Detected")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user