/** * El metodo se encarga de realizar la asignación Hibrida para depósitos con capacidad limitada * (Algoritmo 1). * * <p>Recibe por parámetro <code>DTDepositoVRP</code> donde contiene toda la información del * problema a resolver. * * <p>Retorna una colección de <code>DTAsignacion</code>. Cada <code>DTAsignacion</code> contiene * un deposito y una colección de clientes que estan asignados al deposito. * * @param d <code>DTDepositoVRP</code> donde contiene toda la información del problema a resolver. * @return Devuelve una colección de <code>DTAsignacion</code>.. */ public Collection<DTAsignacion> asignar(DTDepositoVRP d) { System.out.println("Asignar capacidad"); clientes = new ArrayList<ClienteCap2>(); depositos = new ArrayList<Deposito>(); enajenados = new ArrayList<Enajenado>(); Iterator<DTNodo> it = d.getNodos().iterator(); while (it.hasNext()) { DTNodo dt = it.next(); if (dt.getEsDesposito()) { Deposito dep = new Deposito(dt); depositos.add(dep); } } Iterator<DTNodo> it2 = d.getNodos().iterator(); while (it2.hasNext()) { DTNodo dt = it2.next(); if (!dt.getEsDesposito()) { ClienteCap2 cli = new ClienteCap2(dt); cli.setMu(calcularMu(cli, depositos)); clientes.add(cli); } } // Calculo los 2 clientes mas cercanos para cada cliente (precalculo para fase 2) Iterator<ClienteCap2> it3 = this.clientes.iterator(); while (it3.hasNext()) { ClienteCap2 cliente = it3.next(); cliente = addClientesMasCercanos(cliente); System.out.println( "Clientes mas cercanos" + cliente.getNodo().getId() + " y nodos " + cliente.getClieteMasCercano1().getNodo().getId() + " ," + cliente.getClieteMasCercano2().getNodo().getId()); } // Asigno los nodos por urgencia (fase 1). while (clientes.size() > 0) { TreeSet<ClienteCap2> tr = new TreeSet<ClienteCap2>(clientes); Iterator<ClienteCap2> itc = tr.iterator(); ClienteCap2 proximo = itc.next(); proximo .getMasCercano() .agregarCliente(proximo); // agrego el cliente en el deposito mas cercano. clientes.remove(proximo); Iterator<ClienteCap2> itcli = clientes.iterator(); while (itcli.hasNext()) { ClienteCap2 n = itcli.next(); n.setMu(calcularMu(n, depositos)); } } // agrego a lista si los 2 cliente + cercanos a cada cliente pertencen al mismo deposito // deposito (que no es el mismo que el deposito asignado para el cliente). // acaaaa int capacidadvehiculo = Integer.valueOf(d.getCAPACITY()); System.out.println("cap del vehiculo " + capacidadvehiculo); ArrayList<DTAsignacion> ar = null; int costomenor = 0; Iterator<Deposito> itdd = this.depositos.iterator(); while (itdd.hasNext()) { Deposito dep = itdd.next(); DTAsignacion dta = new DTAsignacion(dep.getNodo()); Iterator<Cliente> itcli = dep.getAsignados().iterator(); while (itcli.hasNext()) { Cliente cli = itcli.next(); dta.agregarCliente(cli.getNodo()); } Iterator<DTRuteo> itrut = Fabrica.getInstancia().getRuteo().rutear(dta, capacidadvehiculo).iterator(); while (itrut.hasNext()) { DTRuteo next = itrut.next(); costomenor = costomenor + next.getCosto(); } } System.out.println("costo inicial " + costomenor); int cantidadIteraciones = 0; // Inicializo el Tiempo en Config Config.getInstancia().empezarAlgoritmo(costomenor); ArrayList<Integer> aux, tmp; tmp = new ArrayList<Integer>(); boolean terminar = false; while (!terminar) { cantidadIteraciones++; System.out.println("Cantidad Iteraciones " + cantidadIteraciones); this.calcularEnagenamiento(); // Aplico todos los cambios de la lista de enajenados .... aux = new ArrayList<Integer>(); Iterator<Enajenado> itena = this.enajenados.iterator(); while (itena.hasNext()) { Enajenado ena = itena.next(); aux.add(ena.getCliente().getNodo().getId()); if (ena.getDepositoDestino().getCapacidadLibrePonderada() >= ena.getCliente().getNodo().getDemanda()) { Iterator<Deposito> respita = this.depositos.iterator(); while (respita.hasNext()) { Deposito dep = respita.next(); Deposito nuevo = new Deposito(dep); if (nuevo.getNodo().getId() == ena.getDeposito().getNodo().getId()) nuevo.sacarCliente(ena.getCliente()); if (nuevo.getNodo().getId() == ena.getDepositoDestino().getNodo().getId()) nuevo.agregarCliente(ena.getCliente()); DTAsignacion dta = new DTAsignacion(nuevo.getNodo()); Iterator<Cliente> itcli = nuevo.getAsignados().iterator(); while (itcli.hasNext()) { Cliente cli = itcli.next(); dta.agregarCliente(cli.getNodo()); } } ena.getDeposito().sacarCliente(ena.getCliente()); ena.getDepositoDestino().agregarCliente(ena.getCliente()); } } boolean equalLists = ((aux.size() == tmp.size()) && (tmp.containsAll(aux))); tmp = new ArrayList<Integer>(); tmp.addAll(aux); if ((Config.getInstancia().terminarPorConfig(cantidadIteraciones, costomenor)) || equalLists) terminar = true; } // construir DT de salida. ar = new ArrayList<DTAsignacion>(); Iterator<Deposito> itd = depositos.iterator(); while (itd.hasNext()) { Deposito dep = itd.next(); DTAsignacion dta = new DTAsignacion(dep.getNodo()); Iterator<Cliente> itcli = dep.getAsignados().iterator(); while (itcli.hasNext()) { Cliente cli = itcli.next(); dta.agregarCliente(cli.getNodo()); } ar.add(dta); } Penalization.getInstancia().getCalculoPenalidad(ar); return ar; }
/** Calcula los nodos que son enajendados. */ private void calcularEnagenamiento() { Iterator<Deposito> itd1 = depositos.iterator(); this.enajenados = new ArrayList<Enajenado>(); while (itd1.hasNext()) { Deposito dep1 = itd1.next(); Iterator<Cliente> itc1 = dep1.getAsignados().iterator(); while (itc1.hasNext()) { Cliente clientebase = itc1.next(); Iterator<Deposito> it4 = depositos.iterator(); while (it4.hasNext()) { boolean encontre1 = false; boolean encontre2 = false; Deposito dep2 = it4.next(); if (dep1.getNodo().getId() != dep2.getNodo().getId()) { Iterator<Cliente> it5 = dep2.getAsignados().iterator(); while (it5.hasNext()) { Cliente cliente = it5.next(); if (((ClienteCap2) clientebase).getClieteMasCercano1().getNodo().getId() == cliente.getNodo().getId()) encontre1 = true; if (((ClienteCap2) clientebase).getClieteMasCercano2().getNodo().getId() == cliente.getNodo().getId()) encontre2 = true; } if (encontre1 && encontre2) { this.enajenados.add(new Enajenado(((ClienteCap2) clientebase), dep1, dep2)); break; } } } } } // limpio lista de enegenados por la distancia al deposito. int distCaC1, distCaC2, distDep; Iterator<Enajenado> itena = this.enajenados.iterator(); ArrayList<Enajenado> asacar = new ArrayList<Enajenado>(); while (itena.hasNext()) { Enajenado ena = itena.next(); distCaC1 = Distancia.getInstancia() .getDistancia( ena.getCliente().getClieteMasCercano1().getNodo(), ena.getCliente().getNodo()); distCaC2 = Distancia.getInstancia() .getDistancia( ena.getCliente().getClieteMasCercano2().getNodo(), ena.getCliente().getNodo()); distDep = Distancia.getInstancia() .getDistancia(ena.getCliente().getNodo(), ena.getDeposito().getNodo()); System.out.println( "Clientes mas cercanos a " + ena.getCliente().getNodo().getId() + " ( " + ena.getDeposito().getNodo().getId() + " ). c 1 y c2 " + ena.getCliente().getClieteMasCercano1().getNodo().getId() + " ," + ena.getCliente().getClieteMasCercano2().getNodo().getId() + "(" + ena.getDepositoDestino().getNodo().getId() + ")"); if (distCaC1 + distCaC2 > distDep) asacar.add(ena); // this.enajenados.remove(ena); else ena.setMu(distDep - (distCaC1 + distCaC2)); } Iterator<Enajenado> itsacar = asacar.iterator(); while (itsacar.hasNext()) { this.enajenados.remove(itsacar.next()); } }
/** * Calcula el valor de <code>mu</code>. * * @param c Cliente. * @param dep Colección de depósitos. */ private int calcularMu(ClienteCap2 c, Collection<Deposito> dep) { /*Deposito masCercano=null; if(dep.size()>0) { masCercano=dep.iterator().next(); } else { return 0; } int distanciaMasCercano=Integer.MAX_VALUE; Iterator<Deposito> it=dep.iterator(); while(it.hasNext()) { Deposito n=it.next(); if(n.getCapacidadLibre()>=c.getNodo().getDemanda()) { if(Distancia.getInstancia().getDistancia(n.getNodo(), c.getNodo())<distanciaMasCercano) { masCercano=n; distanciaMasCercano=Distancia.getInstancia().getDistancia(n.getNodo(), c.getNodo()); } } } int sumatoriaDistancias=0; Iterator<Deposito> it2=dep.iterator(); while(it2.hasNext()) { Deposito n=it2.next(); if(n.getCapacidadLibre()>=c.getNodo().getDemanda()) { if(n.getNodo().getId()!=masCercano.getNodo().getId()) { sumatoriaDistancias=sumatoriaDistancias+Distancia.getInstancia().getDistancia(n.getNodo(),c.getNodo()); } } } c.setMasCercano(masCercano); return sumatoriaDistancias-distanciaMasCercano;*/ Deposito masCercano = null; int distanciaMasCercano = Integer.MAX_VALUE; Iterator<Deposito> it = dep.iterator(); while (it.hasNext()) { Deposito n = it.next(); if (n.getCapacidadLibre() >= c.getNodo().getDemanda()) { if (Distancia.getInstancia().getDistancia(n.getNodo(), c.getNodo()) < distanciaMasCercano) { masCercano = n; distanciaMasCercano = Distancia.getInstancia().getDistancia(n.getNodo(), c.getNodo()); } } } if (masCercano != null) { int sumatoriaDistancias = 0; Iterator<Deposito> it2 = dep.iterator(); while (it2.hasNext()) { Deposito n = it2.next(); if (n.getCapacidadLibre() >= c.getNodo().getDemanda()) { if (n.getNodo().getId() != masCercano.getNodo().getId()) { sumatoriaDistancias = sumatoriaDistancias + Distancia.getInstancia().getDistancia(n.getNodo(), c.getNodo()); } } } c.setMasCercano(masCercano); return sumatoriaDistancias - distanciaMasCercano; } else { int distanciaMasCercano2 = Integer.MAX_VALUE; Iterator<Deposito> it2 = dep.iterator(); while (it2.hasNext()) { Deposito n = it2.next(); if (Distancia.getInstancia().getDistancia(n.getNodo(), c.getNodo()) < distanciaMasCercano2) { masCercano = n; distanciaMasCercano2 = Distancia.getInstancia().getDistancia(n.getNodo(), c.getNodo()); } } c.setMasCercano(masCercano); return 0; } }
/** M�todo principal */ public static void main(String[] args) { // faz o parsing dos argumentos da linha de comnaod GetOpt options = new GetOpt("Projeto3", args, "vr"); int opt; while ((opt = options.nextOpt()) != -1) { switch (opt) { default: uso(); break; case 'v': verbose = true; break; case 'r': rand = new Random(0); break; } } if (rand == null) { rand = new Random(); } if (options.optind != args.length - 3) { uso(); } int algoritmo = Integer.parseInt(args[options.optind + 0]); alambiqueN = Integer.parseInt(args[options.optind + 1]); int iteracoes = Integer.parseInt(args[options.optind + 2]); // Cria o dep�sito deposito = new Deposito(algoritmo); Thread dthread = new Thread(deposito, "Deposito"); // Cria o fornecedor fornecedor = new Fornecedor(iteracoes); Thread fThread = new Thread(fornecedor, "Fornecedor"); // Cria os alambiques alambiques = new Alambique[alambiqueN]; alambiqueThreads = new Thread[alambiqueN]; for (int i = 0; i < alambiqueN; i++) { alambiques[i] = new Alambique(i); alambiqueThreads[i] = new Thread(alambiques[i], "Alambique" + i); } // Inicia os threads dthread.setPriority(Thread.NORM_PRIORITY - 1); dthread.start(); fThread.setPriority(Thread.NORM_PRIORITY - 1); fThread.start(); for (Thread t : alambiqueThreads) { t.setPriority(Thread.NORM_PRIORITY - 1); t.start(); } // Espera at� que todos os threads sejam encerrados try { // O thread do fornecedor se encerra quando ele completa todas as itera��es fThread.join(); // Aguarda 3 segundos para dar chance a todos de terminarem o que est�o fazendo, // em seguida todos s�o interrompidos Thread.sleep(3000); // Mata o thread do dep�sito dthread.interrupt(); dthread.join(); // Mata os alambiques for (Thread t : alambiqueThreads) { t.interrupt(); t.join(); } } catch (InterruptedException e) { e.printStackTrace(); } // imprime o estado final out.printf("**** Programa terminando%n"); Pedido quant; Pedido balanco = new Pedido(); int produzido = 0; int noDeposito = 0; int consumido = 0; quant = fornecedor.getProducao(); out.printf("Produzido %s%n", quant); balanco.troca(quant); produzido += quant.total(); quant = deposito.getDisponivel(); for (Cana c1 : Cana.values()) { int n = quant.get(c1); balanco.troca(c1, -n); noDeposito += n; } Pedido totalConsumido = new Pedido(); int totalRequisitado = 0; int totalEspera = 0; for (int i = 0; i < alambiqueN; i++) { quant = alambiques[i].getConsumo(); int requisitado = alambiques[i].requisicoesConcluidas(); int espera = alambiques[i].tempoDeEspera(); totalConsumido.troca(quant); for (Cana g : Cana.values()) { int n = quant.get(g); balanco.troca(g, -n); consumido += n; } out.printf("Alabique %d%n", i); out.printf(" Cana consumida: %s%n", quant); out.printf(" Requisi��es atendidas: %d%n", requisitado); out.printf(" Tempo total de espera: %d ms%n", espera); if (requisitado > 0) { out.printf(" Tempo de espera m�dio: %.2f ms%n", espera / (double) requisitado); } totalRequisitado += requisitado; totalEspera += espera; } out.printf("Balan�o (deficit) � %s%n", balanco); out.printf( "Total: produzido = %d, consumido = %d," + " restando no dep�sito = %d, l�quido = %d%n", produzido, consumido, noDeposito, (produzido - consumido - noDeposito)); out.printf( "Requisi��es conclu�das: %d, tempo de espera m�dio %.2fms%n", totalRequisitado, totalEspera / (double) totalRequisitado); }