graphlayers.cpp
// $Id$
/*
COMIENZO DE DESCRIPCION
__USE_WIKI__
Dado un grafo #vector<set<int>> G# y un vertice de
partida #x# se desea determinar la estructuras de capas
de vecinos de #G# alrededor de #x# definida de la
siguiente forma: la capa 0 es #{x}#, la capa 1 son los
vecinos de #x#. A partir de alli la capa #n>=2# esta
formada por los vecinos de los nodos de la capa #n-1#
(es decir la _adyacencia_ de la capa) pero que no estan
en las capas anteriores (en realidad basta con verificar
que no esten en las capas #n-1# ni #n-2# ).
[Tomado en tercer parcial 22-NOV-2007].
keywords: conjunto
FIN DE DESCRIPCION */
// -----------------------------------------------------------------
#include <iostream>
#include <vector>
#include <set>
#include "./util.h"
using namespace std ;
//---:---<*>---:---<*>---:---<*>---:---<*>---:---<*>
void mklayers(vector< set<int> > &graph,
int x,
vector< set<int> > &layers) {
layers.clear();
layers.push_back(set<int>());
layers.back().insert(x);
int jlay=0;
while (1) {
layers.push_back(set<int>());
set<int>
&newlay = layers[jlay+1],
&layer = layers[jlay];
set<int>::iterator q = layer.begin();
while (q!=layer.end()) {
set<int> &ngbrs = graph[*q];
set<int>::iterator r = ngbrs.begin();
while (r!=ngbrs.end()) {
if (layer.find(*r)!=layer.end()) continue;
if (jlay==0) newlay.insert(*r);
else {
set<int> &inner = layers[jlay-1];
if (inner.find(*r)==inner.end()) {
newlay.insert(*r);
}
}
r++;
}
q++;
}
if (newlay.empty()) break;
jlay++;
}
}
//---:---<*>---:---<*>---:---<*>---:---<*>---:---<*>
void mk_adjncy(vector< set<int> > &G,
set<int> &front, set<int> &adjncy) {
set<int>::iterator p = front.begin();
adjncy.clear();
set<int> tmp;
while (p!=front.end()) {
set_union(adjncy,G[*p++],tmp);
adjncy = tmp;
}
set_difference(adjncy,front,tmp);
adjncy = tmp;
}
//---:---<*>---:---<*>---:---<*>---:---<*>---:---<*>
void mklayers2(vector< set<int> > &G,
int x,
vector< set<int> > &layers) {
layers.clear();
layers.push_back(set<int>());
layers.back().insert(x);
layers.push_back(set<int>());
layers[1] = G[x];
int next=2;
set<int> tmp,newlayer;
while (1) {
mk_adjncy(G,layers[next-1],tmp);
set_difference(tmp,layers[next-2],newlayer);
if (newlayer.empty()) break;
layers.push_back(newlayer);
next++;
}
}
//---:---<*>---:---<*>---:---<*>---:---<*>---:---<*>
void print_layers(vector< set<int> > &layers) {
for (int j=0; j<layers.size(); j++) {
printf("layer[%d] = {",j);
set<int> &lay = layers[j];
set<int>::iterator q = lay.begin();
while(q!=lay.end()) {
printf("%d ",*q);
q++;
}
printf("}\n");
}
}
//---:---<*>---:---<*>---:---<*>---:---<*>---:---<*>
int modulo(int j,int n) {
int k = j%n;
if (k<0) k += n;
return k;
}
//---:---<*>---:---<*>---:---<*>---:---<*>---:---<*>
int main() {
int N=10;
vector< set<int> > G(N),layers;
for (int j=0; j<N; j++) {
G[j].insert((j+1)%N);
G[j].insert((j+N-1)%N);
}
mklayers(G,0,layers);
printf("---------------------\n");
printf("1D cyclic grid, N %d, using algo: mklayers\n",N);
print_layers(layers);
mklayers2(G,0,layers);
printf("---------------------\n");
printf("1D cyclic grid, N %d, using algo: mklayers2\n",N);
print_layers(layers);
int Nvrtx = N*N;
G.clear();
G.resize(N*N);
for (int j=0; j<N; j++) {
for (int k=0; k<N; k++) {
int vrtx=k*N+j, ngbr;
set<int> &ngbrs = G[vrtx];
if (k>0) {
ngbr = modulo((k-1)*N+j,Nvrtx);
ngbrs.insert(ngbr);
}
if (k<N-1) {
ngbr = modulo((k+1)*N+j,Nvrtx);
ngbrs.insert(ngbr);
}
if (j<N-1) {
ngbr = modulo(k*N+j+1,Nvrtx);
ngbrs.insert(ngbr);
}
if (j>0) {
ngbr = modulo(k*N+j-1,Nvrtx);
ngbrs.insert(ngbr);
}
}
}
mklayers(G,0,layers);
printf("---------------------\n");
printf("2D non-cyclic grid, N %d, usigng algo: mklayers\n",N);
print_layers(layers);
mklayers2(G,0,layers);
printf("---------------------\n");
printf("2D non-cyclic grid, N %d, usigng algo: mklayers2\n",N);
print_layers(layers);
}
Generated by GNU Enscript 1.6.6.