Git Product home page Git Product logo

cc76tp20182's Introduction

CC76TP20182

Trabajo parcial para el curso de Complejidad Algorítmica. UPC - Universidad Peruana de Ciencias Aplicadas

Integrantes:

  • Manuel Alvarado Estanga
  • Luis Angel Bernal

Introducción

A lo largo de la existencia de las computadoras, se ha considerado a estas como herramientas de las cuales nos podemos valer para facilitar nuestras actividades. Así, se ha pensado que las computadoras nos pueden ayudar a resolver todos nuestros problemas y que poseen más poder para procesar datos que nosotros. Es raro pensar en que las computadoras poseen limites en sus facultades de cálculo, ya que muy pocas veces nos encontramos ante tales limites; de hecho, probablemente el usuario promedio no tenga que lidiar nunca en su vida con ningún problema que requiera llevar el poder de procesamiento de la computadora hasta casi el límite. Pese a esto, hasta el día de hoy existen ciertos problemas que no han podido ser resueltos ni con la ayuda de las computadoras, esto se debe a que quizás si se pueda encontrar una respuesta, pero el tiempo que le llevaría a las computadoras darnos el resultado podría ser de hasta millones de años.

P vs NP

Por esta razón se plantea el problema P vs. NP; este problema es considerado como uno de los tantos problemas del millón de dólares. Este problema consiste en comprobar que los problemas NP pueden ser resueltos de igual forma que los polinómicos(P) aplicando diversos conceptos que permitan facilitar el proceso de resolución. Este problema trata de aclarar que problemas pueden resolverse con la ayuda de la computadora y cuales no, para de esta forma determinar si la resolución de dichos problemas se hallará relacionada a la creación de equipos más con más potencia de análisis.

  • P: Las soluciones pueden ser calculadas en un tiempo razonable
  • NP: Las soluciones son muy dificiles de encontrar, pero son fáciles de comprobar

El reto es demostrar que P = NP o lo contrario; es decir, mientras no se pruebe que son diferentes podrían existir atajos que permitan resolver un problema de clase NP como uno de complejidad P. Demostrar que P = NP tendría grandes impactos en la criptografía moderna y haría vulnerables a todos los sistemas a nivel mundial en el caso que sea cierto.

Gráfico P vs NP

Fuente: Quora - Does P ! = NP mean that no problem exists which can be solved and checked in polynomial time?

TSP - Travelling Salesman Problem

Entre estos problemas de complejidad NP, se encuentra el problema del vendedor viajero (TSP, por sus siglas en ingles). Dada una colección de ciudades y las distancias entre sus conexiones (costo), el problema consiste en encontrar un camino que recorra todas las ciudades una única vez y regrese al punto inicial con la menor distancia posible. enter image description here

Fuente: Wikipedia - Travelling salesman problem

Objetivos

  • Desarrollar la competencia general de razonamiento cuantitativo y la competencia específica de uso de técnicas y herramientas acorde a los objetivos del curso.
  • Desarrollar un algoritmo que permita resolver completa o parcialmente el problema del vendedor viajero.
  • Establecer relaciones entre problemas de la vida diaria y problemas computacionales.
  • Determinar la importancia de la aplicación de algoritmos eficientes a la hora de resolver un problema.
  • Analizar la eficiencia y complejidad de los algoritmos planteados.

Marco Teórico

Búsqueda en grafos

Búsqueda por amplitud - BFS

Este algoritmo de búsqueda consiste en recorrer los vértices de un grafo de izquierda a derecha; es decir, en lugar de recorrer una rama hacia abajo como lo hace la búsqueda por profundidad (DFS), recorre todos los nodos que se encuentran en el mismo nivel. Una posible implementación del algoritmo es la siguiente:

def  bfs(grafo,inicio,meta):
	cola = [(inicio,[inicio])]
	visitados =  set()
	while  len(cola) >  0:
		nodo,camino = cola.pop(0)
		if nodo not  in visitados:
			visitados.add(nodo)
		for vecino in grafo.vecinos(nodo):
			if vecino == meta:
				return camino + [vecino]
			else:
				if vecino not  in visitados:
					visitados.add(vecino)
					cola.append((vecino,camino+[vecino]))
	return  None

Fuente: Hacker Earth - Breadth First Search

Búsqueda por costo uniforme - UCS

Este algoritmo de búsqueda trabaja con grafos ponderados o con pesos. En este tipo de grafos cada vértice tiene un peso y se define el costo de la arista como la distancia entre los vértices conectados. La búsqueda se realiza a partir de un punto inicial y recorre los vértices más cercanos, de tal manera que se va acumulando el costo total. Esta estrategia utiliza una cola de prioridades (Priority Queue) la cual ordena los vértices y sus respectivos costos en pares (v,c) dentro de una colección del tipo LIFO. Este tipo de colas ubica los elementos de forma ordenada según la prioridad; es decir, los elementos con menor costo estarán ubicados al final y van a ser los primeros en salir. Una posible implementación del algoritmo es la siguiente:

    def  ucs(grafo,inicio, meta):
	    visitados =  set()
	    cola = PriorityQueue()
	    cola.put((0,inicio,[inicio]))
	    while cola:
		    costo,nodo,camino = cola.get()
		    if nodo not  in visitados:
			    visitados.add(nodo)
		    for vecino in grafo.vecinos(nodo):
			    costo_total = costo + grafo.getPeso(nodo,vecino)
			    camino_total = camino + [vecino]
			    if vecino == meta:
				    return (costo_total,camino_total)
				else:
				    if vecino not  in visitados:
					    visitados.add(vecino)
					    cola.put((costo_total,vecino,camino_total))
	    return (None,None)

Fuente: Artificial Intelligence – Uniform Cost Search (UCS)

Análisis de la complejidad algorítmica

Análisis de tiempo para los algoritmos de búsqueda por anchura (BFS):

O(V+E)

Donde: V: Número de vértices en la cola

E: Número de aristas incidentes en cada vértice

Esto es de acuerdo a la estructura del grafo, en este caso se utilizará una lista de adyacencia (n + m). En una matriz de adyacencia sería n^2

Estrategia 1: UCS

Con esta estrategia buscamos encontrar los caminos más cortos desde un punto aleatorio del mapa. El camino (path) debe terminar en el mismo punto de partida para considerarlo como posible solución.

def ucs(grafo,inicio, meta):
	visitados = set()
	cola = PriorityQueue()
	cola.put((0,inicio,[inicio]))
	while cola:
		costo,nodo,camino = cola.get()
		if nodo not in visitados:
			visitados.add(nodo)
		for vecino in grafo.vecinos(nodo):
			costo_total = costo + grafo.getPeso(nodo,vecino)
			camino_total = camino + [vecino]
			if vecino == meta:
				return (costo_total,camino_total)
			else:
				if vecino not in visitados:
					visitados.add(vecino)
					cola.put((costo_total,vecino,camino_total))
	return (None,None)
def generarCaminos(diccionario,grafo):
	n = len(diccionario)
	codigos = list(diccionario)
	colores = ['b','c','m','y','w']
	print("Generando caminos con UCS")
	for i in range(4):
		indiceCP = randint(0,n-1)
		codigo = codigos[indiceCP]
		costo,camino = ucs(grafo,codigo,codigo) #inicia y termina en la misma ciudad (codigo inicio y fin)
		nCoord = len(camino)
		x1 = [0]*nCoord
		y1 = [0]*nCoord
		if costo and camino:
			j = 0
			for codigoCP in camino:
				x1[j] = diccionario[codigoCP].coordX
				y1[j] = diccionario[codigoCP].coordY
				nombreCP = diccionario[codigoCP].nombre
				plt.text(x1[j], y1[j], nombreCP, family="sans-serif", color=colores[i])
				j+=1
				plt.text(x1[0], y1[0] + 0.5, str(round(costo,2)), family="sans-serif", color=colores[i])
				plt.plot(x1,y1,color=colores[i],marker="8",markerEdgeColor="black")
		else:
			continue
generarCaminos(d,grafo)
plt.show()

Obtenemos como resultado los siguientes caminos: Estrategia 1

Estrategia 2: BFS

Usamos BFS para una muestra pequeña de todos los centros poblados. El objetivo será buscar todos los caminos posibles con combinatoria de 2 sobre n, es decir tomamos dos puntos cualquiera del grafo para generar caminos. Para ello utilizaremos backtracking. Si el camino recorre todos los nodos entonces cumple con una de las condiciones del problema TSP.

def bfs(grafo,inicio,meta):
	cola = [(inicio,[inicio])]
	visitados = set()
	while len(cola) > 0:
		nodo,camino = cola.pop(0)
		if nodo not in visitados:
			visitados.add(nodo)
		for vecino in grafo.vecinos(nodo):
			if vecino == meta:
				return camino + [vecino]
			else:
				if vecino not in visitados:
					visitados.add(vecino)
					cola.append((vecino,camino+[vecino]))
	return None

Backtracking:

#solucion = [inicio,fin]
def buscarCaminos(grafo,codigos,solucion,etapa,caminos):
	n = len(solucion)
	numCentrosPoblados = len(codigos)
	if etapa > n: #No hay solución
		return
	i = 0
	while True:
		solucion[etapa] = codigos[i]
		if etapa == n-1:
			camino = bfs(grafo,solucion[0],solucion[1])
			#Validar si ha recorrido todos los nodos del grafo (codigos)
			if camino:
				caminos.append(camino)
		else:
			buscarCaminos(grafo,codigos,solucion,etapa+1,caminos)
		i+=1
		if i == numCentrosPoblados:
			break

Validamos si el camino recorre todos los nodos:

def generarCaminos(diccionario,grafo):
	codigos = list(diccionario)
	colores = ['r','b','c','m','y','w']
	print("Generando caminos con BFS")
	caminos = []
	solucion = [None]*2 # [inicio,final]
	buscarCaminos(grafo,codigos,solucion,0,caminos)
	for c in caminos:
		n = len(c)
		x = [0]*n
		y = [0]*n
		colorC = colores[0]
		encontrado = False
		#Valida si el camino recorre todos los nodos
		#Lo pinta de otro color
		if collections.Counter(c) == collections.Counter(codigos):
			colorC = colores[1]
			encontrado = True
	j = 0
	for codigoCP in c:
		x[j] = diccionario[codigoCP].coordX
		y[j] = diccionario[codigoCP].coordY
		plt.text(x[j], y[j], diccionario[codigoCP].nombre, family="sans-serif", color=colores[2])
		j+=1
	plt.plot(x,y,color=colorC,marker="8",markerEdgeColor="black")
	if encontrado:
		break

Resultado: enter image description here

Conclusiones

  • Se ha resuelto por partes el problema dado. Mediante la primera estrategia se ha logrado encontrar el camino más corto que retorne al punto de partida, mientras que con la segunda estrategia se pudo comprobar los caminos que recorren todos los centros poblados tomando una pequeña muestra.
  • Si se integran ambas estrategias podría obtener una solución para un problema con pocos elementos y es fácil de comprobar; sin embargo, debido a la gran cantidad de datos a procesar los algoritmos propuestos pueden ser ineficientes.

Bibliografía

Jiménez, A. (2006, agosto 26). P versus NP. ¿Nunca lo entendiste? Obtenido de Xataka Ciencia: https://www.xatakaciencia.com/matematicas/p-versus-np-nunca-lo-entendiste

Pavlus, J. (19 de agosto de 2010). ¿Qué significa 'P vs NP' para el resto de nosotros? Obtenido de MIT Technology review: https://www.technologyreview.es/s/1374/que-significa-p-vs-np-para-el-resto-de-nosotros

Vasiliu, A. (25 de setiembre de 2018). Uninformed search algorithms in Python. Obtenido de http://cyluun.github.io/blog/uninformed-search-algorithms-in-python

Garg, P. (25 de setiembre de 2018). Breadth First Search. Obtenido de https://www.hackerearth.com/practice/algorithms/graphs/breadth-first-search/tutorial/

Agrawal, S. (2012 de diciembre de 2012). Artificial Intelligence – Uniform Cost Search(UCS). Obtenido de https://algorithmicthoughts.wordpress.com/2012/12/15/artificial-intelligence-uniform-cost-searchucs/

Ultrablendz. (07 de agosto de 2017). ¿Por qué es la complejidad de tiempo de ambos DFS y BFS O (V + E). Obtenido de https://stackoverrun.com/es/q/3057118

cc76tp20182's People

Contributors

manuxo avatar okotlanlais avatar

Watchers

James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.