Comprobación de estado contiguo (EE. UU.)

Dada una lista de estados, como en los estados de EE. UU., estoy tratando de escribir un algoritmo para saber si los estados son contiguos o no. El orden no importa y los estados se pueden revisar.

Ejemplos:

  • AZ, CA, OR, WA son contiguos
  • AZ, CA, NM, UT son contiguos
  • AZ, NM, OR, WA no son contiguos

Supuestos:

  1. Tengo una colección de cadenas que representan los estados.
  2. Tengo una colección de conexiones estatales.

    class StateConnection
    {
        public string OriginState { get; set; }
        public string ConnectingState { get; set; }
    }
    

Esta colección tiene registros en ambas direcciones:

  • OriginState = AZ, ConnectingState = CA
  • OriginState = CA, ConnectingState = AZ

¿Qué he probado?

Intento 1: Para cada estado de la colección, verifique que haya al menos una StateConnection con otro estado en la lista.

¿Por qué no funcionó? Esto permite pasar el tercer ejemplo, donde hay dos rangos contiguos separados.

Intento 2: Elimine estados de la lista de estados de conexión candidatos después de marcarlos. Esto requerirá una ruta completa que toque cada estado una vez.

¿Por qué no funcionó? Esto no permite el segundo ejemplo, donde un estado actúa como un centro para varios estados.

No he resuelto ningún problema de teoría de grafos desde hace tiempo, así que estoy un poco oxidado.

No busco nada parecido a un camino más corto o un vendedor ambulante. No me importa qué camino se tome o cuántos movimientos se usen. Todo lo que me importa es si hay o no una brecha.

Estoy escribiendo esto en C#, pero siéntete libre de dar una respuesta en otros idiomas.

preguntado el 27 de julio de 12 a las 15:07

3 Respuestas

Echa un vistazo a Llenado de inundaciones en teoría de grafos. Querría "pintar" cada nodo conectado en su árbol y luego, al final, verificar si alguno de sus estados permanece desconectado. No importa cómo recorra el gráfico para pintar (BFS o DFS), pero esto resaltaría las brechas (o nodos desconectados).

contestado el 23 de mayo de 17 a las 13:05

Parece que la mejor solución sería simplemente una búsqueda en amplitud a través del gráfico de estados. Algo como (usando la primera lista como ejemplo):

  • Cree una cola de estados para examinar. Para empezar, está vacío.
  • Elija un estado en la lista, por ejemplo CA, añádelo a la cola.

Luego, haz un bucle de la siguiente manera:

  • Retire un estado de la cola. Márcalo como visitado.
  • Compruebe si alguno de sus vecinos inmediatos (que no han sido visitados) está en la lista. Si es así, agréguelos a la cola.
  • ej. en caso de CA, encontramos dos vecinos en la lista: OR y AZ; agréguelos a una cola de los siguientes estados para examinar. Más tarde, al examinar OR, eso lo veremos WA y CA son sus vecinos y están en la lista; pero CA ya fue visitado, por lo que solo agregaremos WA a la lista de estados a visitar.

Continúe hasta que no haya más estados para eliminar de la cola. Si hemos visitado todos los estados de la lista inicial en ese punto, entonces la lista es contigua. De lo contrario no lo es.

Respondido 27 Jul 12, 16:07

Cree una matriz de conectividad del subconjunto de estados en cuestión (un N*N matriz booleana que incluye una fila y una columna para cada estado en el subconjunto, con m[i,j]==true si y solo si estados i y j son adyacentes entre sí).

Ejecute el siguiente algoritmo:

for (int k=0 ; k != N ; k++)
    for (int i=0 ; i != N ; i++)
        for (int j=0 ; j != N ; j++)
            m[i,j] |= (m[i,k] && m[k,j]);

Verifique que todos los elementos de m[i,j] se ponen a true después de que terminen los tres bucles. Si algún elemento es false, los estados no son contiguos.

En caso de que hayas olvidado qué es "esa cosa de tres bucles", es el famoso Algoritmo de Floyd-Warshall para encontrar cierres transitivos de grafos.

Respondido 27 Jul 12, 16:07

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.