viernes, 29 de junio de 2012

Evaluacion de función objetivo, factibilidad de la solución y soluciones iniciales

Evaluación Función Objetivo
El Objetivo es cubrir la mayor cantidad de aristas con la menor cantidad de nodos  (vertices).
Área Factible  se  define como los vértices que cubren la cantidad de aristas totales en el grafo. En el peor de los casos serian todos los vértices, pero se necesita una solución inicial  que cumpla con la condición que sean la menor cantidad de vértices para esto compararemos a la par el vértice que contiene la mayor cantidad de vecinos  para poder cubrir así la mayor área, ya teniendo ese vértice eliminaremos de una lista las aristas que están cubiertas por ese vértice y volveremos a verificar el siguiente vértice que tiene la mayor cantidad de vecinos (aristas) y lo pondremos en nuestra lista de vértices que constituyen la solución inicial y seguiremos eliminando de la lista de aristas las que ya están cubiertas y si en esta lista ya no existen aristas disponibles termina la función de evaluar el área factible.



Generar una Solución Inicial constituye el hecho de que sea una solución dentro del área factible para poder partir de ahí y poder mejorarla, esto se definiría como la cantidad de vértices utilizados representados de alguna forma por ejemplo vértice A vértice C y vértice F cubren todos los aristas por ello es una solución inicial más no la óptima.

for(i=1;i<=vertices;i++){

      for(j=1;j<=maxar;j++){


 g[i][j] = conectado(densidad);  

        
 if(g[i][j]==1 && c[j]<2){

   printf("%d - %d \n", i, j);

   fprintf(datos, "a %d - %d \n", i, j);

   c[j]=c[j]+1;

   arist[j]=1;
}}}


    for(i=1;i<=vertices;i++){

      for(j=1;j<=maxar;j++){ 

           

 if(g[i][j]==1 && c[j]<2 && arist[j]!=0){

   arist[j]=0;

   verti[i]=1;

                         
}}}
    for(i=1;i<=vertices;i++){

      for(j=1;j<=maxar;j++){ 

         if(arist[j]==2){

   verti[i]=1;
           }
      } 
    }                         
                       
    printf("\n Vertices que cubren todas las aristas:\n");
    for(j=1;j<=maxar;j++){

      if(verti[j]==1){
 printf("%d \n", j);                                 }

    }



jueves, 28 de junio de 2012

Cotas del Problema Cobertura de Vértices

Para el problema de la cobertura de vértices necesitamos  minimizar la cantidad de nodos utilizados para cubrir la mayor cantidad de aristas en el grafo.
 

También se podría minimizar la cantidad de aristas utilizadas para cubrir el total de nodos.










La cota superior es una solucion factible para nuestro problema en este caso sería que se cubrieran todos los nodos y vértices esto seria el total vértices y el máximo de aristas permitido.

La cota inferior es una solución ideal mas aproximada a la solución óptima que se justifica con la relación de aristas en cada vértice, es el vértice que tiene la mayor cantidad de "vecinos" y la cantidad de aristas mínima permitida que recibe como argumento bajo la condición que sea mayor al número de vértices.

Código:
printf("Maximo de aristas: %d \n", maxar);
    printf("Densidad: %f \n", densidad);
    int  max=0;
    int v[vertices+1];    
    for(i=1;i<=vertices;i++)    
      {
       v[i]=0;
      }

    for(i=1;i<=vertices;i++)
     {
     for(j=i;j<=maxar;j++)
      {
       g[i][j] = conectado(densidad);  
       if(g[i][j]==1)
        {
         printf("%d - %d \n", i, j);
         fprintf(datos, "a %d - %d \n", i, j);
         v[i]=v[i]+1;
        }   
       }                                                 
      }
    for(i=1;i<=vertices;i++)    
     {
    if(max < v[i])
      {
       max=v[i];
      } 
     }
    for(i=1;i<=vertices;i++)    
     {
      if(v[i]==max)
       {
        max=i;
       }
     }
    printf("\n#Cota inferior = (%d , %d)\n",max,aristas);   
    printf("#Cota superior = (%d , %d)\n",vertices,maxar);
 

miércoles, 27 de junio de 2012

Generador de Instancias el Problema de Cobertura de vértices (Vertex Cover)

Sea m = |E | el número de lados y n = |V | el número de vértices. Se definen las variables binarias: xi es 1 si el vértice está en la cubierta, y 0 en otro caso. El total de variables binarias usadas en n. El objetivo consiste en minimizar

Sujeto a
  • Todo lado tiene al menos un extremo en la cubierta:

ENTRADA: Grafo G.
SALIDA: El menor número k tal que exista una cobertura de vértices S para G de tamaño k.
Equivalentemente, el problema puede definirse como un problema de decisión:

ENTRADA: Grafo G y un entero positivo k.
PREGUNTA: ¿Existe una cobertura de vértices S para G de tamaño menor o igual a k?

Estructuras para representarlo
Matriz de incidencia – El grafo está representado por una matriz de A (aristas) por V (vértices), donde [arista, vértice] contiene la información de la arista (1 – conectado, 0 – no conectado)
Matriz de adyacencia – El grafo está representado por una matriz cuadrada M de tamaño n2, donde n es el número de vértices. Si hay una arista entre un vértice x y un vértice y, entonces el elemento mx,y es 1, de lo contrario, es 0

Tomaremos como datos de entrada
vértices , aristas.




Resultados del Generador:

#include<stdio.h>
#include<time.h>
#include<string.h>
int conectado(float densidad);

main(int argc, char *argv[]){
  
  int vertices;  // Cantidad de vertices
  int aristas;
  int maxar;    // Numero maximo de aristas
  float densidad;
  int i, j, objetos=0;
  char linea[50];
  FILE *datos;
  datos = fopen(argv[1],"r");

  if(datos!=NULL){
    
    printf("\nLeyendo instancia del archivo: %s \n\n", argv[1]);
                
    do{
      
      fgets(linea, 100, datos);
      
      if(strlen(linea)==0){       
        continue;
      }
      if(linea[0]=='#'){
        
      printf("Comentario: %s \n", linea);  
      
      }
      
      if(linea[0]=='a'){
        objetos += 1;      
 printf("%s", linea);
      }
    }while(!feof(datos));             
    printf("Son %d aristas en la instancia. \n", objetos);                                      
  }
  else{
    vertices = atoi(argv[1]);
    aristas = atoi(argv[2]);
    maxar = (vertices*(vertices-1))/2;
    
    if(aristas<vertices || aristas>maxar){
      printf("\n\nError: El numero de aristas no puede ser menor al numero de vertices");
      return 0;
    }
    
    printf("Generando conexiones al azar entre %d vertices y %d aristas \n", vertices, aristas);
    
    datos = fopen("datos.txt","w");
    
    densidad = (float)(2*aristas)/(float)(vertices*(vertices-1));
    
    fprintf(datos, "i %d %d %f\n", vertices, aristas, densidad);
    fprintf(datos, "# Instancia generada para %d vertices y %d aristas \n\n", vertices, aristas);
    
    int g[vertices+1][maxar+1];
    
    printf("Maximo de aristas: %d \n", maxar);
    printf("Densidad: %f \n", densidad);
    srand(time(NULL));
    
    for(i=1;i<=vertices;i++){
      for(j=i;j<=maxar;j++){
 
 g[i][j] = conectado(densidad);  
 if(g[i][j]==1){
   printf("%d - %d \n", i, j);
   fprintf(datos, "a %d - %d \n", i, j);
 }   
      }                                                 
    }
  }
  return 0;
}
int conectado(float densidad){
  
  float num;
  int x;
  
  num = (rand() % 10) + 0;
  num=num/10.00;
    
  if(num>=densidad){
    x=1;
  }else{
    x=0;
  }
  return(x);     
}


Otros generadores de Instancias en Vertex Cover:
http://www.nlsde.buaa.edu.cn/~kexu/benchmarks/graph-benchmarks.htm
http://cs.hbg.psu.edu/benchmarks/vertex_cover.html


Referencias
cobertura de vertices

martes, 26 de junio de 2012

Vertex Cover

El equipo esta formado por:
  • Karen Alduncin Ibarra (calif. esperada: 100)
  • Kevin Darío Pérez Cuéllar (calif. esperada: 90)
  • Ricardo Lopez Porras (calif. esperada: 80)

El Lenguaje que utilizaremos será C y Java.

El problema a analizar será vertex cover (cobertura de vértices) que es un problema NP-completo.
Este problema es muy utilizado en teoría de complejidad computacional para probar la pertenencia a la clase NP-Hard de otros problemas computacionales difíciles.

Por ejemplo:
  • Clique
  • Set covering
  • Circuitos Hamiltonianos

La cobertura de vértices de un grafo no dirigido G = (V,E) es unsubconjunto S de V (el conjunto de vértices) tal que para cada aristaab del conjunto E, ya sea el vértice a o b pertenece a S.


Suponga un grafo no dirigido G = (V, E). Una cubierta de vértices para G es un subconjunto de vértices V' tal que todo lado de E es incidente en al menos un vértice de V'.

El problema de la cobertura de vértices consiste en determinar una cobertura con el mínimo número de vértices.
El problema de poner guardias en los extremos (vértices) de los pasillos (lados) para cubrirlos todos es un problema de cubierta de vértices; el problema abastecer una colonia con el menor número de luminarias también lo es.

Cada vértice cubre su arco incidente y se trata de buscar el conjunto de vértices que cubra todos los arcos. La idea es encontrar la cobertura de vértices de tamaño mínimo.

En el siguiente grafo, {1,3,5,6} es una cobertura de vértices de tamaño 4. Sin embargo, esta no es la cobertura mínima, porque existen las coberturas de vértices {245} {124} y,ambas de tamaño 3 que satisfacen la cobertura.


Para reducir el conjunto independiente de VERTEX COVER sólo tenemos que observar que un conjunto de nodos S es una cubierta de vértices del grafo G = (V, E) (es decir, S toca cada borde en E) si y sólo si los nodos restantes, VS, son un conjunto independiente de G .


Por lo tanto, para resolver una instancia (G, g), del grupo independiente, sólo tiene que buscar una cubierta de vértices de G con JV nodos j g. Si una cubierta de vértices existe, luego tomar todos los nodos no en él. Si no hay tal cubierta de vértices existe, entonces G no puede tener un conjunto independiente de tamaño de g.

Rango de vertices mayor de 100 para el caso de 100 vertices seria d= 0.5 y mmax = 100(100-1)/2 [4950]*0.05 = 247 aristas totales, con las formulas = mmax*d donde d= m / mmax , mmax = n(n-1)/2 para poder ejemplificar como un problema en un grafo no dirigido.


Referencias: