I have a doubt in a line given below of this code:
cout<<"("<<c<<","<<(*i).get_vertex()<<") value of this pair : "<<(*i).get_weight()<<", ";
How this get_vertex and get_weight work without the help of class edge object. The code compiled successfully and it's working too but I can't figure out how the above line is working.
Output of the code is:
Pairs for 0 are -> (0,1) value of this pair : 2, (0,2) value of this pair : 3, (0,3) value of this pair : 4,
Pairs for 1 are -> (1,2) value of this pair : 5, (1,0) value of this pair : 2,
Pairs for 2 are -> (2,3) value of this pair : 8, (2,1) value of this pair : 5,
Pairs for 3 are -> (3,0) value of this pair : 4, (3,2) value of this pair : 8,
Code is given below:
#include<bits/stdc++.h>
using namespace std;
class edge{
int weight,vertex;
public:
edge(int w , int v){
weight = w;
vertex = v;
}
int get_weight()const{
return weight;
}
int get_vertex()const{
return vertex;
}
};
int main(){
int n = 4;
int c = 0;
vector<list<edge>>adj(n) ;
adj[0].push_back(edge(2,1));
adj[0].push_back(edge(3,2));
adj[0].push_back(edge(4,3));
adj[1].push_back(edge(5,2));
adj[1].push_back(edge(2,0));
adj[2].push_back(edge(8,3));
adj[2].push_back(edge(5,1));
adj[3].push_back(edge(4,0));
adj[3].push_back(edge(8,2));
vector<list<edge>>:: iterator it ;
for(it=adj.begin();it!=adj.end();it++){
cout<<" Pairs for "<<c<<" are -> ";
list<edge>li = *it;
list<edge>::iterator i;
for(i=li.begin();i!=li.end();i++){
cout<<"("<<c<<","<<(*i).get_vertex()<<") value of this pair : "<<(*i).get_weight()<<", ";
}
cout<<endl;
c++;
}
}
Break it into chunks.
Add whitespace:
cout << "("
<< c
<< ","
<< (*i).get_vertex()
<< ") value of this pair : "
<< (*i).get_weight()
<< ", ";
Does that make more sense?
Related
Map with a customized comparator does not work as expected.
Code:
struct Comp {
const bool operator()(const int x, const int y) const {
return abs(x) < abs(y);
}
};
map<int, int, Comp> func(vector<int>& arr) {
map<int, int, Comp> mp;
for (int x : arr) {
mp[x]++;
}
return mp;
};
int main() {
vector<int> arr = { 4, -2, 2, -4 };
map<int, int, Comp> res = func(arr);
for (auto it : res) {
cout << it.first << " -> " << it.second << endl;
}
return 0;
}
Output:
-2 -> 2
4 -> 2
Expected:
-4 -> 1
-2 -> 1
2 -> 1
4 -> 1
Does anyone know if C++ is wrong or my expected result is wrong?
map uses the comparator to test ordering, but also to know if two keys are equal, i.e., if comp(a,b) == false and comp(b,a) == false, then it means that the 2 keys are equal and that they should be considered the same, even though the bits in memory are different.
In your case, comp(-2,2) and comp(2,-2) are both false so it considers it as a single entry. Same thing for -4 and 4. Since the two first inserted keys are 4 and -2, these are the two keys that are set in the map. And since both negative and positive keys point to the same entry, then it increments each value twice.
I found this code online for a adjacency list that uses a vector of a pair of ints. I'm trying to understand the code and can't quite figure out what this specific line is doing in the addEdge function: adj[u].push_back(make_pair(v, wt)); . adj is the name of the vector. I get confused in the print method. When it prints, i don't understand where the source node is being stored. I get that the destination node and weight are being stored as a pair, but where does the source node int get saved? I tried experimenting with the code to understand what was going on, as seen with this line in the print function: cout << "Index: " << u << " "; but it didn't help. Here is the code:
void addEdge(vector <pair<int, int> > adj[], int u,
int v, int wt)
{
adj[u].push_back(make_pair(v, wt));
adj[v].push_back(make_pair(u, wt));
}
// Print adjacency list representaion ot graph
void printGraph(vector<pair<int,int> > adj[], int V)
{
int v, w;
for (int u = 0; u < V; u++)
{
cout << "Node " << u << " makes an edge with \n";
for (auto it = adj[u].begin(); it!=adj[u].end(); it++)
{
cout << "Index: " << u << " ";
v = it->first;
w = it->second;
cout << "\tNode " << v << " with edge weight ="
<< w << "\n";
}
cout << "\n";
}
}
// Driver code
int main()
{
int V = 5;
vector<pair<int, int> > adj[V];
addEdge(adj, 0, 1, 10);
addEdge(adj, 0, 4, 20);
addEdge(adj, 1, 2, 30);
addEdge(adj, 0, 3, 40);
addEdge(adj, 1, 4, 50);
addEdge(adj, 2, 3, 60);
addEdge(adj, 3, 4, 70);
addEdge(adj, 0, 2, 10);
printGraph(adj, V);
}
For reference, this is the output for the first two nodes:
Node 0 makes an edge with
Index: 0 Node 1 with edge weight =10
Index: 0 Node 4 with edge weight =20
Index: 0 Node 3 with edge weight =40
Index: 0 Node 2 with edge weight =10
Node 1 makes an edge with
Index: 1 Node 0 with edge weight =10
Index: 1 Node 2 with edge weight =30
Index: 1 Node 4 with edge weight =50
From your code adj is an array of vectors. So adj[u] is a vector and .push_back stores the node in that particular vector. push_back(), begin() and end() are methods in the vector. begin() returns an iterator to the first element (in your case it is a pair) so it is an iterator to a pair and you access the elements using it->first and it-second and you go to the next element (iterate) using it++
I am taking input from a file in following form :
3
0 1
0 2
1 0
1 2
2 0
2 1
Here 3 is unique number of numbers in the list i.e., 0,1,2.
I have successfully made a adjacency list of the list.
O/P :
0 -> 1 2
1 -> 0 2
2 -> 0 1
Using the following code
if (input.is_open())
{
cout << "File is Open. \n";
input >> totalnode;
pair<pair<int,int>, pair<int,int>> a;
vector<list<int>>adjlist(totalnode);
while (input >> node1 >> node2)
{
adjlist[node1].push_back(node2);
}
vector<list<int>>::iterator i;
int c = 0;
for ( i = adjlist.begin(); i != adjlist.end(); ++i)
{
cout << c << " -> ";
list<int> li = *i;
list<int>::iterator iter;
for ( iter = li.begin(); iter != li.end(); ++iter)
{
cout << *iter << " ";
}
cout << "\n";
c++;
}
Now I wish to make adjacency list of pairs.
Example :
0,1 -> (0,2) (1,0) (1,2) (2,0) (2,1)
0,2 -> (0,1) (1,0) (1,2) (2,0) (2,1)
1,0 -> (0,1) (0,2) (1,2) (2,0) (2,1)
I think, I should use this,
vector<pair<int, int>> asd;
or
vector<list<pair<int,int>>> asd;
How do I compare pairs? Honestly I have no idea, how to achieve this.
It depends on the requirement. As rightly said by Sam, there is default comparison overload which first compares the first field. If that is same, then it compares the second field.
If that's what you want, then just use it directly.
Otherwise, Overload comparison operator. I think in your case, you don't need it.
In your case, what you should do is maintain a map.
map<pair<int, int>, vector< pair<int, int> > > asd;
and directly use pair as key for the map.
I am trying to implement the Bron-Kerbosch's algorithm, which is a recursive algorithm for clique finding. I managed to get to a point, where it returns the correct number of cliques, yet when I print them, they are not correct - additional nodes are added. Am I missing something obvious here?
I am using adjacency list structure:
vector< list<int> > adjacency_list;
where I add edges the following way:
void graph::addEdge(int i1,int i2){
//as this is an undirected graph
adjacency_list[i1].push_back(i2);
adjacency_list[i2].push_back(i1);
}
Main algorithm is the following:
void graph::BronKerbosch(vector<int> R, vector<int> P, vector<int> X){
if (P.empty() && X.empty()){
result_cliques.insert(R);
}
// vector <int> tmpVerts = P;
for(std::vector<int>::iterator it = P.begin(); it != P.end();) {
vector<int> intersection = {}, intersectionX = {};
int node = *it;
//N(P)
for (int nodeP : adjacency_list[node]){
for (int node2 : P){
if (nodeP == node2){
intersection.push_back(nodeP);
}
}
//N(X)
for (int node3 : X){
if (nodeP == node3){
intersectionX.push_back(nodeP);
}
}
}
R.push_back(node);
BronKerbosch(R,intersection,intersectionX);
//P.erase(remove(P.begin(),P.end(),node),P.end());
P.erase(it);
X.push_back(node);
}
}
And I run it within:
void graph::run_BronKerbosch(){
vector<int> R,P,X;
for (int i=1; i < adjacency_list.size(); i++) {
P.push_back(i);
}
BronKerbosch(R,P,X);
cout << "................\nClassic: " << result_cliques.size() << endl;
for (auto clique : result_cliques){
cout << "(";
for (int node : clique){
cout << node <<" ";
}
cout << ")\n";
}
}
The output problem for the following graph input:
1 2
1 3
2 3
is, that this code returns:
(1 2 3 )
(1 2 3 4 )
(1 2 3 4 5 )
whereas it should return (used python for this):
(1 2 3 )
(2 4 )
(2 5 )
Thank you very much for any help.
In the wikipedia page, the recursive call looks like this:
for each vertex v in P:
BronKerbosch1(R ⋃ {v}, P ⋂ N(v), X ⋂ N(v))
...
In the code from the question, you do a R.push_back(node) before the recursive call, but that node will be included in R in all subsequent iterations of the loop, which is not correct.
That is, the following instructions:
R.push_back(node);
BronKerbosch(R,intersection,intersectionX);
should probably be followed by a R.pop_back(node) immediately after the recursive call.
It is best to give an example.
Let's say vector A consists of:
A = {3 ,2 ,1 ,4 ,6 ,3 ,8 ,4}
and vector B consists of:
B = {1.5,2 ,2 ,1.5,3 ,3 ,3 ,2}
The unique values in vector B are {1.5, 2, 3}
I want the resulting vector RESULT to be:
RESULT[0] = Average(A given B=1.5) = Average(3,4)
RESULT[1] = Average(A given B=2 ) = Average(2,1,4)
RESULT[2] = Average(A given B=3 ) = Average(6,3,8)
What is the most efficient way of calculating this. My own method is to loop over unique elements of B, and for each of them, loop over each B value trying to match that unique number and keep summing up the corresponding element of vector A in each match, also counting the number of matches so I can find the average.
This is too slow. since My vector A is 8M elements, and vector B consists of 0.5M unique values.
Any help would be appreciated.
Here's a lazy idea: Traverse both vectors in lockstep and aggregate the results in a separate container. For example:
#include <cassert>
#include <cmath>
#include <iostream>
#include <map>
#include <utility>
std::map<double, std::pair<int, std::size_t>> m;
assert(A.size() == B.size());
for (std::size_t i = 0; i != A.size(); ++i)
{
assert(!std::isnan(B[i]));
auto & p = m[B[i]];
p.first += A[i];
p.second += 1;
}
In the end you just report the results:
for (const auto & p : m)
std::cout << "Average for bin " << p.first << " is "
<< static_cast<double>(p.second.first) / p.second.second
<< "\n";
(Beware that your key value must not be NaN: in an ordered map, NaN is not part of the strict ordering; in an unordered map, it does not compare equal to itself.)
You can do a loop with a (hash) table: see it Live On Coliru
int main()
{
vector<int> A = {3 ,2 ,1 ,4 ,6 ,3 ,8 ,4};
vector<double> B = {1.5,2 ,2 ,1.5,3 ,3 ,3 ,2};
assert(A.size() == B.size());
struct accum {
uintmax_t sum = 0;
size_t number_of_samples = 0;
void sample(int val) { sum += val; ++number_of_samples; }
};
map<double, accum> average_state;
for(size_t i = 0; i<B.size(); ++i)
average_state[B[i]].sample(A[i]);
for(auto& entry : average_state)
{
accum& state = entry.second;
double average = static_cast<double>(state.sum) / state.number_of_samples;
std::cout << "Bucket " << entry.first << "\taverage of " << state.number_of_samples << " samples:\t" << average << "\n";
}
}
Prints
Bucket 1.5 average of 2 samples: 3.5
Bucket 2 average of 3 samples: 2.33333
Bucket 3 average of 3 samples: 5.66667