How to convert a directed graph to an undirected graph? - graph

How do you convert a directed graph to an undirected graph using an adjacency matrix?
public directedToUndirected(boolean[][] adjMatrix) {
}

Do a boolean OR operation with the original matrix and the transpose of the original.

You could loop through the whole array and flip the indices, assuming you're using 0 and 1's
for (int i=0; i<adjMatrix.length; i++) {
for (int j=0; j<adjMatrix[i].length; j++) {
if (adjMatrix[i][j] == 1) {
adjMatrix[j][i] = 1;
}
}
}

You must find any method that need not to change the information. In all of the above suggested methods edge between node i to j is given to j to i and it is wrong because there is not such edge.
You can change the graph into larger one and make some virtual connections. For example if i has connection to j and j has connection to i you can change i to i' and define new edge between j and i. You also should save this fact that i' is the same as i.

Related

Random Values from a variable set of entries in a vector

i have a problem which is the following:
i have for example 4 objects. One object is randomly selected to do a certain action. E.g. if object 1 does an action, the other 3 objects do nothing.
So, i have a vector of these objects.
vector{object1,object2, object3, object4}
In the beginning, i can easily randomly select one object with vector[random].
And here comes the problem: An object can also "die" meaning the object should not be part of the random-step anymore.
For example, if object2 dies, if want to random between 1,3,4 and let the 2 out.
Is this possible somehow? (using C++)
Thanks!
I was just under the shower and thought about it.. i think i found a workaround for this. Pseudo-Code:
vector<figure> all_figure_types;
vector<figure> all_figure_types_alive;
for (int i = 0; i < 5; i++) {
all_figure_types.push_back(generate_random_number(1,10));
}
all_figure_types_alive.clear();
for (int i = 0; i < all_figure_types.size(); i++) {
if (all_figure_types[i].is_alive) {
all_figure_types_alive.push_back(all_figure_types[i]);
}
}
int start = 0;
int end = all_figure_types_alive.size();
int random_num = generate_random_number(start, end);
int object_type = all_figure_types_alive[random_num].type;
If there is a nicer version without resetting this helping-construct all_figure_types_alive, let me know would be nice to hear!

Appending to / removing elements from vector while iterating over said vector [duplicate]

What is the idiomatic way to iterate (read) over the first half of the vector and change the structure of the second half of the vector depending on the first? This is very abstract but some algorithms could be boiled down to this problem. I want to write this simplified C++ example in Rust:
for (var i = 0; i < vec.length; i++) {
for (var j = i + 1 ; j < vec.length; j++) {
if (f(vec[i], vec[j])) {
vec.splice(j, 1);
j--;
}
}
}
An idiomatic solution of this generic problem will be the same for Rust and C, as there's no constraints which would allow simplification.
We need to use indexes because vector reallocation will invalidate the references contained by the iterators. We need to compare the index against the current length of the vector on each cycle because the length could be changed. Thus an idiomatic solution will look like this:
let mut i = 0;
while i < v.len() {
let mut j = i + 1;
while j < v.len() {
if f(v[i], v[j]) {
v.splice(j, 1);
} else {
j += 1;
}
}
i += 1;
}
Playground link
While this code covers the general case, it is rarely useful. It doesn't capture specifics, which are usually inherent to the problem at hand. In turn, the compiler is unable to catch any errors at compile time. I don't advise writing something like this without considering another approaches first.

Passing values between variables of host and kernel Code in a loop in OpenCL

I am in trouble passing values between host code and kernel code due to some vector data types. The following code/explanation is just for referencing my problem, my code is much bigger and complicated. With this small example, hopefully, I will be able to explain where I am having a problem. I f anything more needed please let me know.
std::vector<vector<double>> output;
for (int i = 0;i<2; i++)
{
auto& out = output[i];
sum =0;
for (int l =0;l<3;l++)
{
for (int j=0;j<4; j++)
{
if (some condition is true)
{ out[j+l] = 0.;}
sum+= .....some addition...
}
out[j+l] = sum
}
}
Now I want to parallelize this code, from the second loop. This is what I have done in host code:
cl::buffer out = (context,CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, output.size(), &output, NULL)
Then, I have set the arguments
cl::SetKernelArg(0, out);
Then the loop,
for (int i = 0,i<2, i++)
{
auto& out = output[i];
// sending some more arguments(which are changing accrding to loop) for sum operations
queue.enqueueNDRangeKernel(.......)
queue.enqueuereadbuffer(.....,&out,...)
}
In Kernel Code:
__kernel void sumout(__global double* out, ....)
{
int l = get_global_id(0);
int j = get_global_id(1);
if (some condition is true)
{ out[j+l] = 0.; // Here it goes out of the loop then
return}
sum+= .....some addition...
}
out[j+l] = sum
}
So now, in if condition out[j+l] is getting 0 in the loop. So out value is regularly changing. In normal code, it is a reference pointer to a vector. I am not able to read the values in output from out during my kernel and host code. I want to read the values in output[i] for every out[j+l]. But I am confused due this buffer and vector.
just for more clarification,output is a vector of vector and out is reference vector to output vector. I need to update values in output for every change in out. Since these are vectors, I passed out as cl buffer. I hope it is clear.
Please let me know, if the code is required, I will try to provide as much as I can.
You are sending pointers of vectors to opencl(ofcourse they are contiguous on pointer level) but whole data is not contiguous in memory since each inner vector points to different memory area. Opencl cannot map host pointers to device memory and there is no such command in this api.
You could use vector of arrays(latest version) or pure arrays.

How many components in a directed graph?

I have the following graph:
The optimal solution is to start dfs from vertex (3) then i will get one component, but when we start the dfs from vertex (1) then (3) i will get two components.
The question is:
I want to know how many components in this graph? or on other way, what is the minimum number of dfs needed to cover all the graph?
what is the needed algorithm for doing this?
You are confusing two definitions.
For undirected graphs there is the notion of connected components, which you find by performing a DFS on the undirected graph.
For directed graphs there is the notion of strongly connected components, for which multiple algorithms are available, all slightly more complicated than a simple DFS.
What you should do depends on which of the two notions you need. Your graph has one connected component when viewed as an undirected graph, and two strongly connected components when viewed as a directed graph.
I know this is an old thread but it would be helpful to add how I solved the problem:
1 - Find the strongly connected components (SCC) inside the graph, and for each SCC, we can replace it with a single node that represents that SCC.
2 - Now, we can know the min number of nodes that we can run DFS from and cover all the other nodes by looking at the degrees of the nodes in the new graph, so we can start DFS from the nodes with zero in degree.
I believe you are trying to find weakly connected components .
Testing whether a directed graph is weakly connected can be done easily in linear time. Simply turn all edges into undirected edges and use the DFS-based connected components algorithm.
To solve this exercise, the idea is to work with an adjacency list of IN-edges.
Take as an example a graph with 3 nodes and 2 edges (0,1) and (0,2), whereas (a,b) indicates that if you switch light a, then light b will also be switched.
OUT-edges adjacency list:
0 -> 1, 2
1 -> _
2 -> _
IN-edges adjacency list:
0 -> _
1 -> 0
2 -> 0
Assuming we don't have cycles, if we follow the IN-edges down until you reach a node which does not have a child, you get what I call an "influencer", that is, you can not switch it with any other node.
Now to take account for cycles I check if any neighbor has or is an influencer. If this is not the case and all neighbors have been visited already, I encounter a cycle and make the current node an influencer.
This is my code (tested with simple examples on my desk):
private int numberOfLights(){
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
List<List<Integer>> inAdjList = new ArrayList<List<Integer>>();
for(int i = 0; i < n; i++){
inAdjList.add(new ArrayList<>());
}
for(int i = 0; i < n; i++){
int from = scanner.nextInt();
int to = scanner.nextInt();
inAdjList.get(to).add(from);
}
int[] visited = new int[n];
int[] isOrHasInfluencer = new int[n];
List<Integer> influencers = new ArrayList<>();
for(int i = 0; i < n; i++){
if(!visited[i]){
DFS(i, visited, isOrHasInfluencer, influencers, inAdjList);
}
}
return influencers.size();
}
private void DFS(Integer cur, int[] visited, int[] isOrHasInfluencer, List<Integer> influencers, List<List<Integer>> inAdjList){
visited[cur] = true;
boolean hasUnvisitedChildren = false;
for(Integer neighbor : inAdjList.get(cur)){
if(!visited[neighbor]){
hasUnvisitedChildren = true;
DFS(neighbor, visited, isOrHasInfluencer, influencers, inAdjList);
}
if(isOrHasInfluencer[neighbor]){
isOrHasInfluencer[cur] = true;
}
}
if(!hasUnvisitedChildren && !isOrHasInfluencer[cur]){
isOrHasInfluencer[cur] = true;
influencers.add(cur);
}
}
Hope that helps! :)
You can run findConnectedComponent algorithm from each of nodes and return the minimum number to solve your specific problem.
I think this solution is not optimal but it works very well with small to medium sized input graph.
Old question, but there is another way.
Convert the directed graph to an undirected one by doing a DFS on all the nodes. O(V+E)
Do what you do for undirected graph. O(V+E)

Find the path and max-weigted edge in a Minimax path-finding solution?

I am currently having a programing assignment: given a large weighted unconnected graph (1 < V < 2000,
0 < E < 100 000). Find the maximum-weighted edge along the minimum-weighted path from "source" to point "destination".
What I've got so far is storing the graph in an AdjacencyList (Vector of Vector of IntegerPair where first integer is the neighbor and second is the weight of the edge).
I've also obtained the Minimum Spanning Tree by using Prim's algorithm:
private static void process(int vtx) {
taken.set(vtx, true);
for (int j = 0; j < AdjList.get(vtx).size(); j++) {
IntegerPair v = AdjList.get(vtx).get(j);
if (!taken.get(v.first())) {
pq.offer(new IntegerPair(v.second(), v.first())); //sort by weight then by adjacent vertex
}
}
}
void PreProcess() {
Visited = new Vector<Boolean>();
taken = new Vector<Boolean>();
pq = new PriorityQueue<IntegerPair>();
taken.addAll(Collections.nCopies(V, false));
process(0);
int numTaken = 1;
int mst_cost = 0;
while (!pq.isEmpty() && numTaken != V) { //do this until all V vertices are taken (or E = V - 1 edges are taken)
IntegerPair front = pq.poll();
if (!taken.get(front.second())) { // we have not connected this vertex yet
mst_cost += front.first(); // add the weight of this edge
process(front.second());
numTaken++;
}
}
}
What I am stuck at now is how to find the path from source to destination and return the maxmum weight edge in the below query:
int Query(int source, int destination) {
int ans = 0;
return ans;
}
I was told to use Depth-First Search to traverse the resulting MST but I think the DFS will traverse all vertices that are not on the correct path (am I right?). And how to find the maximum edge?
(This problem is not related to any SSSP algorithm because I haven't been taught Dijstra's, etc.)
One possible way to do this would be to use Kruskal's MST algorithm. It is a greedy algorithm that will start with an empty graph, the repeatedly add the lightest edge that does not produce a cycle. This satisfies the properties of a tree, while assuring the minimum-weighted path.
To find the maximum weighted edge, you can also use the properties of the algorithm. Since you know the that EdgeWeight(n) =< EdgeWeight(n+1), the last edge you add to the graph will be the maximum edge.

Resources