01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
|
package algs44;
import stdlib.*;
/* ***********************************************************************
* Compilation: javac Arbitrage.java
* Execution: java Arbitrage < input.txt
* Dependencies: EdgeWeightedDigraph.java DirectedEdge.java
* BellmanFordSP.java
* Data file: http://algs4.cs.princeton.edu/44sp/rates.txt
*
* Arbitrage detection.
*
* % more rates.txt
* 5
* USD 1 0.741 0.657 1.061 1.005
* EUR 1.349 1 0.888 1.433 1.366
* GBP 1.521 1.126 1 1.614 1.538
* CHF 0.942 0.698 0.619 1 0.953
* CAD 0.995 0.732 0.650 1.049 1
*
* % java Arbitrage < rates.txt
* 1000.00000 USD = 741.00000 EUR
* 741.00000 EUR = 1012.20600 CAD
* 1012.20600 CAD = 1007.14497 USD
*
*************************************************************************/
public class Arbitrage {
public static void main(String[] args) {
// V currencies
int V = StdIn.readInt();
String[] name = new String[V];
// create complete network
EdgeWeightedDigraph G = new EdgeWeightedDigraph(V);
for (int v = 0; v < V; v++) {
name[v] = StdIn.readString();
for (int w = 0; w < V; w++) {
double rate = StdIn.readDouble();
DirectedEdge e = new DirectedEdge(v, w, -Math.log(rate));
G.addEdge(e);
}
}
// find negative cycle
BellmanFordSP spt = new BellmanFordSP(G, 0);
if (spt.hasNegativeCycle()) {
double stake = 1000.0;
for (DirectedEdge e : spt.negativeCycle()) {
StdOut.format("%10.5f %s ", stake, name[e.from()]);
stake *= Math.exp(-e.weight());
StdOut.format("= %10.5f %s\n", stake, name[e.to()]);
}
}
else {
StdOut.println("No arbitrage opportunity");
}
}
}
|