def saturate_source(s,n,Edge,Cost, node_potential,Part_Flow, curr_demand, sink,no_sat_source, Tight_Loose, Tight_Loose_No, No_Max_Flow ): no_sat_source[s] += 1 #print "Desaturate source being called " #Construct residual graph for it #New residual graph required every time Gr_Edge = [[0 for x in range(n)] for x in range(n)] Gr_Cost = [[0 for x in range(n)] for x in range(n)] Gr_Capacity = [[0 for x in range(n)] for x in range(n)] for u in range(n): for v in range(n): if Edge[u][v]>0: #if edge (u,v) in original graph, then temp1 = Tight_Loose[u][v] #if tight edge: if (node_potential[u] - node_potential[v]) == Cost[u][v]: print "Tight edge", u , ":", v ,"found" Gr_Capacity[u][v]= 1000 #infinity capacity Gr_Edge[u][v]=1 Gr_Cost[u][v]=Cost[u][v] Tight_Loose[u][v] = 1 else: Tight_Loose[u][v] = 0 #increments counter by 1 when edge goes from tight to loose and vice versa if temp1 != Tight_Loose[u][v]: Tight_Loose_No[u][v] += 1 #reverse arc: if Part_Flow[u][v] >0 : Gr_Edge[v][u]=1 Gr_Capacity[v][u]=Part_Flow[u][v] Gr_Cost[v][u]= -Cost[u][v] #residual graph completed #Find if any unsaturated sink t reachable from s parent = [-1 for x in range(n)] t = mod_bfs(Gr_Edge,s,parent,sink) print "Current sinks are: ", sink print "t found from mod_bfs is: ", t print "" if t != -1 : #say path found with flow f, then, along the path #Part_Flow[u][v] += f #Need to get f by min. if curr_demand[s] > -curr_demand[t] : f = -curr_demand[t] #sink.remove(t) #saturated sink removed else: f = curr_demand[s] '''#deploy capacity constraint v =t min_cap = 0 cap_list =[] while v != s: u = parent[v] #Part_Flow[u][t] += f cap_list.append(Gr_Capacity[u][v]) v = u min_cap = min(cap_list) path_capacity = min(f, min_cap) curr_demand[s] -= path_capacity curr_demand[t] += path_capacity #because sink has negative demand while source has positive demand, hence the sign difference if curr_demand[t] == 0: sink.remove(t) #Update flow along the path while t!=s : u = parent[t] Part_Flow[u][t] += path_capacity t = u''' #Finding max. flow between source and sink first found (using modified edmondns karp to find max. augmenting path) MF_Capacity = [[0 for x in range(n)] for x in range(n)] MF_Flow = [[0 for x in range(n)] for x in range(n)] for u in range(n): for v in range(n): MF_Capacity[u][v] = min(f, Gr_Capacity[u][v]) # min of these 2 because flow cannot be more than supply/demand at source/sink #maxFlow = edmonds_karp(n,s,t,MF_Capacity, Part_Flow) maxFlow = edmonds_karp(n,s,t,MF_Capacity, MF_Flow, f ) for u in range(n): for v in range(n): Part_Flow[u][v] += MF_Flow[u][v] No_Max_Flow[s][t] += 1 print "" print "maxFlow found is: ", maxFlow curr_demand[s] -= maxFlow curr_demand[t] += maxFlow #because sink has negative demand while source has positive demand, hence the sign difference if curr_demand[t] == 0: sink.remove(t) #print "" print "Sink removed: ",t #print "" print "Current demand array is: ", curr_demand #check if source is saturated: if curr_demand[s] > 0: saturate_source(s,n,Edge,Cost,node_potential,Part_Flow,curr_demand,sink,no_sat_source, Tight_Loose, Tight_Loose_No,No_Max_Flow) else: #i.e. when no reachable unsat. sink from this unsat. source s, we raise node potentials, definitely define new routine for this print "We need to raise node potential for source ", s raise_node_potentials(s, n, Edge, Cost, node_potential, Gr_Edge) # need to go through this source again and unsaturate it saturate_source(s,n,Edge,Cost,node_potential,Part_Flow,curr_demand,sink,no_sat_source, Tight_Loose, Tight_Loose_No,No_Max_Flow)
def saturate_source(s,n,Edge,Cost, node_potential,Part_Flow, curr_demand, sink,no_sat_source, Tight_Loose, Tight_Loose_No, No_Max_Flow ): no_sat_source[s] += 1 #print "Desaturate source being called " #Construct residual graph for it #New residual graph required every time Gr_Edge = [[0 for x in range(n)] for x in range(n)] Gr_Cost = [[0 for x in range(n)] for x in range(n)] Gr_Capacity = [[0 for x in range(n)] for x in range(n)] for u in range(n): for v in range(n): if Edge[u][v]>0: #if edge (u,v) in original graph, then temp1 = Tight_Loose[u][v] #if tight edge: if (node_potential[u] - node_potential[v]) == Cost[u][v]: print "Tight edge", u , ":", v ,"found" Gr_Capacity[u][v]= 1000 #infinity capacity Gr_Edge[u][v]=1 Gr_Cost[u][v]=Cost[u][v] Tight_Loose[u][v] = 1 else: Tight_Loose[u][v] = 0 #increments counter by 1 when edge goes from tight to loose and vice versa if temp1 != Tight_Loose[u][v]: Tight_Loose_No[u][v] += 1 #reverse arc: if Part_Flow[u][v] >0 : Gr_Edge[v][u]=1 Gr_Capacity[v][u]=Part_Flow[u][v] Gr_Cost[v][u]= -Cost[u][v] #residual graph completed #Find if any unsaturated sink t reachable from s parent = [-1 for x in range(n)] t = mod_bfs(Gr_Edge,s,parent,sink) print "Current sinks are: ", sink print "t found from mod_bfs is: ", t print "" if t != -1 : #say path found with flow f, then, along the path #Part_Flow[u][v] += f #Need to get f by min. if curr_demand[s] > -curr_demand[t] : f = -curr_demand[t] #sink.remove(t) #saturated sink removed else: f = curr_demand[s] '''#deploy capacity constraint v =t min_cap = 0 cap_list =[] while v != s: u = parent[v] #Part_Flow[u][t] += f cap_list.append(Gr_Capacity[u][v]) v = u min_cap = min(cap_list) path_capacity = min(f, min_cap) curr_demand[s] -= path_capacity curr_demand[t] += path_capacity #because sink has negative demand while source has positive demand, hence the sign difference if curr_demand[t] == 0: sink.remove(t) #Update flow along the path while t!=s : u = parent[t] Part_Flow[u][t] += path_capacity t = u''' #Finding max. flow between source and sink first found (using modified edmondns karp to find max. augmenting path) MF_Capacity = [[0 for x in range(n)] for x in range(n)] MF_Flow = [[0 for x in range(n)] for x in range(n)] for u in range(n): for v in range(n): MF_Capacity[u][v] = -min(f, Gr_Capacity[u][v]) #-ve sign because -ve capacities for fib heap, # min of these 2 because flow cannot be more than supply/demand at source/sink #maxFlow = edmonds_karp(n,s,t,MF_Capacity, Part_Flow) maxFlow = max_min_bottleneck(n,s,t,MF_Capacity, MF_Flow, f ) for u in range(n): for v in range(n): Part_Flow[u][v] += MF_Flow[u][v] No_Max_Flow[s][t] += 1 print "" print "maxFlow found is: ", maxFlow print "Current flow matrix is: ", Part_Flow curr_demand[s] -= maxFlow curr_demand[t] += maxFlow #because sink has negative demand while source has positive demand, hence the sign difference if curr_demand[t] == 0: sink.remove(t) #print "" print "Sink removed: ",t #print "" print "Current demand array is: ", curr_demand #check if source is saturated: if curr_demand[s] > 0: saturate_source(s,n,Edge,Cost,node_potential,Part_Flow,curr_demand,sink,no_sat_source, Tight_Loose, Tight_Loose_No,No_Max_Flow) else: #i.e. when no reachable unsat. sink from this unsat. source s, we raise node potentials, definitely define new routine for this print "We need to raise node potential for source ", s raise_node_potentials(s, n, Edge, Cost, node_potential, Gr_Edge) # need to go through this source again and unsaturate it saturate_source(s,n,Edge,Cost,node_potential,Part_Flow,curr_demand,sink,no_sat_source, Tight_Loose, Tight_Loose_No,No_Max_Flow)
def saturate_source(s,n,Edge,Cost, node_potential,Part_Flow, curr_demand, sink ): #print "Desaturate source being called " #Construct residual graph for it #New residual graph required every time Gr_Edge = [[0 for x in range(n)] for x in range(n)] Gr_Cost = [[0 for x in range(n)] for x in range(n)] Gr_Capacity = [[0 for x in range(n)] for x in range(n)] for u in range(n): for v in range(n): if Edge[u][v]>0: #if edge (u,v) in original graph, then #if tight edge: if (node_potential[u] - node_potential[v]) == Cost[u][v]: print "Tight edge", u , ":", v ,"found" Gr_Capacity[u][v]= 1000 #infinity capacity Gr_Edge[u][v]=1 Gr_Cost[u][v]=Cost[u][v] #reverse arc: if Part_Flow[u][v] >0 : Gr_Edge[v][u]=1 Gr_Capacity[v][u]=Part_Flow[u][v] Gr_Cost[v][u]= -Cost[u][v] #residual graph completed #Find if any unsaturated sink t reachable from s parent = [-1 for x in range(n)] t = mod_bfs(Gr_Edge,s,parent,sink) if t != -1 : #say path found with flow f, then, along the path #Part_Flow[u][v] += f #Need to get f by min. if curr_demand[s] > -curr_demand[t] : f = -curr_demand[t] #sink.remove(t) #saturated sink removed else: f = curr_demand[s] #deploy capacity constraint v =t min_cap = 0 cap_list =[] while v != s: u = parent[v] #Part_Flow[u][t] += f cap_list.append(Gr_Capacity[u][v]) v = u min_cap = min(cap_list) path_capacity = min(f, min_cap) curr_demand[s] -= path_capacity curr_demand[t] += path_capacity #because sink has negative demand while source has positive demand, hence the sign difference if curr_demand[t] == 0: sink.remove(t) #Update flow along the path while t!=s : u = parent[t] Part_Flow[u][t] += path_capacity t = u #check if source is saturated: if curr_demand[s] > 0: saturate_source(s,n,Edge,Cost,node_potential,Part_Flow,curr_demand,sink) else: #i.e. when no reachable unsat. sink from this unsat. source s, we raise node potentials, definitely define new routine for this print "We need to raise node potential for source ", s raise_node_potentials(s, n, Edge, Cost, node_potential, Gr_Edge) # need to go through this source again and unsaturate it saturate_source(s,n,Edge,Cost,node_potential,Part_Flow,curr_demand,sink)