En el siguiente gráfico, ¿hay algún atributo que pueda establecer que represente a A y H en el mismo rango? y D y G en el mismo rango? Para mi caso de uso, cada nodo es un proceso que comenzará tan pronto como se completen los procesos del nodo entrante y me gustaría que la posición del nodo indique la hora de inicio.

digraph {
    A -> B
    B -> C
    H -> C
    C -> D
    D -> E
    E -> F
    C -> G
    G -> F
}

digraph

Me gustaría que el resultado se pareciera al siguiente, pero como estos gráficos se generan dinámicamente, no quiero tener que calcular qué nodos debería marcar con el mismo rango.

digraph {
    { rank="same"; A; H }
    { rank="same"; D; G }
    A -> B
    B -> C
    H -> C
    C -> D
    D -> E
    E -> F
    C -> G
    G -> F
}

digraph-ideal

0
icio 13 mar. 2021 a las 22:43

2 respuestas

La mejor respuesta

Lo que está buscando existe como una configuración en el software Flying Logic y se llama sesgo allí.

Desafortunadamente, en el momento de mi respuesta (marzo de 2021), esto no existe. Por favor, vea la respuesta de uno de los mantenedores desde hace mucho tiempo a mi pregunta en Twitter. https://twitter.com/Graphviz/status/1128339044826517508?s=20

0
Wizard of Kneup 13 mar. 2021 a las 21:05

Este gvpr (https://www.graphviz.org/pdf/gvpr.1.pdf) el programa parece agregar correctamente subgrafos con rango = igual para "aumentar" los nodos según lo solicitado.
Tenga en cuenta que no espere que funcione si el gráfico de origen tiene subgráficos (especialmente grupos).

BEGIN {
  int i, j, n, s=0, changed=0; 
  int checkedNode[];
  int newRank[];
  string str1, rankString[], fld[int];
  node_t aNode, headNode;
  edge_t anEdge;
  graph_t aSub;
}
BEG_G{
  for (aNode=fstnode($G); aNode; aNode = nxtnode(aNode)){
    if (aNode.indegree==0){
      newRank[aNode]=1;
    }
  }
  while (1){
  for (newRank[aNode]){
    for (anEdge = fstout(aNode); anEdge; anEdge = nxtout(anEdge)){
      headNode=anEdge.head;
      if (newRank[headNode]=="" || (newRank[aNode]+1)>newRank[headNode]){
        newRank[headNode]=newRank[aNode]+1;
        print ("// rank=", newRank[headNode], "  ",  headNode.name);
    changed++;
      }
    }
  }
  if (changed==0)break;
  changed=0;
  }
  for (newRank[aNode]){
    rankString[newRank[aNode]]=sprintf("%s%s|",rankString[newRank[aNode]],aNode.name);
  }
  /* create subgraphs w/ rank=same */
  for (rankString[i]){
    unset(fld);
    n=tokens(rankString[i],fld,"|");
    if (n>1){
      str1=sprintf("__sub_%d",++s);    
      aSub=subg($G,str1);
      aSub.rank="same";
      for (j=0;j<n;j++){
        print ("// fld: >", fld[j], "<  ", j, "  ", n);
        aNode=node($G, fld[j]);
        aNode=subnode(aSub, aNode);
      }
    }
  }
}

Use una línea de comando como esta:

gvpr -c -f raiseRanks.gvpr  yourfile.gv | dot -Tpng >yourfile.png 

Dando:

// comments deleted
igraph {
        subgraph __sub_1 {
                graph [rank=same];
                A;
                H;
        }
        subgraph __sub_2 {
                graph [rank=same];
                D;
                G;
        }
        A -> B;
        B -> C;
        C -> D;
        C -> G;
        H -> C;
        D -> E;
        E -> F;
        G -> F;
}

enter image description here

0
sroush 14 mar. 2021 a las 19:21