def test_negative_edge_cycle(self): G = nx.cycle_graph(5, create_using = nx.DiGraph()) assert_equal(nx.negative_edge_cycle(G), False) G.add_edge(8, 9, weight = -7) G.add_edge(9, 8, weight = 3) assert_equal(nx.negative_edge_cycle(G), True) assert_raises(ValueError,nx.single_source_dijkstra_path_length,G,8) assert_raises(ValueError,nx.single_source_dijkstra,G,8) assert_raises(ValueError,nx.dijkstra_predecessor_and_distance,G,8) G.add_edge(9,10) assert_raises(ValueError,nx.bidirectional_dijkstra,G,8,10)
def test_negative_weight_cycle_heuristic(self): G = nx.DiGraph() G.add_edge(0, 1, weight=-1) G.add_edge(1, 2, weight=-1) G.add_edge(2, 3, weight=-1) G.add_edge(3, 0, weight=3) assert not nx.negative_edge_cycle(G, heuristic=True) G.add_edge(2, 0, weight=1.999) assert nx.negative_edge_cycle(G, heuristic=True) G.edges[2, 0]["weight"] = 2 assert not nx.negative_edge_cycle(G, heuristic=True)
def test_negative_edge_cycle(self): G = nx.cycle_graph(5, create_using=nx.DiGraph()) assert_equal(nx.negative_edge_cycle(G), False) G.add_edge(8, 9, weight=-7) G.add_edge(9, 8, weight=3) assert_equal(nx.negative_edge_cycle(G), True) assert_raises(ValueError, nx.single_source_dijkstra_path_length, G, 8) assert_raises(ValueError, nx.single_source_dijkstra, G, 8) assert_raises(ValueError, nx.dijkstra_predecessor_and_distance, G, 8) G.add_edge(9, 10) assert_raises(ValueError, nx.bidirectional_dijkstra, G, 8, 10)
def test_negative_edge_cycle(self): G = nx.cycle_graph(5, create_using=nx.DiGraph()) assert not nx.negative_edge_cycle(G) G.add_edge(8, 9, weight=-7) G.add_edge(9, 8, weight=3) graph_size = len(G) assert nx.negative_edge_cycle(G) assert graph_size == len(G) pytest.raises(ValueError, nx.single_source_dijkstra_path_length, G, 8) pytest.raises(ValueError, nx.single_source_dijkstra, G, 8) pytest.raises(ValueError, nx.dijkstra_predecessor_and_distance, G, 8) G.add_edge(9, 10) pytest.raises(ValueError, nx.bidirectional_dijkstra, G, 8, 10)
def test_negative_weight_cycle_consistency(self): import random unif = random.uniform for random_seed in range(2): # range(20): random.seed(random_seed) for density in [.1, .9]: # .3, .7, .9]: for N in [1, 10, 20]: # range(1, 60 - int(30 * density)): for max_cost in [1, 90]: # [1, 10, 40, 90]: G = nx.binomial_graph(N, density, seed=4, directed=True) edges = ((u, v, unif(-1, max_cost)) for u, v in G.edges) G.add_weighted_edges_from(edges) no_heuristic = nx.negative_edge_cycle(G, heuristic=False) with_heuristic = nx.negative_edge_cycle(G, heuristic=True) assert no_heuristic == with_heuristic
def currency_exchange_solution(t: List[List[float]]) -> bool: """ Determine if an arbitrage is possible :param t: table for converting between currencies. if t[i][j] = x, it means that 1 of current i equals x of currency j. :return: True if an arbitrage is possible, else False """ """ idea: we can create a graph with n nodes and n^2 edges, such that the edge from node i to node j has weight t[i][j]. we are looking for a cycle of currencies i1, i2, ..., i_k, i1 such that t[i1][i2]*...*t[i_k][i1] > 1 - so actually, we are looking for a cycle that the multiplication of it's weights is bigger than one. let's try to convert this condition into negative sum cycle, that we can easily detect (using bellman-ford). we know that log operation (on any base) converts multiplication operation into summing - log(a*b) = log(a) + log(b) and in addition log(1) = 0. so, if we use log(t[i][j]) as the weight of an edge, we are looking now for a positive cycle. by using -log(t[i][j]) we convert the problem into looking for the existence of negative cycle. """ n = len(t) g = nx.DiGraph() g.add_nodes_from(range(n)) for i in range(n): for j in range(n): g.add_weighted_edges_from([(i, j, -np.log(t[i][j]))]) return nx.negative_edge_cycle( g ) # since bellman ford requires a source, this method adds a new node that is
def _detect_unboundedness(R): """Detect infinite-capacity negative cycles. """ s = generate_unique_node() G = nx.DiGraph() G.add_nodes_from(R) # Value simulating infinity. inf = R.graph['inf'] # True infinity. f_inf = float('inf') for u in R: for v, e in R[u].items(): # Compute the minimum weight of infinite-capacity (u, v) edges. w = f_inf for k, e in e.items(): if e['capacity'] == inf: w = min(w, e['weight']) if w != f_inf: G.add_edge(u, v, weight=w) if nx.negative_edge_cycle(G): raise nx.NetworkXUnbounded( 'Negative cost cycle of infinite capacity found. ' 'Min cost flow may be unbounded below.')
def __init__(self, G, max_res, min_res, preprocess, REF, algorithm=None): # Check inputs check(G, max_res, min_res, REF_forward=REF, algorithm=__name__) # Preprocess graph self.G = preprocess_graph(G, max_res, min_res, preprocess, REF) self.max_res = max_res self.min_res = min_res # Update resource extension function if given if REF: self.REF = REF else: self.REF = add if negative_edge_cycle(G) or algorithm == "simple": self.algorithm = "simple" else: self.algorithm = "astar" # Attribute to hold source-sink path self.st_path = None # Attribrutes for exposure # # resource feasible source-sink path self.best_path = None # Final cost self.best_path_cost = None # Final resource consumption self.best_path_total_res = None
def consistent_stn(self,add_tcs=[]): """ Returns whether a Simple Temporal Network is consistent. """ #Checks if there are additional constraints to be temporarily added #to the graph. if len(add_tcs)>0: for tc in add_tcs: #Adds temporary constraints self.add_temporal_constraint(tc) #Checks if it is consistent neg_cycles = nx.negative_edge_cycle(self._dist_graph) for tc in add_tcs: #Removes temporary constraints self.remove_temporal_constraint(tc) return not neg_cycles else: return not nx.negative_edge_cycle(self._dist_graph)
def checkIsMLExist(StateTransitionProbs, HoldingTimes): #We will check is there a ML trajectory which is equivalent to \prod_{i=0}^{k-1}P_{s_i,s_{i+1}\lambda_{s_i}>1} #We will start with creating an DAG with edge weights log P_{s,s^\prime}\lambda_s NumOfStates = StateTransitionProbs.shape[1] WeightGraph = np.zeros((NumOfStates, NumOfStates)) #Check for log(0) LogGraph = np.log(StateTransitionProbs) LogGraph = np.multiply(LogGraph, np.tile(HoldingTimes, (1, NumOfStates))) G = nx.from_numpy_matrix(LogGraph, create_using=nx.DiGraph()) return not nx.negative_edge_cycle((-1) * G)
def checkIsMLExist(StateTransitionProbs,HoldingTimes): #We will check is there a ML trajectory which is equivalent to \prod_{i=0}^{k-1}P_{s_i,s_{i+1}\lambda_{s_i}>1} #We will start with creating an DAG with edge weights log P_{s,s^\prime}\lambda_s NumOfStates = StateTransitionProbs.shape[1] WeightGraph = np.zeros((NumOfStates,NumOfStates)) #Check for log(0) LogGraph = np.log(StateTransitionProbs) LogGraph = np.multiply(LogGraph,np.tile(HoldingTimes,(1,NumOfStates))) G=nx.from_numpy_matrix(LogGraph,create_using=nx.DiGraph()) return not nx.negative_edge_cycle((-1)*G)
def initialize_graph_characteristics_weighted(self): """ Initializes class attributes which asscociated especially with weighted graphs such as if graph has negative cycles, if graph has negative weights, average shortest path length based on weights of edges. """ self.check_if_has_negative_weights() self.negative_cycle = nx.negative_edge_cycle(self.graph, 'weight') self.average_shortest_path_length.append( calculate_average_shortest_path_length(self.graph, 'weight'))
def _formulate(self): # minimize reduced cost self.prob += pulp.lpSum( [ self.sub_G.edges[i, j]["weight"] * self.x[(i, j)] for (i, j) in self.sub_G.edges() ] ) # flow balance for v in self.sub_G.nodes(): if v not in ["Source", "Sink"]: in_flow = pulp.lpSum( [self.x[(i, v)] for i in self.sub_G.predecessors(v)] ) out_flow = pulp.lpSum( [self.x[(v, j)] for j in self.sub_G.successors(v)] ) self.prob += in_flow == out_flow, "flow_balance_%s" % v # Start at Source and end at Sink self.prob += ( pulp.lpSum([self.x[("Source", v)] for v in self.sub_G.successors("Source")]) == 1, "start_at_source", ) self.prob += ( pulp.lpSum([self.x[(u, "Sink")] for u in self.sub_G.predecessors("Sink")]) == 1, "end_at_sink", ) # Forbid route Source-Sink self.prob += ( pulp.lpSum([self.x[(i, j)] for (i, j) in self.sub_G.edges()]) >= 2, "at_least_1_stop", ) # Problem specific constraints if self.time_windows: self._add_time_windows() if self.num_stops: self._add_max_stops() if self.load_capacity: self._add_max_load() if self.duration: self._add_max_duration() self.elementarity = False if negative_edge_cycle(self.G): logger.debug("negative cycle found") self._add_elementarity() self.elementarity = True if self.pickup_delivery: self._add_pickup_delivery() if self.distribution_collection: self._add_distribution_collection()
def find_arbitrage(filename="snapshot.csv", find_all=False, sources=None): """ Looks for arbitrage opportunities within a snapshot, i.e negative-weight cycles that include the currencies given in the sources list :param filename: filename of snapshot, defaults to "snapshot.csv" :type filename: str, optional :param find_all: whether to find all paths, defaults to False. If false, sources must be provided. :type find_all: bool, optional :param sources: list of starting nodes – should choose the 'most connected' pairs, defaults to None. :type sources: str list, optional :return: list of negative-weight cycles, or None if none exist :rtype: str list """ # Read df and convert to negative logs so we can use Bellman Ford # Negative weight cycles thus correspond to arbitrage opps # Transpose log_df so that graph has same API as the dataframe df = pd.read_csv(filename, header=0, index_col=0) g = nx.DiGraph(-np.log(df).fillna(0).T) if nx.negative_edge_cycle(g): print("ARBITRAGE FOUND\n" + "=" * 15 + "\n") if find_all: unique_cycles = all_negative_cycles(g) else: all_paths = [] for s in sources: all_paths.append(bellman_ford_negative_cycles(g, s)) flatten = lambda l: [item for sublist in l for item in sublist] unique_cycles = [ list(i) for i in set(tuple(j) for j in flatten(all_paths)) ] for p in unique_cycles: calculate_arb(p, g) return unique_cycles else: print("No arbitrage opportunities") return None
def process(filename): edges, vertexesNumber, edgesNumber = read(filename) G = nx.DiGraph() G.add_nodes_from(xrange(1, vertexesNumber + 1)) G.add_weighted_edges_from(edges) print "Graph %s formed" % filename if nx.negative_edge_cycle(G): print "Graph %s has negative cycle" % filename return print "Begin FW for %s" % filename lengths = nx.floyd_warshall(G) shortestPathLengths = map(dict.values, lengths.values()) shortestPathLength = min(min(raw) for raw in shortestPathLengths) print "Shortest path for %s: %d" % (filename, shortestPathLength)
def create_graph(cvor): """ Kreiranje random direktiranog grafa Parameters ---------- cvor: int Broj čvorova za kreiranje random grafa Returns ------- Vraća matricu koja sadržava sve vrijednosti novokreiranog grafa """ G = nx.generators.directed.random_k_out_graph( cvor, 3, 0.75, self_loops=False) # networkx naredba za generiranje direktiranog grafa # postavljanje random weighta na svaki pravac u grafu for (u, v, w) in G.edges(data=True): w['weight'] = random.randint(-2, 5) if nx.negative_edge_cycle(G): print('Warning: created graph contains negative cycles') # kreiranje pdf-a prije konvertiranja grafa create_pdf(G) #konverzija grafa u matricu adj_matrix = nx.to_numpy_array(G).astype( int) # pretvorba grafa u numpy array tipa int for i, row in enumerate( adj_matrix ): # pretvara sve nule u 2D arrayu u INF za daljnji rad sa njim for j, column in enumerate(row): if i != j and adj_matrix[i][j] == 0: adj_matrix[i][j] = INF return adj_matrix
def main(): data = getTickerData() Graph = createGraphFromData(data) Graph = prepEdges(Graph) print nx.info(Graph) print(nx.negative_edge_cycle(Graph)) #print nx.bellman_ford(G,'BTC',weight='weight') import pylab pos = nx.spring_layout(Graph) # version 1 pylab.figure(1) nx.draw(Graph, pos) # use default edge labels nx.draw_networkx_edge_labels(Graph, pos) # show graphs pylab.show() pos = nx.spring_layout(Graph) nx.draw_networkx_edges(Graph, pos) plt.show()
def _detect_unboundedness(R): """Detect infinite-capacity negative cycles.""" G = nx.DiGraph() G.add_nodes_from(R) # Value simulating infinity. inf = R.graph["inf"] # True infinity. f_inf = float("inf") for u in R: for v, e in R[u].items(): # Compute the minimum weight of infinite-capacity (u, v) edges. w = f_inf for k, e in e.items(): if e["capacity"] == inf: w = min(w, e["weight"]) if w != f_inf: G.add_edge(u, v, weight=w) if nx.negative_edge_cycle(G): raise nx.NetworkXUnbounded( "Negative cost cycle of infinite capacity found. " "Min cost flow may be unbounded below.")
def prog_25(fname): graphs = {} f = open(fname) ns = eval(f.readline().strip()) for i in xrange(ns): graph = nx.DiGraph() nds,eds = map(int, f.readline().strip().split()) for j in xrange(eds): e1,e2,w = map(int, f.readline().strip().split()) graph.add_weighted_edges_from([(e1,e2,w)]) graphs[i]=graph f.close() for i in xrange(ns): graph = graphs[i] if nx.negative_edge_cycle(graph): print 1, else: print -1,
def bellmanFord(): """ Génere une question sur l'agorithme de Dijkstra au format json : - question Dijkstra - graph pondéré - graph dirigé ou non - bonne réponse plus court chemin - mauvaise réponses """ avecPoids = 1 # random.randint(0,1) #generation graph pondere question = "{ \"question\": \"D'après l'algorithme de Bellman-Ford, quel est le plus court chemin entre le noeud A et le noeud E ?\", " if (avecPoids): ponderate = "\"ponderate\": \"True\", " else: ponderate = "\"ponderate\": \"False\", " colorBase = "\"colorbase\": \"{0,4}\", " #noeud a colorer de base colorReponse = "\"colorreponse\": " #noeud a colorer a l'affichage de la reponse complementReponse = "\"complementreponse\": \"None\", " base = nx.fast_gnp_random_graph( 1, 0, None, True ) #base -> graph dirigé obligatoire pour utiliser l'ago de bellman-ford nbrReponse = 0 while nbrReponse < 3: G = nx.path_graph(5, base) #creation path_graph de base à 5 noeuds #ajout noeuds supplémentaires for i in range(5, 10): G.add_node(i) #ajout random arcs for i in range(0, 10): G.add_edge(random.randint(0, 9), random.randint(0, 9)) #suppression de l'arc A - E si il existe pour compliquer la réponse G.add_edge(0, 4) G.remove_edge(0, 4) if (avecPoids): G = addWeightNegatif(G) #ajout des poids random sur les arcs nbrReponse = nombreReponse(G) negativeCycle = nx.negative_edge_cycle(G, weight='weight') G = addEdgesIds(G) graph = graphToJson(G) #mise au format Json #si presence de cycle négatif utilisation de bellman-ford impossible if (negativeCycle): true_answer = "Utilisation de l'algorithme impossible." reponse_true = ", \"true_answer\": \"" reponse_true += true_answer colorReponse += "\"None\", " complementReponse = "\"complementreponse\": \"L'algorithme de Bellman-Ford ne s'applique pas aux graphes possédant des cycles négatifs.\"," else: true_answer = nx.bellman_ford_path(G, 0, 4, weight='weight') reponse_true = ", \"true_answer\": \"" #change node id to char value colorReponse += "{ \"nodes\": \"{" for i in true_answer: if i == true_answer[len(true_answer) - 1]: reponse_true += chr(i + 65) colorReponse += str(i) else: reponse_true += chr(i + 65) + "-" colorReponse += str(i) + ", " colorReponse += "}\", \"edges\": \"{" reponse_true += "\"" if not negativeCycle: #ajout des arcs à colorer dans colorReponse i = 0 j = 1 while j < len(true_answer): colorReponse += str(G[true_answer[i]][true_answer[j]]['id']) + "," i += 1 j += 1 colorReponse = colorReponse[:len(colorReponse) - 1] #cut dernière virgule colorReponse += "}\"}," #fermeture ensemble pour respecter format json colorReponse = colorReponse.replace( " ", "") #suppression des " " pour un meilleure parsage en javascript else: listCycle = nx.find_cycle(G, source=None, orientation='original') print(listCycle) #mauvaise reponse reponse_wrong = ", \"wrong_answer\": \"" + wrongAnswer(G, true_answer) + "\"" graph = graph[ 1:len(graph) - 1] #cut { et } pour ajouter la question/réponse et garder un format json valide graph = question + ponderate + colorBase + colorReponse + complementReponse + str( graph ) + str( reponse_true ) + reponse_wrong + "}" #ajout question/reponse dans le format json + fermeture de l'objet json avec } return graph
def test_negative_edge_cycle(self): G = nx.cycle_graph(5, create_using = nx.DiGraph()) assert_equal(nx.negative_edge_cycle(G), False) G.add_edge(8, 9, weight = -7) G.add_edge(9, 8, weight = 3) assert_equal(nx.negative_edge_cycle(G), True)
# g.add_edge("USD","JPY", {"weight": 91.9943456}) # g = nx.cycle_graph(nodes, create_using=nx.DiGraph()) g.add_nodes_from(nodes) g.add_weighted_edges_from(newdata) options = { 'node_color': 'yellow', 'node_size': 330, 'width': 1, 'arrowstyle': '-|>', 'arrowsize': 32, 'with_labels': True, 'font_size': 10 } # pos = nx.circular_layout(g) # nx.draw(g, with_labels=True, node_color='y') layout = nx.circular_layout(g) nx.draw_networkx_edge_labels(g, layout, label_pos=0.3) nx.draw_networkx_nodes(g, layout, node_color='yellow', node_size=500) nx.draw_networkx_edges(g, layout, edge_color='r', arrows=True, arrowstyle='-|>', arrowsize=20) nx.draw_networkx_labels(g, layout, font_size=10, font_family="sans-serif") # nx.draw_networkx(g, arrows=True, **options) print(nx.negative_edge_cycle(g)) print(nx.single_source_bellman_ford_path(g, "USD")) plt.show()
import kraken.computation.dummy_data as data import matplotlib.pyplot as plt import networkx as nx from kraken.computation import utils G = nx.DiGraph() G.add_nodes_from(data.NODES_CYCLE) G.add_weighted_edges_from(utils.log_weight(data.EDGES_CYCLE)) if nx.negative_edge_cycle(G): profitable = utils.cycle_filter(nx.simple_cycles(G), data.EDGES_CYCLE, max_cycle=3, min_cycle=3) for c, p in profitable: print("Profit for cycle %s: %s" % (c, p)) else: print('No negative cycle found') d = G.get_edge_data('USD', 'ETH') print(d) # for c in nx.simple_cycles(G): # print(c) # nx.draw(G, with_labels=True) # plt.show()
def test_negative_edge_cycle_custom_weight_key(self): d = nx.DiGraph() d.add_edge("a", "b", w=-2) d.add_edge("b", "a", w=-1) assert nx.negative_edge_cycle(d, weight="w")
def calc_neg(ex1="USD", ex2="BTC"): #nx.astar_path(G, "USD", "BTC") nx.negative_edge_cycle(G) return nx.astar_path(G, ex1, ex2)
# Iterate graphs results = [] for graph in graphs: # Create graph G = nx.DiGraph() # Unique nodes flat_list = [val for sublist in graph for val in sublist] uniq_node = list(set(flat_list)) for node in range(1, max(uniq_node)): G.add_node(node) # Place edges for pair in graph: G.add_edge(pair[0], pair[1], weight=pair[2]) # Compute connected components cycle = nx.negative_edge_cycle(G) if cycle == True: results.append(1) else: results.append(-1) # AG = nx.nx_agraph.to_agraph(G) # AG.write("file.dot") # AG.layout() # AG.draw(f'file{i}.png') print(" ".join([str(x) for x in results]))
db = current_price["ticker"]["buy"] # print ds # print db p = (base, alt, {"weight": -1.0 * math.log(float(db))}) b = (alt, base, {"weight": -1.0 * math.log(1 / float(ds))}) conj1 = base + "_" + alt conj2 = alt + "_" + base price_dict[conj1] = float(db) price_dict[conj2] = 1 / float(ds) # print p # print b G.add_edges_from([p]) G.add_edges_from([b]) print "price_dict", price_dict neg_check = nx.negative_edge_cycle(G) print neg_check ub_grow = nx.astar_path(G, "usd", "btc") print "ub_grow", ub_grow print ub_grow[-1] + "_" + ub_grow[0] ub_moneyWalk = [] if neg_check == True: for i in ub_grow[1:]: key_finder = ub_grow[ub_grow.index(i) - 1] + "_" + ub_grow[(ub_grow.index(i))] key = price_dict[key_finder] print key # print 'key_finder', key_finder print price_dict[key_finder]
# cycles in a graph import networkx as nx from itertools import combinations f = open('rosalind_nwc.txt') k = int(f.readline().rstrip()) result = [] for i in range(k): s = '' while s == '': s = f.readline().rstrip() n, m = [int(l) for l in s.split()] nodes = [i+1 for i in range(n)] G = nx.DiGraph() G.add_nodes_from(nodes) edges = [(int(l) for l in f.readline().rstrip().split()) for j in range(m)] G.add_weighted_edges_from(edges) output = '-1' if nx.negative_edge_cycle(G, weight='weight'): output = '1' result.append(output) result = ' '.join(result) print(result) open('rosalind_nwc_sub.txt', 'wt').write(result)
# rosalind_sq # cycles in a graph import networkx as nx from itertools import combinations f = open('rosalind_nwc.txt') k = int(f.readline().rstrip()) result = [] for i in range(k): s = '' while s == '': s = f.readline().rstrip() n, m = [int(l) for l in s.split()] nodes = [i + 1 for i in range(n)] G = nx.DiGraph() G.add_nodes_from(nodes) edges = [(int(l) for l in f.readline().rstrip().split()) for j in range(m)] G.add_weighted_edges_from(edges) output = '-1' if nx.negative_edge_cycle(G, weight='weight'): output = '1' result.append(output) result = ' '.join(result) print(result) open('rosalind_nwc_sub.txt', 'wt').write(result)
def test_negative_edge_cycle(self): G = nx.cycle_graph(5, create_using=nx.DiGraph()) assert_equal(nx.negative_edge_cycle(G), False) G.add_edge(8, 9, weight=-7) G.add_edge(9, 8, weight=3) assert_equal(nx.negative_edge_cycle(G), True)
def negativeCycle(fileName="./" + SUBDIRNAME + "/negCycle.png"): print() G = nx.MultiDiGraph() G.add_edges_from([ (4, 5, { 'weight': 0.35 }), (5, 4, { 'weight': -0.66 }), (4, 7, { 'weight': 0.37 }), (5, 7, { 'weight': 0.28 }), (7, 5, { 'weight': 0.28 }), (5, 1, { 'weight': 0.32 }), (0, 4, { 'weight': 0.38 }), (0, 2, { 'weight': 0.26 }), (7, 3, { 'weight': 0.39 }), (1, 3, { 'weight': 0.29 }), (2, 7, { 'weight': 0.34 }), (6, 2, { 'weight': 0.40 }), (3, 6, { 'weight': 0.52 }), (6, 0, { 'weight': 0.58 }), (6, 4, { 'weight': 0.93 }), ]) print('Negative cycles: ' + str(nx.negative_edge_cycle(G))) Gprime = G.copy() # modify G to include labels for weights, so it can be drawn for edge in G.edges(): Gprime[edge[0]][edge[1]][0].update( {'label': Gprime[edge[0]][edge[1]][0]['weight']}) # convert to dot d = nx.drawing.nx_pydot.to_pydot(Gprime) print(d) print("Saving file to " + str(fileName)) d.write_png(fileName)