Vous êtes sur la page 1sur 8

using System;

using System.Collections.Generic;
using System.Text;
namespace Ramificacion_y_poda
{
class Grafo
{
int[,] Mat;
int n;
public int[,] Mat1
{
get { return Mat; }
set { Mat = value; }
}
public int N
{
get { return n; }
set { n = value; }
}
/*public Grafo(int n)
{
this.n = n;
Mat = new int[n, n];
Console.WriteLine("Ingrese caminos. Finalice con 0");
int i, j, k;
Console.WriteLine("Ingrese ciudad fuente (1-" + n + ")");
i = (Int32.Parse(Console.ReadLine())-1);
Console.WriteLine("Ingrese ciudad destino (1-" + n + ")");
j = (Int32.Parse(Console.ReadLine())-1);
Console.WriteLine("Ingrese distancia");
k = Int32.Parse(Console.ReadLine());
while ((i != -1) && (j != -1))
{
Mat[i, j] = k;
Console.WriteLine("Ingrese ciudad salida(1-" + n + ")");
i = (Int32.Parse(Console.ReadLine())-1);
Console.WriteLine("Ingrese ciudad destino(1-" + n + ")");
j = (Int32.Parse(Console.ReadLine())-1);
Console.WriteLine("Ingrese distancia");
k = Int32.Parse(Console.ReadLine());
}
}*/
public Grafo()
{
Mat = new int[5, 5];
Mat[0, 1] = 15; Mat[0, 2] = 7; Mat[0, 3] = 4; Mat[0, 4] = 20;
Mat[1, 0] = 1; Mat[1, 2] = 16; Mat[1, 3] = 6; Mat[1, 4] = 5;
Mat[2, 0] = 8; Mat[2, 1] = 20; Mat[2, 3] = 4; Mat[2, 4] = 10;
Mat[3, 0] = 4; Mat[3, 1] = 7; Mat[3, 2] = 14; Mat[3, 4] = 3;
Mat[4, 0] = 10; Mat[4, 1] = 35; Mat[4, 2] = 15; Mat[4, 3] = 4;
}
}
class Monticulo
{
nodo[] Arbol;
public Monticulo(int xcant)
{
int cant = xcant + 10;
Arbol = new nodo[cant];
Arbol[0] = new nodo();
Arbol[0].K = 0;
}
public int Padre(int i) { return (i / 2); }
public int Hijo_Izquierdo(int i) { return (i * 2); }
public int Hijo_Derecho(int i) { return ((i * 2) + 1); }
public void Insertar(nodo x)
{
if (Arbol[0].K == 0)
{
Arbol[1] = x;
Arbol[0].K++;
}
else
{
Arbol[Arbol[0].K + 1] = x;
Arbol[0].K++;
int H = Arbol[0].K;
int P = Padre(H);
nodo aux;
while ((P > 0) && (Arbol[P].Costo > Arbol[H].Costo))
{
aux = Arbol[H];
Arbol[H] = Arbol[P];
Arbol[P] = aux;
H = P;
P = Padre(H);
}
}
}
public int Menor(int x, int y)
{
if (Arbol[x].Costo < Arbol[y].Costo)
return (x);
else
if (Arbol[x].Costo > Arbol[y].Costo)
return (y);
return 0;
}
public nodo Elimina_Min()
{
if (Arbol[0].K == 0)
{
Console.WriteLine(" ..:. No hay nada cargado en el Arbol...");
return null;
}
else
{
nodo aux = Arbol[1];
if (Arbol[0].K == 1)
{
Arbol[1] = null;
Arbol[0].K--;
return aux;
}
else
{
Arbol[1] = Arbol[Arbol[0].K];
Arbol[Arbol[0].K] = null;

int HI = Hijo_Izquierdo(1);
int HD = Hijo_Derecho(1);
int P = 1;

while (((Arbol[0].K > HI) && (Arbol[0].K > HD)) && ((Arbol[P
].Costo > Arbol[HD].Costo) && (Arbol[P].Costo > Arbol[HI].Costo)))
{
int M = Menor(HI, HD);
nodo aux2 = Arbol[M];
Arbol[M] = Arbol[P];
Arbol[P] = aux2;
P = M;
HI = Hijo_Izquierdo(P);
HD = Hijo_Derecho(P);
}
Arbol[0].K--;
return aux;
}
}
}
public bool Vacia() { return Arbol[0].K == 0; }
}
class nodo
{
static int cota;
static int n;
int MAXHIJOS;
int costo;
int[,] matriz;
int k;
int[] solucion;
public int K
{
get { return k; }
set { k = value; }
}
public int Maxhijos
{
get { return MAXHIJOS; }
}
public int[] Solucion
{
get { return solucion; }
set { solucion = value; }
}
public int[,] Matriz
{
get { return matriz; }
set { matriz = value; }
}
public void definir_n(int m) { n = m; }
public void Poner_Cota(int m)
{
if (m < cota)
cota = m;
}
public int Costo
{
get { return costo; }
set { costo = value; }
}
public nodo() { }
public nodo(int n)
{
matriz = new int[n, n];
solucion = new int[n];
}
public nodo(int n, int[,] m)
{
definir_n(n);
matriz = new int[n, n];
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
matriz[i, j] = m[i, j];
for (int i = 0; i < n; i++)
matriz[i, i] = Int16.MaxValue;
costo = reducir();
solucion = new int[n];
solucion[0] = 1;
MAXHIJOS = n - 1;
k = 1;
cota = Int16.MaxValue;
}
public int reducir()
{
int costo = 0, min;
for (int i = 0; i < n; i++)
{
min = CosteFil(i);
if ((min > 0) && (min < Int16.MaxValue))
{
QuitarFil(i, min);
costo += min;
}
}
for (int j = 0; j < n; j++)
{
min = CosteCol(j);
if ((min > 0) && (min < Int16.MaxValue))
{
QuitarCol(j, min);
costo += min;
}
}
return costo;
}
public int CosteFil(int i)
{
int c = matriz[i, 0];
for (int j = 1; j < n; j++)
{
if (matriz[i, j] < c)
{
c = matriz[i, j];
}
}
return c;
}
public int CosteCol(int j)
{
int c = matriz[0, j];
for (int i = 0; i < n; i++)
{
if (matriz[i, j] < c)
{
c = matriz[i, j];
}
}
return c;
}
public void QuitarFil(int i, int min)
{
for (int j = 0; j < n; j++)
{
if (matriz[i, j] < Int16.MaxValue)
{
matriz[i, j] -= min;
}
}
}
public void QuitarCol(int j, int min)
{
for (int i = 0; i < n; i++)
{
if (matriz[i, j] < Int16.MaxValue)
{
matriz[i, j] -= min;
}
}
}
public int Expandir(ref nodo[] hijos, nodo nod)
{
int nk, i, nhijos = 0;
nodo p = new nodo(n);
nk = nod.K;
i = nod.Solucion[nk - 1] - 1;
if (nk >= n)
return nhijos;
for (int j = 0; j < n; j++)
{
if (NoEsta(nod.Solucion, nk, j))
{
nhijos++;
p = Copiar(nod);
p.Solucion[nk] = j + 1;
if (nk == n - 1)
{
p.Costo += (nod.Matriz[i, j] + nod.Matriz[j, 0]);
}
else
{
for (int l = 0; l < n; l++)
{
p.Matriz[i, l] = Int16.MaxValue;
p.Matriz[l, j] = Int16.MaxValue;
}
p.Matriz[j, 0] = Int16.MaxValue;
p.Costo += (p.reducir() + nod.Matriz[i, j]);
}
p.K++;
hijos[nhijos - 1] = p;
}
}
return nhijos;
}
public nodo Copiar(nodo nod)
{
nodo p = new nodo(n);
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
p.Matriz[i, j] = nod.Matriz[i, j];
for (int i = 0; i < n; i++)
p.Solucion[i] = nod.Solucion[i];
p.K = nod.K;
p.costo = nod.costo;
p.MAXHIJOS = nod.Maxhijos;
return p;
}
public bool NoEsta(int[] solucion, int k, int j)
{
for (int i = 0; i < k; i++)
{
if (solucion[i] == j + 1)
return false;
}
return true;
}
public bool EsAceptable()
{
return (costo < cota);
}
public bool EsSolucion()
{
return (k == n);
}
}
class Program
{
static void Main(string[] args)
{
int generados = 0, analizados = 0, podados = 0, n = 5;
/*Console.WriteLine("Ingrese cantidad de ciudades");
n = Int32.Parse(Console.ReadLine());*/
Monticulo E;
Grafo a = new Grafo();
/*int[,] m = new int[n, n];
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
m[i, j] = a.Mat1[i, j];
}
}*/
int[] solucion = new int[n];
nodo nod = new nodo(n, a.Mat1);
nod.definir_n(n);
nodo[] hijos = new nodo[nod.Maxhijos];
int numhijos;
E = new Monticulo(n);
E.Insertar(nod);
while (!E.Vacia())
{
nod = E.Elimina_Min();
analizados++;
numhijos = nod.Expandir(ref hijos, nod);
generados += numhijos;
for (int i = 0; i < numhijos; i++)
{
if (hijos[i].EsAceptable())
{
if (hijos[i].EsSolucion())
{
hijos[i].Poner_Cota(hijos[i].Costo);
for (int j = 0; j < numhijos; j++)
{
if (i != j)
{
hijos[j] = null;
}
}
solucion = hijos[i].Solucion;
}
else E.Insertar(hijos[i]);
}
else
{
hijos[i] = null;
podados++;
}
}
}
Console.WriteLine("Nodos Generados: {0}", generados);
Console.WriteLine("Nodos Analizados: {0}", analizados);
Console.WriteLine("Nodos Podados: {0}", podados);
if (solucion[0] != 0)
{
for (int i = 0; i < n; i++)
Console.WriteLine(solucion[i]);
}
else Console.WriteLine("No hay solucion");
Console.Read();
}
}
}

Vous aimerez peut-être aussi