¿La derivada de un gráfico está relacionada con listas de adyacencia?

14

Algunas de las obras de Conor McBride, Diff , Dissect , relacionan la derivada de los tipos de datos con su "tipo de contextos de un agujero". Es decir, si toma la derivada del tipo, le queda un tipo de datos que le muestra cómo se ve el tipo de datos desde adentro en cualquier punto dado.

Entonces, por ejemplo, si tienes una lista (en Haskell)

data List a = [] | a : List a

esto corresponde a

data List a = 1 + a * List a

y a través de un poco de magia matemática, la derivada es

data ListDeriv a = List a * List a

lo cual se interpreta que significa que en cualquier punto de la lista habrá una lista a la izquierda y una lista a la derecha. Podemos recorrer la lista original utilizando la estructura de datos derivados.

Ahora, estoy interesado en hacer algo similar con los gráficos. Una representación común de gráficos es un conjunto de vértices y aristas, que podrían implementarse ingenuamente con un tipo de datos como:

data Gr a b i = Gr [(i,a)] [(i,i,b)]

Si lo entiendo correctamente, una derivada de este tipo de datos, con respecto al índice del gráfico i, debería ser algo así.

data GrDeriv a b i = d/di (Gr a b i)
     = d\di ( [a*i] * [b*i^2] )
     = (d\di [a*i]) * [b*i^2] ) + [a*i]*(d/di [b*i^2])
     = (a* [a*i] * [a*i]) * [b*i^2] ) 
       + [a*i] * (2*b*i) *[b*i^2]*[b*i^2])
     = InNodes { nodesLeft :: [(a,i)]
               , nodeLbl :: a
               , nodesRight :: [(a,i)]
               , edges :: [(b,i,i)] }
     | InEdges { nodes :: [(a,i)]
               , adjNode :: Either (b,i) (b,i)
               , edgesLeft :: [(b,i,i)]
               , edgesRight :: [(b,i,i)] }

Obtuve esto mediante el uso de la regla del producto y las reglas de la cadena para derivados, y aunque posiblemente haya algunos errores, parece seguir el esquema general. En esta estructura, se centrará en Nodos (constructor InNodes) o Bordes (en bordes) y se le dará el lugar donde verá los datos relevantes.

Pero esto no es lo que esperaba. Esperaba una construcción más estrechamente relacionada con la interfaz de Martin Erwigs Functional Graph Library. Específicamente, quiero ver en un nodo un contexto que represente la etiqueta del nodo y dos listas de adyacencia, una para saliente y otra para entrante.

Node a b = ([(i,b)],a,[(i,b)])

Sin embargo, veo esperanza, ya que la representación de adyacencia tiene algunos términos en común con la derivada, la etiqueta solitaria a, en cada ubicación de agujero, la representación / disección de adyacencia de cada borde.

Dado que una derivada no es la misma función que la original, pero una integración de la derivada es (kindof), ¿hay algún tipo de análogo de integración que sirva para transformar la derivada en una colección de contextos de nodo? No es una integración directa para recuperar la estructura original, pero una estructura equivalente a la original pero en una representación más amigable con el algoritmo.

Si es así, espero que las estructuras de tipo de relación puedan especificarse mediante un lenguaje sencillo de "conjunto de vértices y aristas" y pueda derivar una biblioteca eficiente para trabajar con esa estructura. Tal implementación podría usarse para estudiar estructuras "más allá de la teoría de grafos": hipergramas, complejos simpliciales ...

Entonces. ¿Esta idea parece factible? ¿Útil? ¿Ha habido algún estudio sobre este tipo de cosas sobre el que podría leer más?

Apéndice

Como comentó Curtis F , un conjunto de nodos y aristas no es exactamente un gráfico. Sin embargo, todos los gráficos pueden ser representados por tales, y me parece bastante común la presentación. He visto (la muy gruesa especificación) utilizado en investigaciones que aplican la teoría de grafos a las optimizaciones de redes inalámbricas de varias maneras. Aquí hay un ejemplo de acceso abierto, DRAND *. Esto plantea la pregunta, ¿cuál es el vínculo entre la presentación y cómo se puede implementar algún software basado en la investigación?sol=(V,mi)

Dicho esto, no me opongo por completo a cambiar la especificación de entrada de a otra cosa. Por ejemplo, dado un tipo de índice , etiquetas de nodo, , y las etiquetas de borde, . Entonces el gráfico es (aproximadamente) una función de índices a una etiqueta y lista de bordes.sol=(V,mi)yoVmi

sol=yo(Vyomi)

Esto, estoy bastante seguro de que se puede expresar (¿teoría de categorías?) Como

(1)sol=(Vmiyo)yo

o

sol=Vyomiyoyo

que puede verse como un conjunto de vértices y bordes, dadas suficientes advertencias. Sin embargo, no está claro si la derivada de es significativa:(1)

sol=En(Vmiyo)(Vmiyo)yo(En(mi)Vmiyo)

Por mi parte, creo que muestra cierta promesa, pero me falta la sofisticación para ir más allá. Sé que debe haber algún trabajo por ahí explorando la conexión aún más.

* En caso de que el enlace se rompa alguna vez, cita: Rhee, Injong, et al. "DRAND: programación distribuida aleatoria de TDMA para redes inalámbricas ad hoc". Transacciones IEEE en informática móvil 8.10 (2009): 1384-1396.

trevor cook
fuente
El enlace que proporciona para la investigación está muerto. ¿Puedes dar un enlace más permanente, como DOI o la revista en la que se publicó?
Curtis F

Respuestas:

5

Su tipo Grrealmente no corresponde a gráficos, porque incluye muchas instancias que claramente no son gráficos, porque los índices de borde no necesitan ser índices de vértices reales.

Por ejemplo,

V={UN,si}mi={(C,re,mi)}

no es un gráfico, pero está permitido en su tipo como

Gr [(1, A), (2, B)] [(3, 4, e)]

Más bien, su Grcorresponde literalmente a una lista de índices etiquetados y una lista separada, no relacionada, de pares de índices etiquetados. Es por eso que obtienes una derivada "literal" de Grese tipo que no corresponde a los "agujeros" en los gráficos.

También existe el desafortunado problema de preocuparse por el orden de los vértices / bordes (visible en las distinciones nodesLeft/Righty edgesLeft/Right), pero esto se puede solucionar mediante el uso de una en Setlugar de una lista.


Aquí hay un tipo expresado en Haskell que creo que corresponde más estrechamente a los gráficos (no vacíos):

data Graph v e = Lone v | Joined v (Graph (v, ([e], [e])) e)

Para simplificar, en su lugar consideraré gráficos completos, simples y no dirigidos:

data Graph v e = Lone v | Joined v (Graph (v, e) e)

(Para relajar la integridad, deje e = Boolmarcar la presencia de borde)

Tenga en cuenta que Graphes recursivo (y de hecho, paramétricamente recursivo). Esto es lo que nos permite restringirnos al tipo de gráficos y no solo a listas de adyacencia combinadas con listas de vértices.

Escrito más algebraicamente,

sol(v,mi)=v+vsol(vmi,mi)

mivsol

sol(v)=v+vsol(vmi)

Al expandirse repetidamente, obtenemos el punto fijo

sol(v)=v1mi(12)+v2mi(22)+v3mi(32)+v4 4mi(4 42)+...

Esto tiene sentido, ya que un gráfico (completo) es

  • Un vértice y sin aristas
  • Dos vértices y un borde.
  • Tres vértices y tres aristas.
  • Cuatro vértices y cuatro eligen 2 = 6 aristas
  • ....

ksolk(v)=vkmi(k2)sol(v)=sol1(v)+sol2(v)+...

que tiene derivada

rerevsol(v)=yo=1solyo(v)

solk(v)=rerev[vkmik(k-1)2]=kvk-1mik(k-1)2

solk-1(v)=vk-1mi(k-1)(k-2)2solk(v)=solk-1(v)kmik-1

kk-1k-1k-1k

data SimpleGraph v e = Lone v | Joined v (SimpleGraph (v, e) e)

data SimpleGraphHole v e = Empty
                         | InsertLater v (SimpleGraphHole (v, e) e)
                         | InsertHere (SimpleGraph (v, e) e)

Orden de fijación en este gráfico

Esta versión de la estructura de datos Graph es fundamentalmente una lista vinculada, por lo que codifica el orden de los vértices. Si bien eso podría solucionarse en su versión de lista de adyacencia mediante el uso de un conjunto, no es tan directo aquí.

Creo que puede modificar una estructura de datos de árbol para hacer el mismo tipo de recursión paramétrica, con la raíz desempeñando el papel que desempeña la "cabeza" SimpleGraph. Mediante la interfaz de los conjuntos de árboles resultantes, el orden / estructura subyacente se vuelve invisible (o incluso canónico, si no está interesado en actualizaciones rápidas).

Su derivado propuesto

Usted propuso un tipo derivado; Lo cambiaré para combinar las etiquetas y los índices como lo hice:([(v,e)], [(v,e)])

1(1-vmi)2C+v1-vmi(v, [(v, e)])

Curtis F
fuente