I have been trying to solve a problem from coursera.
Problem description: Given an undirected graph with 𝑛 vertices and 𝑚 edges, check whether it is bipartite.
Input Format. A graph is given in the standard format.
Constraints. 1 ≤ 𝑛 ≤ 105, 0 ≤ 𝑚 ≤ 105.
Output Format. Output 1 if the graph is bipartite and 0 otherwise.
Input:
4 4
1 2
4 1
2 3
3 1
Output:
0
Input:
5 4
5 2
4 2
3 4
1 4
Output:
1
I came up with a solution in c++ that looks like
#include <bits/stdc++.h>
using namespace std;
#define vvi vector<vector<int>>
#define vi vector<int>
#define qi queue<int>
int bfs(vvi adj, int s, vi &disc, vi &dist)
{
disc[s] = 1; dist[s] = 0;
qi q;
q.push(s);
while(!q.empty())
{
int u = q.front(); q.pop();
for(int i: adj[u])
{
if(!disc[i])
{
disc[i] = 1;
q.push(i);
dist[i] = dist[u]+1;
}else if(dist[u]==dist[i])
{
return 0;
}
}
}
return 1;
}
bool isBipartite(vvi adj, vi &disc, vi &dist)
{
for(int i=0;i<adj.size();++i)
{
if(!disc[i])
{
if(!bfs(adj, i, disc, dist))
{
return 0;
}
}
}
return 1;
}
int main()
{
int n, m;
cin >> n >> m;
vvi adj(n);
for(int i=0;i<m;++i)
{
int x, y;
cin >> x >> y;
adj[x-1].push_back(y-1);
adj[y-1].push_back(x-1);
}
vi dist(n);
vi disc(n, 0);
cout << isBipartite(adj, disc, dist);
}
But this solution is generating wrong answer on test case 3. Can anyone figure out what I have missed in that code?
Thanks in advance. ♥
Your logic seems flawless, there is a possible cause of error: you don't pass adj parameter as a reference. This mean that for every call of bfs method the graph will be copied. If 3rd test case is an isolated graph (no edges) that would be bad. Sometimes runtime error and memory exceeded error are treated by the online judge as a non existent wrong answer.
So I have a grid which is in one form and im trying to get the X and Y.
Is there a formula where I could turn for example 12 into 2,2 or 14 to 2,3
Also is there a name for this type of grid?
static int getX(int z)
{
int count = 0;
int res = 0;
int curr = 0;
for(int temp = z; temp > 0; temp >>= 1)
{
if(count % 2 ==0)
{
res += ((temp & 1) << curr);
curr++;
}
count++;
}
return res;
}
static int getY(int z)
{
int count = 0;
int res = 0;
int curr = 0;
for(int temp = z; temp > 0; temp >>= 1)
{
if(count % 2 ==1)
{
res += ((temp & 1) << curr);
curr++;
}
count++;
}
return res;
}
As Sneftel observed, this looks like a Z-order curve. As such, you can convert coordinates by interleaving binary representations. So your examples are
0 1 0 x=2 0 1 0 x=2
0 1 0 y=2 0 1 1 y=3
001100 p=12 001110 p=14
So to get x and y coordinates from the cell number p, you assign the bits of p alternatingly to x and y. This kind of bit arithmetic is pretty hard to express using elementary arithmetic operations, and there is no generally recognized formula symbol for this that I'm aware of, but the idea is quite simple.
I newbie to mpi programming. I was trying to write matrix multiplication. Went through the post MPI Matrix Multiplication with scatter gather about matrix multiplication using scatter and gather routine.
I tried modifying the code available on above post as below...
#define N 4
#include <stdio.h>
#include <math.h>
#include <sys/time.h>
#include <stdlib.h>
#include <stddef.h>
#include "mpi.h"
void print_results(char *prompt, int a[N][N]);
int main(int argc, char *argv[])
{
int i, j, k, rank, size, tag = 99, blksz, sum = 0;
int a[N][N]={{1,2,3,4},{5,6,7,8},{9,1,2,3},{4,5,6,7,}};
int b[N][N]={{1,2,3,4},{5,6,7,8},{9,1,2,3},{4,5,6,7,}};
int c[N][N];
int aa[N],cc[N];
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
//scatter rows of first matrix to different processes
MPI_Scatter(a, N*N/size, MPI_INT, aa, N*N/size, MPI_INT,0,MPI_COMM_WORLD);
//broadcast second matrix to all processes
MPI_Bcast(b, N*N, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Barrier(MPI_COMM_WORLD);
//perform vector multiplication by all processes
for (i = 0; i < N; i++)
{
for (j = 0; j < N; j++)
{
sum = sum + aa[j] * b[i][j];
}
cc[i] = sum;
sum = 0;
}
MPI_Gather(cc, N*N/size, MPI_INT, c, N*N/size, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Barrier(MPI_COMM_WORLD);
MPI_Finalize();
print_results("C = ", c);
}
void print_results(char *prompt, int a[N][N])
{
int i, j;
printf ("\n\n%s\n", prompt);
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) {
printf(" %d", a[i][j]);
}
printf ("\n");
}
printf ("\n\n");
}
I ran above program as
$mpirun -np 4 ./a.out
For above program I am getting following incorrect output..
C =
0 0 -562242168 32766
1 0 4197933 0
-562242176 32766 0 0
4197856 0 4196672 0
C =
0 0 -1064802792 32765
1 0 4197933 0
-1064802800 32765 0 0
4197856 0 4196672 0
C =
30 70 29 60
70 174 89 148
29 89 95 74
60 148 74 126
C =
0 0 -1845552920 32765
1 0 4197933 0
-1845552928 32765 0 0
4197856 0 4196672 0
I have following queries
1. Why result matrix C is getting printed by all processes. It is
supposed to be printed by only main process.
2. Why incorrect result is being printed?
Corrections and help in this regard will be appreciated.
The result matrix c is getting printed by all processes because every process executes the function void print_results(char *prompt, int a[N][N]). Since you are gathering at the process having rank 0, add a statement if (rank == 0) before calling the print_results(...) function. Further, the result is incorrect because of a wrong loop logic in :
for (j = 0; j < N; j++)
{
sum = sum + aa[j] * b[i][j];
}
This should be :
for (j = 0; j < N; j++)
{
sum = sum + aa[j] * b[j][i];
}
Also there is no need to broadcast b as all processes already already have a copy of it and you can avoid MPI_Barrier(). The complete program then becomes :
#define N 4
#include <stdio.h>
#include <math.h>
#include <sys/time.h>
#include <stdlib.h>
#include <stddef.h>
#include "mpi.h"
void print_results(char *prompt, int a[N][N]);
int main(int argc, char *argv[])
{
int i, j, k, rank, size, tag = 99, blksz, sum = 0;
int a[N][N]={{1,2,3,4},{5,6,7,8},{9,1,2,3},{4,5,6,7,}};
int b[N][N]={{1,2,3,4},{5,6,7,8},{9,1,2,3},{4,5,6,7,}};
int c[N][N];
int aa[N],cc[N];
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
//scatter rows of first matrix to different processes
MPI_Scatter(a, N*N/size, MPI_INT, aa, N*N/size, MPI_INT,0,MPI_COMM_WORLD);
//broadcast second matrix to all processes
MPI_Bcast(b, N*N, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Barrier(MPI_COMM_WORLD);
//perform vector multiplication by all processes
for (i = 0; i < N; i++)
{
for (j = 0; j < N; j++)
{
sum = sum + aa[j] * b[j][i]; //MISTAKE_WAS_HERE
}
cc[i] = sum;
sum = 0;
}
MPI_Gather(cc, N*N/size, MPI_INT, c, N*N/size, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Barrier(MPI_COMM_WORLD);
MPI_Finalize();
if (rank == 0) //I_ADDED_THIS
print_results("C = ", c);
}
void print_results(char *prompt, int a[N][N])
{
int i, j;
printf ("\n\n%s\n", prompt);
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) {
printf(" %d", a[i][j]);
}
printf ("\n");
}
printf ("\n\n");
}
Then c =
C =
54 37 47 57
130 93 119 145
44 41 56 71
111 79 101 123
Call to mpi_finalize doesn't indicate that all the MPI processes are terminated like in OpenMP !
In most of mpi implementation, all the processes execute the instruction before the MPI_init and after MPI_Finalized.
A good practice is to do nothing before MPI_Init and after MPI_Finalized.
I have to count number of distinct prime factors over 2 to 100000, Is there any fast method than what I am doing ?
i.e.. 2 has 1 distinct prime factor 2
10 has 2 distinct prime factor (2,5)
12 has 2 distinct prime factor (2,3)
My code :-
#include<stdio.h>
#include<math.h>
typedef unsigned long long ull;
char prime[100000]={0};
int P[10000],fact[100000],k;
void sieve()
{
int i,j;
P[k++]=2;
for(i=3;i*i<1000;i+=2)
{
if(!prime[i])
{
P[k++]=i;
for(j=i*i;j<100000;j+=i+i)
prime[j] = 1;
}
}
for(i=1001;i<100000;i+=2)
if(!prime[i])
P[k++]=i;
}
int calc_fact() {
int root,i,count,j;
fact[1]=fact[2]=fact[3]=1;
for(i=4;i<=100000;i++) {
count=0;
root=i/2+1;
for(j=0;P[j]<=root;j++) {
if(i%P[j]==0)count++;
}
if(count==0) fact[i]=1;
else fact[i]=count;
}
return 0;
}
int main(){
int i;
sieve();
calc_fact();
for(i=1;i<10000;i++) printf("%d ,",fact[i]);
return 0;
}
You can easily adapt the sieve of Erasthotenes to count the number of prime factors a number has.
Here's an implementation in C, along with some tests:
#include <stdio.h>
#define N 100000
static int factorCount[N+1];
int main(void)
{
int i, j;
for (i = 0; i <= N; i++) {
factorCount[i] = 0;
}
for (i = 2; i <= N; i++) {
if (factorCount[i] == 0) { // Number is prime
for (j = i; j <= N; j += i) {
factorCount[j]++;
}
}
}
printf("2 has %i distinct prime factors\n", factorCount[2]);
printf("10 has %i distinct prime factors\n", factorCount[10]);
printf("11111 has %i distinct prime factors\n", factorCount[11111]);
printf("12345 has %i distinct prime factors\n", factorCount[12345]);
printf("30030 has %i distinct prime factors\n", factorCount[30030]);
printf("45678 has %i distinct prime factors\n", factorCount[45678]);
return 0;
}
You can definitely do better by making a sieve of Eratosthenes.
In Python
N = 100000
M = int(N**.5) # M is the floor of sqrt(N)
nb_of_fact = [0]*N
for i in xrange(2,M):
if nb_of_fact[i] == 0: # test wether i is prime
for j in xrange(i,N,i): # loop through the multiples of i
nb_of_fact[j] += 1
for i in xrange(M,N):
if nb_of_fact[i] == 0:
nb_of_fact[i] = 1
At the end of the loop, nb_of_fact[i] is the number of prime factors of i (in particular it is 1 if and only if i is prime).
Older wrong version
N = 100000
nb_of_fact = [1]*N
for i in xrange(2,N):
if nb_of_fact[i] == 1: # test wether i is prime
for j in xrange(2*i,N,i): # loop through the multiples of i
nb_of_fact[j] += 1
I have a problem with loops in opencl when I want to use counters in my loop to generate values, It seems like the counters values remain constants during the iterations. My OpenCL function code is the following :
void my_loop( __global unsigned int* tab1, unsigned int* tab2){
uint i, j;
uint global_id_y = get_global_id(1);
uint global_size_y = get_global_size(1);
uint loop = global_size_y - global_id_y - 1
uint length = get_global_size(0);
for(i = 0; i < loop; i++){
sidx = i * length;
for(j = 0; j < length; j++){
tab2[sidx + j ] = i*10 + j;
}
}
The code that calls the clEnqueueNDRangeKernel function
global_work_size[0] = ncols; //ncols = 5
global_work_size[1] = nbfrequents; //nbfrequents = 10
local_work_size[0] = ncols;
local_work_size[1] = nbfrequents;
clEnqueueNDRangeKernel(command_queue, kernel, 2, NULL, global_work_size,
local_work_size, 0, NULL, &event);
After execution, the results I obtained is something like this :
0 1 2 3 4
0 1 2 3 4
0 1 2 3 4
0 1 2 3 4
...
0 1 2 3 4
Is it normal ? How can I do to use the differents values of my counters ?