quarta-feira, 18 de fevereiro de 2009

Dijkstra Shortest Path (Menor Caminho) em Java

Resolvi colocar uma implementação em Java do famoso algoritmo de Dijkstra para a solução do problema do menor caminho em um grafo. Lembrando que as arestas necessitam de um valor de peso positivo, caso contrário o algoritmo funcionará incorretamente (procure pelo algoritmo de Bellman-Ford para esse caso).

O código utiliza a biblioteca JUNG2 (atualmente na versão beta), e mais duas classes próprias (Vertice e Aresta), bem simples. A biblioteca é utilizada apenas para receber um Graph, do tipo Vertice, Aresta.
O objetivo é mostrar a implementação do algoritmo, pois o JUNG2 já possui a implementação, basta usar a classe DijkstraShortestPath.

Para usar a classe, intancie fazendo Dijkstra dijkstra = new Dijkstra(). Em seguida, use o método dijkstra.getMenorCaminho(grafo, verticeOrigem, verticeDestino);
  • Crie um pacote chamado "modelo" e coloque as classes a seguir:
Classe Vertice
package modelo;


public class Vertice {
private String nome;
private boolean flagOrigemDestino = false;
public Vertice(){
this.nome = "v";
}
public Vertice(String nome){
this.nome = nome;
}
public String getNome() {
return nome;
}

public void setNome(String nome) {
this.nome = nome;
}
public boolean isFlagOrigemDestino() {
return flagOrigemDestino;
}
public void setFlagOrigemDestino(boolean flagOrigemDestino) {
this.flagOrigemDestino = flagOrigemDestino;
}
@Override
public String toString() {
return nome;
}

@Override
public boolean equals(Object obj) {
return ((Vertice)obj).getNome().equalsIgnoreCase(this.nome);
}

}

Classe Aresta
package modelo;

public class Aresta {
private int peso = 0;
private boolean flagCaminho = false;

public Aresta(int peso){
this.peso = peso;
}
public int getPeso() {
return peso;
}

public void setPeso(int peso) {
this.peso = peso;
}

public boolean isFlagCaminho() {
return flagCaminho;
}

public void setFlagCaminho(boolean flagCaminho) {
this.flagCaminho = flagCaminho;
}

@Override
public String toString() {
return String.valueOf(peso);
}
}

  • Crie um pacote chamado "dijkstra" e coloque a classe a seguir:
Classe Dijkstra
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.PriorityQueue;

import modelo.Aresta;
import modelo.Vertice;
import edu.uci.ics.jung.graph.Graph;

public class Dijkstra {
private final Comparator comparatorDistancia = new Comparator() {
public int compare(Vertice v1, Vertice v2) {
int distV1 = distancias.get(v1);
int distV2 = distancias.get(v2);

if (distV1 > distV2)
return +1;
else if (distV1 <>
return -1;
else
return 0;
}
};

private HashSet nosFechados = new HashSet(); // nós resolvidos
private PriorityQueue nosAbertos = new PriorityQueue(10,comparatorDistancia);// nós nao calculados
private HashMap distancias = new HashMap();// distancia, vertice
private HashMap antecessores = new HashMap();// vertice, vertice antecessor

public List getMenorCaminho(Graph g,
Vertice origem, Vertice destino) {
// reseta estruturas
nosFechados.clear();
nosAbertos.clear();
distancias.clear();
antecessores.clear();

distancias.put(origem, 0);
nosAbertos.add(origem);
for(Vertice v : g.getVertices())
distancias.put(v, Integer.MAX_VALUE);

// enquanto houver vertices na nuvem
while (!nosAbertos.isEmpty()) {

Vertice u = nosAbertos.poll(); // pega vertice de menor distancia
if (nosFechados.contains(u)) // se vertice ja foi calculado, continuar
continue;
if (u == destino) // chegamos ao destino, parar
break;

nosFechados.add(u); // vertice calculado
// atualizar distancias e caminho
for (Vertice v : g.getNeighbors(u)) {
if (nosFechados.contains(v))
continue;

Aresta arestaUV = g.findEdge(u, v); // pega aresta entre u e v
int dist = distancias.get(u) + arestaUV.getPeso();
if (dist <>
// atualiza distancia de v
distancias.put(v, dist);
// setPai
antecessores.put(v, u);
// adiciona a nuvem
nosAbertos.add(v);
}
}
}
// compõe menor caminho
LinkedList menorCaminho = new LinkedList();
Aresta a;
Vertice u;
Vertice v = destino;
while( (u = antecessores.get(v)) != null){ 
a = g.findEdge(v, u);
v = u;
menorCaminho.add(a);
}
Collections.reverse(menorCaminho);
return menorCaminho;
}
}

quinta-feira, 8 de março de 2007

Mais dicas Firefox!

Bom dia!
Primeiramente, quero desejar a todas as mulheres um Feliz Dia Internacional das Mulheres!

Bom, tenho um amigo que é fã do Opera. Eu também gostei do Opera e cheguei a usar um tempo. Ele é um ótimo navegador, é muito leve, tem um visual bonito e possui inúmeros recursos, como zoom no site inteiro por porcentagem (inclusive zoom nas figuras do site), bloqueador de conteúdos (não é o de janela, apesar dele também ter). Esses recursos não existem no Firefox por padrão, normalmente é necessário baixar um plugin... Mas o que me fez desistir do Opera foram alguns bugs do navegador e alguns sites que são exibidos de forma estranha (talvez não por culpa do navegador... porque ele é extremamente rigoroso aos padrões da web - CSS/W3C).

Mas a dica de hoje é a seguinte: Você sabia que é possível abrir a última aba fechada no Firefox? Provavelmente disso você já sabia. O que talvez não sabia era a tecla de atalho, não muito intuitiva: CTRL+SHIFT+T (Firefox). No Opera, a tecla é CTRL+Z (no Firefox isso desfaz um texto/letra digitada num campo).

Outra dica, que é algo que já vem configurado no Opera por padrão, é a possibilidade de ao abrir o navegador ele iniciar com as últimas abas que você visitou. No Firefox isso também é possível, basta configurar:

  1. Menu Ferramentas
  2. Opções
  3. Aba Principal
  4. Seção "Iniciar"
  5. "Ao Iniciar Firefox" escolha "Abrir janelas e abas da última sessão"
Abraços!

terça-feira, 27 de fevereiro de 2007

Software Livre até na Pirataria!

Incrível, tive que vir postar isso. Olha só:

Fizeram um modchip (modificação de chip) para o Wii, vídeo game de 3ª geração da Nintendo que é open-source (código aberto). O modchip é para permitir que a leitora consiga ler DVDs gravados (vulgos piratas ou alternativos).
O melhor é que o modchip foi liberado com o código-fonte, incluindo todo o esquema do chip, caso alguem queira fazer em casa. O nome do modchip é Wiip. Custará cerca de 20 dólares.

A grande vantagem disso é que se eles descontinuarem o modchip (pararem de atualizar), outras pessoas poderão fazê-lo. Essa é apenas uma das vantagens que o software livre proporciona!

Site oficial: http://www.tcniso.net/Nav/Wiip/

Falows!

Status Bar do FireFox

Quantas vezes você não já entrou num site em que a barra de status (status bar) é toda animada, com textos vindo pra cá e pra lá... ;P
Pois é, apesar de ser fútil, muitos usuários gostam. E o Firefox, creio eu por questões de proteção/segurança, por padrão desabilita a possibilidade de modificar o texto da status bar.

Resolvi escrever esse post pois outro dia estava fazendo uns testes com javascript, e um dele foi justamente modificar o texto da status bar. Como uso Firefox, logo vi que não funcionou. Imediatamente fui ao Internet Explorer testar também, para saber se era problema no código: funcionou.
Como eu achava que o código estava bem limpo e nos padrões, achei que era algo do Firefox, só não sabia o quê. Googlei, e bingo! Basta configurar...

Segue a configuração para habilitar:
1. Menu Ferramentas
2. Opções...
3. Aba Conteúdo
4. Botão Avançado da seção Javascript
5. Marque a opção "Modificar o texto da barra de status"

Pronto!
Abraços

sábado, 24 de fevereiro de 2007

O que é Ajax?

Bem, ultimamente tenho lido sobre Ajax. Calma, vou lhe dizer o que o Ajax NÃO é:
  • Detergente
  • Time Europeu
Então, Ajax é a sigla em inglês para "Asynchronous JavaScript And XML", ou em português, "JavaScript e XML Assíncrono". E o que isso significa? Que eu posso através de algum código pequeno em JavaScript fazer requisições HTTP ao servidor, sem ter que recarregar a página....

... não entendeu nada? Uns exemplos pra ficar mais claro: GMail usa Ajax, o novo Yahoo! Mail usa Ajax, Google Suggest usa Ajax (digite devagar).

Então, o que o Ajax tem de vantagem:
  • Como havia dito, possibilidade de fazer requisições ao servidor sem ter que sair da página atual;
  • Modificar o conteúdo da página em tempo real, assim que receber a resposta do servidor (por exemplo, clicar em um email e abrí-lo em uma aba).
  • Tornar a experiência web do usuário mais rica e interativa;
  • Tornar o ambiente Web mais próximo do ambiente Desktop;
Nem tudo são flores... desvantagens:
  • Por natureza perderá as ações de Voltar, Avançar e Favoritos do navegador (apesar de já existirem soluções para o problema);
  • O usuário pode não perceber as modificações na página;
  • Ficam atualizando as propagandas pelo site toda hora;
Essa foi a introdução ao Ajax! Num próximo post eu falarei, quem sabe, como fazer um primeiro exemplo bastante simples em Ajax!

Até!

sexta-feira, 16 de fevereiro de 2007

3D Graphics Engines (Motores Gráficos 3D)

Opa! Não tenho postado muito, até porque não quero colocar inutilidades aqui. Gosto de colocar apenas aquilo que é interessante para a comunidade. Como esse post de hoje, aos interessados principalmente em desenvolvimento de aplicações gráficas em três dimensões (normalmente jogos), vou deixar uma dica de um site que contém uma gama de engines gráficas 3D.

O site é: http://www.devmaster.net/engines/
Existem cerca de 250 engines cadastradas, dentre as mais variadas: licenças, linguagens de programação e recursos. A maiora é voltada para o desenvolvimento de jogos.

Uma que recomendo dar uma boa olhada é o OGRE (Oriented-Object Graphics Rendering Engine, Motor de Renderização Gráfica Orientado a Objeto). Além de ser open-source, tem boa documentação da API, possui uma comunidade ativa e muito prestativa, software em constante desenvolvimento, possui diversos tutoriais em páginas de wiki, e quer mais? O SDK é só 40MB!

Porém se quiser um bom ambiente de programação (produtivo e funcionando), será necessário: Windows, Microsoft Visual C++ 2005 Express (grátis - 400mb), Plataforma SDK da Microsoft (windows server 2003 - 400mb). Isso não é pra desanimar, não! Na verdade estou adiantando que é bem difícil e trabalhoso fazer funcionar a engine no Linux, por exemplo, usando uma IDE como o Code::Blocks.

É isso aí, bons downloads! :)

domingo, 11 de fevereiro de 2007

Lazarus Free Pascal


Outro dia estava procurando por um compilador pascal mais "polido", sem ser o velho e bom Turbo Pascal, famoso fundo de tela cor azul, e descobri um projeto open-source, que faz ou pelo menos tenta fazer o que o Delphi faz, com a vantagem de poder rodar tanto no Windows quanto no Linux.
A ferramenta chama-se "Lazarus Free Pascal", é baseada no compilador "Free Pascal", e você pode conferir mais sobre a ferramenta neste endereço: http://www.lazarus.freepascal.org/

Não cheguei a testar a ferramenta, mas a ferramenta demonstra ser uma boa alternativa livre à da Borland.

Até!

sábado, 10 de fevereiro de 2007

Primeiro blog :)

Ae galera... esse é meu primeiro blog. Sejam bem-vindos :D

O objetivo deste blog não é pessoal, ou seja, não irei falar da minha vida, muito menos da vida alheia! :P
Criei esse blog pra falar de tecnologia em geral, tecnologia da informação, computadores, internet, programação, curiosidades, etc. Tudo relacionado à era digital!

Sobre a URL do blog
Escolher um nome foi complicado... acabei escolhendo "retornanulo". Esse nome eu tirei de vicios de programação... pra ficar algo bem nerd, ou geek...
return null
(versao java/c++)

Àqueles que me conhecem pessoalmente, e quiserem fazer parte deste blog, para escrever posts sobre tecnologia, é só falar comigo que eu mando o convite!

Abraços