I would appreciate advice/algorithms for the following problem:
Consider a graph with V vertices connected by E edges (V, E <= 10^5). When a vertex is removed, all the edges connected to that vertex are removed. The vertices are labeled 1, 2, ..., V.
Input is given on E lines, and on each line there are two space-separated vertex numbers representing an edge between those two vertices. The next V lines are a permutation of 1, 2, ..., V, representing the order in which the vertices are removed. Output V lines stating if the graph is connected (i.e. there is a sequence of paths between every pair of vertices) at each step. V and E are known and are given as space-separated integers on the first line of input.
For example, consider the following example input (edges are undirected):
5 5
1 2
3 1
2 3
2 4
5 4
3
4
1
2
5
The first line indicates that there are 5 vertices and 5 edges. The next 5 lines describe the edges (which are undirected, i.e. an edge from 1 to 2 can also be taken from 2 to 1). The 5 lines after that give the order in which the vertices are removed.
For this example, we would get the output as follows:
When vertex 3 is removed, the graph is connected, since we can go from any of 1, 2, 4, 5 to any other of 1, 2, 4, 5. When vertex 4 is removed, the graph is disconnected because there are no connections out of vertex 5. When vertex 1 is removed the same problem exists. When vertex 2 is removed only 5 is left, so the graph is connected. When all vertices are removed the graph is connected.
I tried a naive recursive approach as follows to check if it is possible to go from a start vertex to an end vertex:
void dfs(int start, int curr, int end):
if (curr == 0): // start condition, i.e. curr not yet initialized
curr = start
if (curr == end):
return true
else:
for (int v : edges[curr]):
dfs(start, v, end)
return false
Checking at each step if it is possible to travel from all vertices A to all other vertices B using the above algorithm is far too slow (O(V^2 * E^V), algorithm should be ideally O(V log V), or maybe O(V^2) to run in about one second).
For each step store number of partition graph has. For initial graph it is done by doing full traversal (DFS or BFS) from initial vertex, than repeat traversal from vertex that is not yet covered. If number of partitions is <= 1, than graph is connected.
If removed vertex has degree 0, than number of partition is decreased by one.
If removed vertex has degree 1, than number of partitions stays the same.
If removed vertex has degree larger than 1, than number of partitions can be increased by max degree-1. That is checked by similar traversing from neighbours of removed vertex. Start from initial neighbour and find all neighours that are connected to it. Repeat traversing from not visited neigbour.
Related
Say I have a graph with several nodes. I need to design an algorithm which randomly creates directed edges between nodes while satisfying the following conditions:
each node has exactly one edge pointing to it
each node has exactly one edge pointing away from it
no node points to itself
For example, say my graph had three nodes, the following scenarios would be acceptable:
Node A points to B, B points to C, C points to A
Node A points to C, C points to B, B points to A
Does anyone know what the most efficient way of doing this would be? I'm using nodejs btw. For argument's sake, we can say that I am starting with an array containing the names of the nodes.
Thanks
lets define you have array of vertex: V = {v}; |V| = N, now we can shuffle array of vertex by using any random shuffle algorithm.
V = [v_1, v_2, v_3,..,v_n]
Now we can define N-1 edges E, where e[i] = (v[i] to v[i + 1]), and the last vertex will be (v[N-1] to v[0])
I've made an adjacency list, which is a vector that contains many node structures that each contain 2 numbers. They're formatted such that Vertex 1 that is connected to verticies 2 and 3 create structs 1,2 and 2,1 as well as 1,3 and 3,1. How would I go about checking the connectivity of this adjacency list using DSF?
From your question it is not clear in which language you want to do this, so I will try to give some pseudocode.
1 adj <- [(1,2), (2,1), (1,3), (3,1)] // Adjacency list
2 S <- {} // Stack that keeps track of vertices that are discovered
3 for each vertex v:
4 visited[v] = false
5 S.push(v)
6 while S not empty:
7 u <- S.pop()
8 if visited[u] == false:
9 visited[u] = true // Found a new vertex, let's explore
10 for each edge in adj:
11 if edge[0] = u: // If this is the first vertex of an edge
12 S.push(edge[1]) // We add the neighbor to the stack of 'to-explore' vertices
After this algorithm you could loop over the adjacency list and check if the first part of the struct is in the discovered list (If one of the 2 vertices connected by an edge is in the discovered list, so must the other)
You could make this more efficient by changing the adjacency list so that all 'duplicate' structs get removed, so changing [(1,2), (2,1), (1,3), (3,1)] to [(1,2), (1,3)]. Then change line 11 to check for both edge[0] and edge[1], and pushing the other one. This way the for-loops will only be half as long.
I have a file shows different points' coordinates(first 10 rows):
1 10.381090522139 55.39134945301
2 10.37928179195319 55.38858713256631
3 10.387152479898077 55.3923338690609
4 10.380048819655258 55.393938880906745
5 10.380679138517507 55.39459444742785
6 10.382474625286 55.392132993022
7 10.383736185130601 55.39454404088371
8 10.387334283235987 55.39433237195271
9 10.388468103023115 55.39536574771765
10 10.390814951258335 55.396308397998475
Now I want to calculate the MST(minimum spanning tree) of them so firstly I change my coordinates to weight graph(distance->weight):
n = 10
data = []
for i in range(0, n):
for j in range(i + 1, n):
temp = []
temp.append(i)
temp.append(j)
x = np.array(rawdata[i, 1:3])
y = np.array(rawdata[j, 1:3])
temp.append(np.linalg.norm(x - y))
data.append(temp)
Then, using networkx to load weight data:
G = nx.read_weighted_edgelist("data.txt")
T = nx.minimum_spanning_tree(G)
nx.draw(T)
plt.show()
but I cannot see the orignal shape from result:
how to solve this problem?
I'm just answering the question about the position of the nodes. I can't tell from what you've done whether the minimum spanning tree is what you're after or not.
When you plot a network, it will assign positions based on an algorithm that is in part stochastic. If you want the nodes to go at particular positions, you will have to include that information in the call in an optional argument. So define a dictionary (it's usually called pos) such that pos[node] is a tuple (x,y) where x is the x-coordinate of node and y is the y-coordinate of node.
Then the call is nx.draw(T, pos=pos).
I want to check if my weighted graph has a negative cycle. For using bellman-ford algorithm, we need to select a source node, initialize all other distances to infinity and start relaxing n-1 times if number of vertices is n. My problem is that the unreachable nodes will have infinite distance all throughout and won't get changed in nth iteration also. So for an unreachable negative cycle we get wrong output.
def negative_cycle(adj, cost):
dist = [float('inf')] * n
prev = [None] * n
dist[0] = 0
for _ in range(n-1):
for u, edges in enumerate(adj):
for i, v in enumerate(edges):
if dist[v]>dist[u]+cost[u][i]:
dist[v]=dist[u]+cost[u][i]
prev[v]=u
for u, edges in enumerate(adj):
for i, v in enumerate(edges):
if dist[v]>dist[u]+cost[u][i]:
return 1
return 0
You should run it for each connected component. For this, implement your function in the way that it gets a vertex v (In your function, it's always vertex 0), then implement a loop and for each vertex which has distance set to infinity, call your function on that vertex.
If you don't care about the shortest path and simply want to detect a negative cycle, you can set the initial distance of all vertices to 0. This has the same effect as creating an imaginary source s and connecting s to all other vertices with weight 0 edges.
Your code would then look like the one below (Probably, I don't know Python, so my syntax could be incorrect).
def negative_cycle(adj, cost):
dist = [0] * n
prev = [None] * n
for _ in range(n-1):
for u, edges in enumerate(adj):
for i, v in enumerate(edges):
if dist[v]>dist[u]+cost[u][i]:
dist[v]=dist[u]+cost[u][i]
prev[v]=u
for u, edges in enumerate(adj):
for i, v in enumerate(edges):
if dist[v]>dist[u]+cost[u][i]:
return 1
return 0
I am creating a Genetic Algorithm to solve the Traveling Salesman Problem.
Currently, two 2D lists represent the two parents that need to be crossed:
path_1 = np.shuffle(np.arange(12).reshape(6, 2))
path_2 = np.arange(12).reshape(6,2)
Suppose each element in the list represents an (x, y) coordinate on a cartesian plane, and the 2D list represents the path that the "traveling salesman" must take (from index 0 to index -1).
Since the TSP requires that all points are included in a path, the resulting child of this crossover must have no duplicate points.
I have little idea as to how I can make such crossover and have the resulting child representative of both parents.
You need to use an ordered crossover operator, like OX1.
OX1 is a fairly simple permutation crossover.
Basically, a swath of consecutive alleles from parent 1 drops down,
and remaining values are placed in the child in the order which they
appear in parent 2.
I used to run TSP with these operators:
Crossover: Ordered Crossver (OX1).
Mutation: Reverse Sequence Mutation (RSM)
Selection: Roulette Wheel Selection
You can do something like this,
Choose half (or any random number between 0 to (length - 1)) coordinates from one parent using any approach, lets say where i % 2 == 0.
These can be positioned into the child using multiple approaches: either randomly, or all in the starting (or ending), or alternate position.
Now the remaining coordinated need to come from the 2nd parent for which you can traverse in the 2nd parent and if the coordinate is not chosen add it in the empty spaces.
For example,
I am choosing even positioned coordinated from parent 1 and putting it in even position indices in the child and then traversing in parent 2 to put the remaining coordinated in the odd position indices in the child.
def crossover(p1, p2, number_of_cities):
chk = {}
for i in range(number_of_cities):
chk[i] = 0
child = [-1] * number_of_cities
for x in range(len(p1)):
if x % 2 == 0:
child[x] = p1[x]
chk[p1[x]] = 1
y = 1
for x in range(len(p2)):
if chk[p2[x]] == 0:
child[y] = p2[x]
y += 2
return child
This approach preserves the order of cities visited from both parents.
Also since it is not symmetric p1 and p2 can be switched to give 2 children and the better (or both) can be chosen.