C++ - DFS code error - c++

I tried to implement this algorithm but there's some logical error. The algorithm is given below.
DFS(G)
1. for each vertex u ∈ G.V
2. u.color = WHITE
3. u.pi = NIL
4. time = 0
5. for each vertex u ∈ G.V
6. if u.color == WHITE
7. DFS-VISIT(G,u)
DFS-VISIT(G,u)
1. time = time + 1
2. u.d = time
3. u.color = GRAY
4. for each v ∈ G.Adj[u]
5. if v.color == WHITE
6. v.pi = u
7. DFS-VISIT(G,v)
8. u.color = BLACK
9. time = time + 1
10. u.f = time
Code:
#include <bits/stdc++.h>
using namespace std;
#define WHITE 0
#define GRAY 1
#define BLACK 2
#define SIZE 100
int Time;
int adj[SIZE][SIZE];
int color[SIZE];
int parent[SIZE];
int d[SIZE];
void dfs_Visit(int G, int u)
{
Time++;
d[u] = Time;
color[u] = GRAY;
for(int i = 0; i < G; i++)
{
if(color[i] == WHITE)
{
parent[i] = u;
dfs_Visit(G, i);
}
}
color[u] = BLACK;
Time++;
cout << u << " ";
}
void dfs(int G)
{
for(int i = 0; i < G; i++)
{
color[i] = WHITE;
parent[i]=NULL;
}
Time=0;
cout << "DFS is ";
for(int i = 0; i < G; i++)
{
if(color[i] == WHITE)
{
dfs_Visit(G, i);
}
}
}
int main()
{
int vertex;
int edge;
cout << "VERTEX & Edge : ";
cin >> vertex >> edge;
cout << "Vertex is : " << vertex <<endl;
cout << "Edge is : " << edge <<endl;
int node1, node2;
for(int i = 0; i < edge; i++)
{
cout << "EDGE " << i << ": ";
cin >> node1 >> node2;
adj[node1][node2] = 1;
adj[node2][node1] = 1;
}
dfs(vertex);
}
Output picture
Inputs:
VERTEX & Edge : 4 5
Vertex is : 4
Edge is : 5
EDGE 0: 0 1
EDGE 1: 1 2
EDGE 2: 2 0
EDGE 3: 0 3
EDGE 4: 2 4
Output:
DFS is 3 2 1 0
And the accepted result is 2 1 3 0

The problem is that you haven't coded DFS-VISIT step 4 correctly
Step 4 says for each v ∈ G.Adj[u] but your code says for(int i=0; i<G; i++). Those aren't the same thing at all. You should only visit the adjacent vertexes.
In fact if you look at your code you never use adj at all. That can't be right.

Related

C++ Knight moves path

I am working on the knight moves problem and managed to print the number of moves but still need to print the path e.g. "3 moves: path is: [3,3] [4,5] [2,4] [4,3]". I tried to print the Queue but got instead all visited paths. I tried also to work backward to the previous points (function minStepToReachTarget) but i think my novice skill did not help.
i already got the number of moves but is there a function or piece of code that help me print the path?
Best,
James.
#include <bits/stdc++.h>
#include <iostream>
#include <queue>
using namespace std;
// structure for storing a cell's data
class cell {
public:
int x, y;
int dis;
cell() {}
cell(int x, int y, int dis) : x(x), y(y), dis(dis) { }
};
// Utility method returns true if (x, y) lies
// inside Board
bool isInside(int x, int y, int N)
{
if (x >= 1 && x <= N && y >= 1 && y <= N)
return true;
return false;
}
// Method returns minimum step
// to reach target position
int minStepToReachTarget( int knightPos[], int targetPos[], int N)
{
// x and y direction, where a knight can move
int dx[] = { -2, -1, 1, 2, -2, -1, 1, 2 };
int dy[] = { -1, -2, -2, -1, 1, 2, 2, 1 };
// queue for storing states of knight in board
queue<cell> q;
// push starting position of knight with 0 distance
q.push(cell(knightPos[0], knightPos[1], 0));
cell t;
int x, y;
bool visit[N + 1][N + 1];
// make all cell unvisited
for (int i = 1; i <= N; i++)
for (int j = 1; j <= N; j++)
visit[i][j] = false;
// visit starting state
visit[knightPos[0]][knightPos[1]] = true;
// loop until we have one element in queue
while (!q.empty()) {
t = q.front();
q.pop();
// cout << "[" << t.x << " "<< t.y<<"]\n";
// if current cell is equal to target cell,
// return its distance
if (t.x == targetPos[0] && t.y == targetPos[1]) {
// cout << "[" << targetPos[0] << " " << targetPos[1] << "]\n";
return t.dis;
}
// loop for all reachable states
for (int i = 0; i < 8; i++) {
x = t.x + dx[i];
y = t.y + dy[i];
// If reachable state is not yet visited and
// inside board, push that state into queue
if (isInside(x, y, N) && !visit[x][y]) {
visit[x][y] = true;
//** cout << "[" << x << " " << y << "]\n";
q.push(cell(x, y, t.dis + 1));
}
}
}
return t.dis;
}
int main(){
int N = 8, knightPos[2], targetPos[2];
cout <<"=> Enter the current Knight’s location: ";
for (int i = 0; i < 2; i++) std::cin>> knightPos[i];
cout <<"=> Enter the destination location: ";
for (int i = 0; i < 2; i++) std::cin>> targetPos[i];
cout <<"=> You made it in " << minStepToReachTarget(knightPos, targetPos, N) <<
" moves from [" << knightPos[0] <<"," << knightPos[1] << "] "
"to [" << targetPos[0] <<"," << targetPos[1] <<"]! Here is your path: ";
return 0;
/*
=> Enter the current Knight’s location: 3 3
=> Enter the destination location: 4 3
=> You made it in 3 moves from [3,3] to [4,3]! Here is your path:
[3,3] [4,5] [2,4] [4,3]
*/
}
You're doing a breadth-first search on your board. Once your reach your destination, the function minStepToReachTarget has no idea how it got there. What you can do is, for each cell in the queue, keep track of its 'parent', i.e. from which cell it was visited first. Once you've found the target, instead of returning t.dis, you could trace the parents of t and return an array representing the path. t.dis would then be equal to the length of the array minus one, since you include both the starting point and target point in the path.

Getting WA, created own test cases too but not getting approved answers

Link of Question : https://www.codechef.com/JULY20B/problems/PTMSSNG
Question Statement
Chef has N axis-parallel rectangles in a 2D Cartesian coordinate system. These rectangles may intersect, but it is guaranteed that all their 4N vertices are pairwise distinct.
Unfortunately, Chef lost one vertex, and up until now, none of his fixes have worked (although putting an image of a point on a milk carton might not have been the greatest idea after all…). Therefore, he gave you the task of finding it! You are given the remaining 4N−1 points and you should find the missing one.
Can anyone suggest where I'm going wrong or update my code or share a few test cases.
#include <iostream>
#include <vector>
#include <algorithm>
#include <utility>
#define ll long long
using namespace std;
int main()
{
int t;
cin >> t;
for (int i = 0; i < t; i++)
{
vector<pair<ll, ll>> v;
ll n, m, a;
bool checkx = false;
cin >> n;
m = 4 * n - 1;
ll x[m], y[m];
ll c, d;
a = (m - 1) / 2;
for (ll i = 0; i < m; i++)
{
cin >> x[i] >> y[i];
v.push_back(make_pair(x[i], y[i]));
}
sort(v.begin(), v.end());
for (ll i = a; i >= 1; --i)
{
if (v[2 * i].first != v[2 * i - 1].first)
{
c = v[2 * i].first;
checkx = true;
if ((2 * i) % 4 == 0 && i >= 2)
{
if (v[2 * i].second == v[2 * i + 1].second)
{
d = v[2 * i + 2].second;
}
else
{
d = v[2 * i + 1].second;
}
}
else
{
if (v[2 * i].second != v[2 * i - 1].second)
{
d = v[2 * i - 1].second;
}
else
{
d = v[2 * i - 2].second;
}
}
break;
}
}
if (checkx)
{
cout << c << " " << d;
}
else
{
if (v[0].second == v[1].second)
{
d = v[2].second;
}
else
{
d = v[1].second;
}
cout << v[0].first << " " << d;
}
cout << endl;
}
return 0;
}
You don't need to do such complex things. Just input your x and y vectors and xor every element of each vector. The final value will be the required answer.
LOGIC :
(a,b)------------------(c,b)
| |
| |
| |
| |
(a,d)------------------(c,d)
See by this figure, each variable (a, b, c, d) occurs even number of times. This "even thing" will also be true for the N rectangles. Hence, you have to find the values of x and y which are occurring odd number of times.
To find the odd one out in such cases, the best trick is to xor every element of the vector. This works because of these properties of xor : k xor k = 0 and k xor 0 = k.
CODE:
#include <functional>
#include <iostream>
#include <numeric>
#include <vector>
signed main() {
std::size_t t, n;
std::cin >> t;
while (t--) {
std::cin >> n;
n = 4 * n - 1;
std::vector<int> x(n), y(n);
for (std::size_t i = 0; i < n; ++i)
std::cin >> x.at(i) >> y.at(i);
std::cout << std::accumulate(x.begin(), x.end(), 0L, std::bit_xor<int>()) << ' '
<< std::accumulate(y.begin(), y.end(), 0L, std::bit_xor<int>()) << '\n';
}
return 0;
}
here is a test case that your code doesn't work:
1
2
1 1
1 4
4 6
6 1
9 6
9 3
4 3
the output of your code is (6,3),but it should be (6,4).
I guess you can check more cases where the rectangles intersects.
from functools import reduce
for _ in range(int(input())):
n=int(input())
li=[]
li1=[]
for i in range(4*n-1):
m,n=map(int,input().split())
li.append(m)
li1.append(n)
r =reduce(lambda x, y: x ^ y,li)
print(r,end=' ')
r =reduce(lambda x, y: x ^ y,li1)
print(r,end=' ')
print()

Probability for each vertex

I have a graph with N vertices and M edges (N is between 1 and 15 and M is between 1 and N^2). The graph is directed and weighted (with a probability for that excact edge). You are given a start vertex and a number of edges. The program is then going to calculate the probability for each vertex being the end vertex.
Examle input:
3 3 //Number of vertices and number of edges
1 2 0.4 //Edge nr.1 from vertex 1 to 2 with a probability of 0.4
1 3 0.5 //Edge nr.2 from vertex 1 to 3 with a probability of 0.5
2 1 0.8 //Edge nr.3...
3 //Number of questions
2 1 //Start vertex, number of edges to visit
1 1
1 2
Output:
0.8 0.2 0.0 //The probability for vertex 1 beign the last vertex is 0.8 for vertex 2 it is 0.2 and for vertex 3 it is 0.0
0.1 0.4 0.5
0.33 0.12 0.55
I have used a DFS in my solution, but when number of edges to visit can be up to 1 billion, this is way too slow... I have been looking at DP but I am not sure about how to implement it for this particular problem (if it is even the right way to solve it). So I was hoping that some of you could suggest an alternative to DFS and/or perhaps a way of using/implementing DP.
(I know it might be a bit messy, I have only been programming in C++ for a month)
#include <iostream>
#include <vector>
#include <stack>
using namespace std;
struct bird {
int colour;
float probability;
};
struct path {
int from;
int to;
};
vector <vector <bird>> birdChanges;
vector <int> layer;
vector <double> savedAnswers;
stack <path> nextBirds;
int fromBird;
//Self loop
void selfLoop(){
float totalOut = 0;
for (int i = 0; i < birdChanges.size(); i++) {
for (int j = 0; j < birdChanges[i].size(); j++) {
totalOut += birdChanges[i][j].probability;
}
if (totalOut < 1) {
bird a;
a.colour = i;
a.probability = 1 - totalOut;
birdChanges[i].push_back(a);
}
totalOut = 0;
}
}
double fillingUp(double momentarilyProbability, long long int numberOfBerries){
int layernumber=0;
while (layer[numberOfBerries - (1+layernumber)] == 0) {
layernumber++;
if (numberOfBerries == layernumber) {
break;
}
}
layernumber = layer.size() - layernumber;
path direction;
int b;
if (layernumber != 0) {
b= birdChanges[nextBirds.top().from][nextBirds.top().to].colour;//Usikker
}
else {
b = fromBird;
}
while (layer[numberOfBerries - 1] == 0) {
//int a = birdChanges[nextBirds.top().from][nextBirds.top().to].colour;
if (layernumber != 0) {
momentarilyProbability *= birdChanges[nextBirds.top().from][nextBirds.top().to].probability;
//b = birdChanges[nextBirds.top().from][nextBirds.top().to].colour;
}
for (int i = 0; i < birdChanges[b].size(); i++) {
direction.from = b;
direction.to = i;
//cout << endl << "Stacking " << b << " " << birdChanges[b][i].colour;
nextBirds.push(direction);
layer[layernumber]++;
}
layernumber++;
b = birdChanges[nextBirds.top().from][nextBirds.top().to].colour;
}
//cout << "Returning" << endl;
return momentarilyProbability *= birdChanges[nextBirds.top().from][nextBirds.top().to].probability;;
}
//DFS
void depthFirstSearch(int fromBird, long long int numberOfBerries) {
//Stack for next birds (stack)
path a;
double momentarilyProbability = 1;//Momentarily probability (float)
momentarilyProbability=fillingUp(1, numberOfBerries);
//cout << "Back " << momentarilyProbability << endl;
//Previous probabilities (stack)
while (layer[0] != 0) {
//cout << "Entering" << endl;
while (layer[numberOfBerries - 1] != 0) {
savedAnswers[birdChanges[nextBirds.top().from][nextBirds.top().to].colour] += momentarilyProbability;
//cout << "Probability for " << birdChanges[nextBirds.top().from][nextBirds.top().to].colour << " is " << momentarilyProbability << endl;
momentarilyProbability = momentarilyProbability / birdChanges[nextBirds.top().from][nextBirds.top().to].probability;
nextBirds.pop();
layer[numberOfBerries - 1]--;
if (layer[numberOfBerries - 1] != 0) {
momentarilyProbability *= birdChanges[nextBirds.top().from][nextBirds.top().to].probability;
}
}
if (layer[0] != 0) {
int k = 1;
while (layer[layer.size() - k]==0&&k+1<=layer.size()) {
//cout << "start" << endl;
momentarilyProbability = momentarilyProbability / birdChanges[nextBirds.top().from][nextBirds.top().to].probability;
//cout << "Popping " << nextBirds.top().from << birdChanges[nextBirds.top().from][nextBirds.top().to].colour << endl;
nextBirds.pop();
//cout << "k " << k << endl;
layer[numberOfBerries - 1 - k]--;
k++;
//cout << "end" << endl;
}
}
if (layer[0] != 0) {
//cout << 1 << endl;
//cout << "Filling up from " << nextBirds.top().from << birdChanges[nextBirds.top().from][nextBirds.top().to].colour << endl;
momentarilyProbability = fillingUp(momentarilyProbability, numberOfBerries);
}
}
//Printing out
for (int i = 1; i < savedAnswers.size(); i++) {
cout << savedAnswers[i] << " ";
}
cout << endl;
}
int main() {
int numberOfColours;
int possibleColourchanges;
cin >> numberOfColours >> possibleColourchanges;
birdChanges.resize(numberOfColours+1);
int from, to;
float probability;
for (int i = 0; i < possibleColourchanges; i++) {
cin >> from >> to >> probability;
bird a;
a.colour = to;
a.probability = probability;
birdChanges[from].push_back(a);
}
selfLoop();
int numberOfQuestions;
cin >> numberOfQuestions;
long long int numberOfBerries;
for (int i = 0; i < numberOfQuestions; i++) {
cin >> fromBird >> numberOfBerries;
savedAnswers.assign(numberOfColours + 1, 0);
layer.resize(numberOfBerries, 0);
//DFS
depthFirstSearch(fromBird, numberOfBerries);
}
system("pause");
}
Fast explanation of how to do this with the concept of a Markov Chain:
Basic algorithm:
Input: starting configuration vector b of probabilities of
being in a vertex after 0 steps,
Matrix A that stores the probability weights,
in the scheme of an adjacency matrix
precision threshold epsilon
Output:
an ending configuration b_inf of probabilities after infinite steps
Pseudocode:
b_old = b
b_new = A*b
while(difference(b_old, b_new) > epsilon){
b_old = b_new
b_new = A*b_old
}
return b_new
In this algorithm, we essentially compute potencies of the probability matrix and look for when those become stable.
b are the probabilities to be at a vertex after no steps where taken
(so, in your case, every entry being zero except for the start vertex, which is one)
A*b are those after one step was taken
A^2 * b are those after two steps were taken, A^n * b after n steps.
When A^n * b is nearly the same as A^n-1 * b, we assume that nothing big will happen to it any more, that it is basically the same as A^infinity * b
One can mock this algorithm with some examples, like an edge that leads in a subgraph with a very small probability that will result one being in the subgraph with probability 1 after infinite steps, but for example from reality, it will work.
For the difference, the euclidean distance should work well, but essentially any norm does, you could also go with maximum or manhattan.
Note that I present a pragmatic point of view, a mathematician would go far more into detail about under which properties of A it will converge how fast for which values of epsilon.
You might want to use a good library for matrices for that, like Eigen.
EDIT:
Reading the comment of Jarod42, I realize that your amount of steps are given. In that case, simply go with A^steps * b for the exact solution. Use a good library for a fast computation of the potency.

Duplicate data when printing the adjacency list of a graph

I was just trying to implement an adjacency list based graph, I'm not able to sort out, why second value appears twice in output print:
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int main() {
int k = 0;
int n = 0;
cin>>k;
while(k>0){
cin>>n;
//Declare Adjacency List
vector<vector<pair<int, int>>> G;
G.resize(n);
//Add an edge u,v of weight w
while(n>0){
int u=0,v=0,w=0;
cin>>u>>v>>w;
G[u].push_back({v,w});
n--;
}
int i=0;
vector<vector<pair<int,int>>>::iterator it;
vector<pair<int,int>>::iterator it1;
for(it=G.begin() ; it < G.end(); it++,i++ ) {
for (it1=G[i].begin();it1<G[i].end();it1++){
for(pair<int,int> p: G[i]){
cout <<" "<<i<<"-> (w = "<<p.second<<") -> "<<p.first;
}
cout<<endl;
}
}
k--;
}
return 0;
}
Input:
1
5
1 2 2
2 3 1
2 4 4
4 5 3
Output:
0-> (w = 0) -> 0
1-> (w = 2) -> 2
2-> (w = 1) -> 3 2-> (w = 4) -> 4
2-> (w = 1) -> 3 2-> (w = 4) -> 4
4-> (w = 3) -> 5
I want to learn implementation.
Any new implementation will also be welcomed, I want to implement an undirected, weighted graph.
Because of your second for-loop
for (it1=G[i].begin();it1<G[i].end();it1++)
you get a duplicate output.
I assume you use C++11. Here's a slightly improved version of your program. First of all, I have added the option to read in the number of vertices and edges.
#include <iostream>
#include <utility>
#include <vector>
int main() {
int k = 0;
std::cin >> k;
while (k > 0) {
// read in number of nodes and edges
auto n = 0;
auto m = 0;
std::cin >> n >> m;
// Adjacency list
std::vector<std::vector<std::pair<int, int>>> G;
G.resize(n);
// Add an edge (u,v) with weight w
while (m > 0) {
int u=0, v=0, w=0;
std::cin >> u >> v >> w;
G[u].emplace_back(v,w);
--m;
}
// Print out adjacency list
for (auto i = 0; i < G.size(); ++i) {
for (const auto pair: G[i]) {
std::cout << " " << i << "-- (w = " << pair.second << ") --> " << pair.first;
}
std::cout << '\n';
}
--k;
}
return 0;
}
With your example-input
1
5
4
1 2 2
2 3 1
2 4 4
4 5 3
which denotes a graph with 5 vertices and 4 edges we get the following output:
1-- (w = 2) --> 2
2-- (w = 1) --> 3 2-- (w = 4) --> 4
4-- (w = 3) --> 5

Perceptron converging but returning odd results

I made a simple perceptron in c++ to study AI and even following a book(pt_br) i could not make my perceptron return an expected result, i tryed to debug and find the error but i didnt succeed.
My algorithm AND gate results (A and B = Y):
0 && 0 = 0
0 && 1 = 1
1 && 0 = 1
1 && 1 = 1
Basically its working as an OR gate or random.
I Tried to jump to Peter Norving and Russel book, but he goes fast over this and dont explain on depth one perceptron training.
I really want to learn every inch of this content, so i dont want to jump to Multilayer perceptron without making the simple one work, can you help?
The following code is the minimal code for operation with some explanations:
Sharp function:
int signal(float &sin){
if(sin < 0)
return 0;
if(sin > 1)
return 1;
return round(sin);
}
Perceptron Struct (W are Weights):
struct perceptron{
float w[3];
};
Perceptron training:
perceptron startTraining(){
//- Random factory generator
long int t = static_cast<long int>(time(NULL));
std::mt19937 gen;
gen.seed(std::random_device()() + t);
std::uniform_real_distribution<float> dist(0.0, 1.0);
//--
//-- Samples (-1 | x | y)
float t0[][3] = {{-1,0,0},
{-1,0,1},
{-1,1,0},
{-1,1,1}};
//-- Expected result
short d [] = {0,0,0,1};
perceptron per;
per.w[0] = dist(gen);
per.w[1] = dist(gen);
per.w[2] = dist(gen);
//-- print random numbers
cout <<"INIT "<< "W0: " << per.w[0] <<" W1: " << per.w[1] << " W2: " << per.w[2] << endl;
const float n = 0.1; // Lerning rate N
int saida =0; // Output Y
long int epo = 0; // Simple Couter
bool erro = true; // Loop control
while(erro){
erro = false;
for (int amost = 0; amost < 4; ++amost) { // Repeat for the number of samples x0=-1, x1,x2
float u=0; // Variable for the somatory
for (int entrad = 0; entrad < 3; ++entrad) { // repeat for every sinaptic weight W0=θ , W1, W2
u = u + (per.w[entrad] * t0[amost][entrad]);// U <- Weights * Inputs
}
// u=u-per.w[0]; // some references sau to take θ and subtract from U, i tried but without success
saida = signal(u); // returns 1 or 0
cout << d[amost] << " <- esperado | encontrado -> "<< saida<< endl;
if(saida != d[amost]){ // if the output is not equal to the expected value
for (int ajust = 0; ajust < 3; ++ajust) {
per.w[ajust] = per.w[ajust] + n * (d[amost] - saida) * t0[amost][ajust]; // W <- W + ɳ * ((d - y) x) where
erro = true; // W: Weights, ɳ: Learning rate
} // d: Desired outputs, y: outputs
} // x: samples
epo++;
}
}
cout << "Epocas(Loops): " << epo << endl;
return per;
}
Main with testing part:
int main()
{
perceptron per = startTraining();
cout << "fim" << endl;
cout << "W0: " << per.w[0] <<" W1: " << per.w[1] << " W2: " << per.w[2] << endl;
while(true){
int x,y;
cin >> x >> y;
float u=0;
u = (per.w[1] * x);
u = u + (per.w[2] * y);
//u=u-per.w[0];
cout << signal(u) << endl;
}
return 0;
}
In your main(), re-enable the line you commented out. Alternatively, you could write it like this to make it more illuminating:
float u = 0.0f;
u += (per.w[0] * float (-1));
u += (per.w[1] * float (x));
u += (per.w[2] * float (y));
The thing is that you trained the perceptron with three inputs, the first being hard-wired to a "-1" (making the first weight w[0] act like a constant "bias"). Accordingly, in your training function, your u is the sum of all THREE of those weight-input product.
However, in the main() you posted, you omit w[0] completely, thus producing a wrong result.