Publicações arquivadas sob Tecnologia

Eclipse Galileo pulando breakpoints

Estou usando o Eclipse Galileo no trabalho para programar em Java e de repente, no modo de Debug, nenhum breakpoint é respeitado: todos passam direto.

Procurei um pouco na net e descobri que é um problema do JDK 1.6.0.14.

Usem outra versão -> A 1.6.0.16 corrige esse problema.

Fonte

Adicionar comentário 13 de Agosto de 2009 às 14:52 Thiago

8 Puzzle - Parte 2

Ontem fiz um programa para resolver o 8 puzzle. Testei em casa com o puzzle presente no jogo Professor Layton e para minha tristeza o programa era lento demais. Deixei ligado por vários minutos e a resposta não apareceu. Logicamente precisava aumentar a performance e a maneira mais óbvia era trocar o algoritmo de busca, já que a busca em largura, apesar de dar a resposta correta, é muito lenta.

Dito isto, troquei para o algoritmo A*, que é o super bambambam dos algoritmos de busca. Para implementar este algoritmo, preciso de uma fila de prioridade e felizmente a biblioteca de Python já possui uma implementação no módulo heapq. Também é preciso associar um custo com cada configuração do tabuleiro e fiz da seguinte forma: o custo de um configuração é a soma da quantidade de movimentos até chegar nela mais a soma das distâncias Manhattan de cada quadrado até sua posição na configuração final. Usei uma matriz bacana para armazenar fácil essas distâncias, hehe!

Por fim, rodei o programa e dentro de poucos minutos ele deu uma resposta. Testei e a resposta está correta. Até que enfim resolvi esse puzzle terrível! O código está abaixo.

Yesterday I wrote a program to solve the 8 puzzle, but my implementation was too slow. I changed the search algorithm to A* and everyting worked just fine. I finally got through that pesky puzzle in the game.


"""
This is a solver for the 8 sliders puzzle.

A state is a snapshot of the game board. It is represented by a list of
9 items, eg. [0,1,2,3,4,5,6,7,8]. The positions in the list map to the
following positions on the board:
        0 1 2
        3 4 5
        6 7 8
We assume the square labelled 0 is the empty square. It is possible
to have more of the same number on the board.
"""

# A Priority Queue implementation
import heapq

""" The allowed moves in the game. For example, 0:[1,3] means that
a square in position zero can be swapped with the square in position one
or the square in position three.
"""
SWAPS = {0:[1,3],
         1:[0,2,4],
         2:[1,5],
         3:[0,4,6],
         4:[1,3,5,7],
         5:[2,4,8],
         6:[3,7],
         7:[4,6,8],
         8:[5,7]}

def solve_eight_puzzle(begin, goal):
    distance = calculate_distance(goal)
    openlist = []
    heapq.heappush(openlist, package_cost(begin, 0, distance))
    closedlist = []
    previous = {begin:None}
    while len(openlist) > 0:
        print len(openlist),
        cost, state = heapq.heappop(openlist)
        closedlist.append(state)
        if state == goal:
            s = goal
            path = []
            while previous[s] is not None:
                path.append(s)
                s = previous[s]
            path.append(s)
            path.reverse()
            return path
        nextstates = [s for s in possible_moves(state) if s not in closedlist]
        for next in nextstates:
            previous[next] = state
            heapq.heappush(openlist, package_cost(next, cost + 1, distance))
    return None

def package_cost(state, path_length, distance):
    cost = path_length
    for i in range(9):
        cost += distance[state[i]][i]
    return (cost, state)

def possible_moves(state):
    izero = index_of_zero(state)
    swaps = SWAPS[izero]
    new_states = []
    for swap in swaps:
        new_state = list(state)
        new_state[izero] = state[swap]
        new_state[swap] = state[izero]
        new_states.append(tuple(new_state))
    return new_states

def instructions(state_list):
    answer = []
    previous = None
    for state in state_list:
        if previous is not None:
            izero1 = index_of_zero(previous)
            izero2 = index_of_zero(state)
            if izero1 / 3 < izero2 / 3:
                # zero went down
                inst = "move a piece up"
            elif izero1 / 3 == izero2 / 3:
                if izero1 < izero2:
                    # zero  went right
                    inst = "move a piece left"
                else:
                    #zero went left
                    inst = "move a piece right"
            elif izero1 / 3 > izero2 / 3:
                # zero went up
                inst = “move a piece down”
            answer.append(inst)
        previous = state
    return answer            

def index_of_zero(tup):
    i = 0
    while i < 9:
        if tup[i] == 0:
            return i
        i += 1
    print "Mega error: there is no ZERO in", tup

def calculate_distance(goal):
    distance = {}
    distance[goal[0]] = [0, 1, 2, 1, 2, 3, 2, 3, 4]
    distance[goal[1]] = [1, 0, 1, 2, 1, 2, 3, 2, 3]
    distance[goal[2]] = [2, 1, 0, 3, 2, 1, 4, 3, 2]
    distance[goal[3]] = [1, 2, 3, 0, 1, 2, 1, 2, 3]
    distance[goal[4]] = [2, 1, 2, 1, 0, 1, 2, 1, 2]
    distance[goal[5]] = [3, 2, 1, 2, 1, 0, 3, 2, 1]
    distance[goal[6]] = [2, 3, 4, 1, 2, 3, 0, 1, 2]
    distance[goal[7]] = [3, 2, 3, 2, 1, 2, 1, 0, 1]
    distance[goal[8]] = [4, 3, 2, 3, 2, 1, 2, 1, 0]
    return distance 

# Test
i = 1
print
for inst in instructions(solve_eight_puzzle((1,2,3,4,5,6,7,0,1),(1,2,3,4,0,7,6,5,1))):
    print i, inst
    i += 1
raw_input()

Adicionar comentário 18 de Fevereiro de 2009 às 12:29 Thiago

8 Puzzle

O problema 8 puzzle é um quebra cabeça em que temos um tabuleiro 3 por 3 com 8 quadrados deslizantes e um espaço em branco. Dada uma posição inicial dos quadrados, pede-se para chegar em uma outra posição qualquer considerando que:

  • Os quadrados podem ser deslizados para ocuparem a posição previamente em branco.
  • Movimentos diagonais são proibidos.
  • As peças só podem ser deslizadas, isto é, não pode-se tirá-las do tabuleiro.

Estava jogando o ótimo Professor Layton and the Curious Village quando emperrei num dos puzzles, que é um 8 puzzle (Puzzle 107: A Worm’s Dream). Depois de milhares de movimentos, desisti e resolvi escrever um programa para resolver o problema para mim, hehe. Apresento a solução abaixo, escrita em Python 2.5.

Adotei a abordagem mais simples, é uma busca em largura sem heurística no grafo onde os vértices são as diversas configurações do tabuleiro. Primeiro implementei a busca como uma função recursiva, mas estava estourando a pilha (Stack Overflow) então reescrevi a função de forma iterativa.

Conseguem ver como ela funciona? O que pode ser feito para melhorar a performance? :)

Alguém tem uma idéia melhor para como armazenar a seqüência de movimentos que o jogador tem que fazer?


This Python 2.5 program solves the 8 puzzle. It uses a simple breadth first search algorithm in a graph where the vertices are game board snapshots.

Can you see how it works? How can the performance be improved? Does someone have a better idea of how the answer should be stored or presented?


"""
This is a solver for the 8 sliders puzzle.

A state is a snapshot of the game board. It is represented by a list of
9 items, eg. [0,1,2,3,4,5,6,7,8]. The positions in the list map to the
following positions on the board:
        0 1 2
        3 4 5
        6 7 8
We assume the square labelled 0 is the empty square. It is possible
to have more of the same number on the board.
"""

""" The allowed moves in the game. For example, 0:[1,3] means that
a square in position zero can be swapped with the square in position one
or the square in position three.
"""
SWAPS = {0:[1,3],
         1:[0,2,4],
         2:[1,5],
         3:[0,4,6],
         4:[1,3,5,7],
         5:[2,4,8],
         6:[3,7],
         7:[4,6,8],
         8:[5,7]}

def solve_eight_puzzle(begin, goal):
    openlist = [begin]
    closedlist = []
    previous = {tuple(begin):None}
    while len(openlist) > 0:
        state = openlist.pop(0)
        closedlist.append(state)
        if state == goal:
            s = tuple(goal)
            path = []
            while previous[s] is not None:
                path.append(s)
                s = previous[s]
            path.append(s)
            path.reverse()
            return path
        nextstates = [s for s in possible_moves(state) if s not in closedlist]
        for next in nextstates:
            previous[tuple(next)] = tuple(state)
        openlist.extend(nextstates)
    return None

def possible_moves(state):
    izero = state.index(0)
    swaps = SWAPS[izero]
    new_states = []
    for swap in swaps:
        new_state = state[:]
        new_state[izero] = state[swap]
        new_state[swap] = state[izero]
        new_states.append(new_state)
    return new_states

# Test
print solve_eight_puzzle([0,1,3,4,2,5,7,8,6],[1,2,3,4,5,6,7,8,0])

Adicionar comentário 17 de Fevereiro de 2009 às 17:27 Thiago

Requisitos mínimos do sistema

Hoje eu recebi a tarefa de enviar para o cliente do projeto em que trabalho os requisitos mínimos para rodar a aplicação desktop que desenvolvi. Como nunca havia feito isso antes, fiquei em dúvida sobre como proceder para determinar esses requisitos. Acabei coletando os requisitos mínimos para rodar a versão de Java que uso no desenvolvimento da aplicação (1.4.2) e os incrementei um pouco. De qualquer forma, ficou a dúvida: existe uma metodologia para determinar os requisitos mínimos de uma aplicação?

1 comentário 5 de Agosto de 2008 às 10:45 Matheus

Arredondamento em Java

Curioso código em Java que encontrei num programa no trabalho.
Sabendo que DeltaY é um int, explique porque:
1) O código funciona
2) O autor fez isso

BAD WAY
int Diametro = Math.round(Math.round(0.9*DeltaY));

GOOD WAY
int Diametro = Math.round(0.9f*DeltaY);

Adicionar comentário 15 de Fevereiro de 2008 às 14:59 Thiago

Copiando arquivos em Java

Um código simples que usei para copiar um arquivo (na verdade, uso para copiar de um InputStream para um OutputStream):

InputStream in = (...)
OutputStream out = (...)
for (int b = in.read(); b != -1; out.write(b), b = in.read());

5 comentários 17 de Setembro de 2007 às 13:48 Thiago

Quines

Quines são programas que imprimem o seu próprio código fonte.
Sempre quis escrever um e finalmente o fiz, em Python.
O código está a seguir. Alguém mais quer tentar?

a = """a = UIA
c = chr(34) * 3
print a.replace("UIA", (c + a + c), 1)"""
c = chr(34) * 3
print a.replace("UIA", (c + a + c), 1)

Pelo menos em Python, usando a biblioteca, fica fácil.

Adicionar comentário 6 de Setembro de 2007 às 09:11 Thiago

Complexo Nacional

Gente, não sei se estão sabendo da lei do Simples Nacional. Os sistemas são desenvolvidos aqui no Serpro, mas os prazos legais para construção deles são absurdos!!!

Veja semana passada: meu chefe abriu um projeto na quarta-feira que teria que estar pronto na sexta. Incluindo tudo que se espera de um estabelecimento certificado CMMI2: requisitos, implementação, testes, homologação e implantação.

Hoje foi pior.

Meu chefe acabou de abrir um projeto devido a uma resolução do comitê que coordena o Simples Nacional. Que foi feita ontem. E que deve ser implantada hoje.

Acabei de fazer os requisitos e estamos mandando para aprovação. Ainda temos que implementar, testar, homologar e implantar hoje ainda. HOJE!

Tá uma correria aqui…

Adicionar comentário 31 de Julho de 2007 às 11:16 Thiago

Pacote nômade

Todo programador sabe (ou deveria saber) o trabalho que dá manter um programa compatível. Compatível consigo mesmo, com as versões anteriores, com as diversas máquinas dos usuários, com a decisão tomada apressadamente há 10 anos atrás por alguém que nem faz parte da equipe mais. Ao trabalhar aqui no Serpro dá para ter um gostinho do que o pessoal da Microsoft passa.

Bom, hoje a questão é o XPath. Um programa nosso funcionou na máquina de um colega meu, mas não na minha. O Eclipse não conseguiu encontrar um pacote. A diferença entre nossas configurações é que ele usa a JRE 5.0 e eu a 1.4 para implementar. O problema é: o pacote onde estão as classes do XPath é diferente no Java 1.4 e no 5.0.

Como o código tem que rodar nessas duas versões da máquina virtual, a saída que arranjei foi carregar as classes por reflexão. Isto é: tente com um nome de pacote e se não der, use o outro.

Bom, pelo menos não tenho mais que programar para OS/2. :)

Adicionar comentário 5 de Junho de 2007 às 18:12 Thiago

Java GPL

Mais informações aqui.

Adicionar comentário 11 de Maio de 2007 às 10:06 Thiago

Publicações anteriores


Calendário

Setembro 2010
S T Q Q S S D
« Dez    
 12345
6789101112
13141516171819
20212223242526
27282930  

Minhas Publicações Recentes

Publicações por Mês

Estatísticas

Meta