#############################################################################
##
#W  weights.xml
#Y  Copyright (C) 2023                               Raiyan Chowdhury
##
##  Licensing information can be found in the README file of this package.
##
#############################################################################
##

<#GAPDoc Label="EdgeWeights">
    <ManSection>
    <Attr Name="EdgeWeights" Arg="digraph"/>
    <Oper Name="EdgeWeightsMutableCopy" Arg="digraph"/>
    <Returns>A list of lists of integers, floats or rationals.</Returns>
    <Description>
     <C>EdgeWeights</C> returns the list of lists of edge weights of
    the edges of the digraph <A>digraph</A>.<P/>

    More specifically, <C>weights[i][j]</C> is the weight given to the <C>j</C>th edge from vertex <C>i</C>, according to the ordering of edges given by <C>OutNeighbours(digraph)[i]</C>.<P/>

    The function <C>EdgeWeights</C> returns an immutable list of immutable
    lists, whereas the function <C>EdgeWeightsMutableCopy</C> returns a copy
    of <C>EdgeWeights</C> which is a mutable list of mutable lists.<P/>

    The edge weights of a digraph cannot be computed and must be set either
    using <C>SetEdgeWeights</C> or <Ref Func="EdgeWeightedDigraph" />.<P/>
    <Example><![CDATA[
gap> gr := EdgeWeightedDigraph([[2], [3], [1]], [[5], [10], [15]]);
<immutable digraph with 3 vertices, 3 edges>
gap> EdgeWeights(gr);
[ [ 5 ], [ 10 ], [ 15 ] ]
gap> a := EdgeWeightsMutableCopy(gr);
[ [ 5 ], [ 10 ], [ 15 ] ]
gap> a[1][1] := 100;
100
gap> a;
[ [ 100 ], [ 10 ], [ 15 ] ]
gap> b := EdgeWeights(gr);
[ [ 5 ], [ 10 ], [ 15 ] ]
gap> b[1][1] := 534;
Error, List Assignment: <list> must be a mutable list
]]></Example>
    </Description>
    </ManSection>
<#/GAPDoc>

<#GAPDoc Label="EdgeWeightedDigraph">
    <ManSection>
    <Func Name="EdgeWeightedDigraph" Arg="digraph, weights"/>
    <Returns>A digraph or <K>fail</K></Returns>
    <Description>
        The argument <A>digraph</A> may be a digraph or a list of lists of integers, floats or rationals.<P/>

        <A>weights</A> must be a list of lists of integers, floats or rationals
         of an equal size and shape to <C>OutNeighbours(digraph)</C>, otherwise it will fail.<P/>

        This will create a digraph and set the EdgeWeights to <A>weights</A>.<P/>

        See <Ref Attr="EdgeWeights"/>.
    <Example><![CDATA[
gap> g := EdgeWeightedDigraph(Digraph([[2], [1]]), [[5], [15]]);
<immutable digraph with 2 vertices, 2 edges>
gap> g := EdgeWeightedDigraph([[2], [1]], [[5], [15]]);
<immutable digraph with 2 vertices, 2 edges>
gap> EdgeWeights(g);
[ [ 5 ], [ 15 ] ]
]]></Example>
    </Description>
    </ManSection>
<#/GAPDoc>

<#GAPDoc Label="EdgeWeightedDigraphTotalWeight">
    <ManSection>
    <Attr Name="EdgeWeightedDigraphTotalWeight" Arg="digraph"/>
    <Returns>An integer, float or rational.</Returns>
    <Description>
        If <A>digraph</A> is a digraph with edge weights, then this attribute
        returns the sum of the weights of its edges.<P/>

        &MUTABLE_RECOMPUTED_ATTR;

        See <Ref Attr="EdgeWeights"/>.
    <Example><![CDATA[
gap> D := EdgeWeightedDigraph([[2], [1], [1, 2]],
>                             [[12], [5], [6, 9]]);
<immutable digraph with 3 vertices, 4 edges>
gap> EdgeWeightedDigraphTotalWeight(D);
32]]></Example>
    </Description>
    </ManSection>
<#/GAPDoc>

<#GAPDoc Label="EdgeWeightedDigraphMinimumSpanningTree">
    <ManSection>
    <Attr Name="EdgeWeightedDigraphMinimumSpanningTree" Arg="digraph"/>
    <Returns>A digraph.</Returns>
    <Description>
        If <A>digraph</A> is a connected digraph with edge weights, then this
        attribute returns a digraph which is a minimum spanning tree of
        <A>digraph</A>.<P/>

        A <E>spanning tree</E> of a digraph is a subdigraph with the same
        vertices but a subset of its edges that form an undirected tree.  It is
        <E>minimum</E> if it has the smallest possible total weight for a
        spanning tree of that digraph.<P/>

        &MUTABLE_RECOMPUTED_ATTR;

        See <Ref Attr="EdgeWeights"/>,
        <Ref Attr="EdgeWeightedDigraphTotalWeight"/> and
        <Ref Prop="IsConnectedDigraph"/>.
    <Example><![CDATA[
gap> D := EdgeWeightedDigraph([[2], [1], [1, 2]],
>                             [[12], [5], [6, 9]]);
<immutable digraph with 3 vertices, 4 edges>
gap> T := EdgeWeightedDigraphMinimumSpanningTree(D);
<immutable digraph with 3 vertices, 2 edges>
gap> EdgeWeights(T);
[ [  ], [ 5 ], [ 6 ] ]]]></Example>
    </Description>
    </ManSection>
<#/GAPDoc>

<#GAPDoc Label="EdgeWeightedDigraphShortestPaths">
<ManSection>
  <Attr Name="EdgeWeightedDigraphShortestPaths" Label="for a digraph" Arg="digraph"/>
  <Oper Name="EdgeWeightedDigraphShortestPaths" Label="for a digraph and a pos int" Arg="digraph, source"/>
  <Returns>A record.</Returns>
  <Description>
    If <A>digraph</A> is an edge-weighted digraph, this attribute returns a
    record describing the paths of lowest total weight (the <E>shortest
    paths</E>) connecting each pair of vertices.  If the optional argument
    <A>source</A> is specified and is a vertex of <A>digraph</A>, then the
    output will only contain information on paths originating from that
    vertex. <P/>

    In the two-argument form, the value returned is a record containing three
    components: <C>distances</C>, <C>parents</C> and <C>edges</C>.  Each of
    these is a list of integers with one entry for each vertex <C>v</C> as
    follows: <P/>
    <List>
      <Item>
        <C>distances[v]</C> is the total weight of the shortest path from
        <A>source</A> to <C>v</C>.
      </Item>
      <Item>
        <C>parents[v]</C> is the final vertex before <C>v</C> on the shortest
        path from <A>source</A> to <C>v</C>.
      </Item>
      <Item>
        <C>edges[v]</C> is the index of the edge of lowest weight going from
        <C>parents[v]</C> to <C>v</C>.
      </Item>
    </List>
    Using these three components together, you can find the shortest edge
    weighted path to all other vertices from a starting vertex. <P/>

    If no path exists from <A>source</A> to <C>v</C>, then <C>parents[v]</C> and
    <C>edges[v]</C> will both be <K>fail</K>.  The distance from <A>source</A>
    to itself is considered to be 0, and so both <C>parents[<A>source</A>]</C> and
    <C>edges[<A>source</A>]</C> are <K>fail</K>.
    Edge weights can have negative values, but there is currently no implemented
    method for this operation if a negative-weighted cycle exists. <P/>

    In the one-argument form, the value returned is also a record containing
    components <C>distances</C>, <C>parents</C> and <C>edges</C>, but each of
    these will instead be a list of lists in which the <C>i</C>th entry is the
    list that corresponds to paths starting at <C>i</C>. <P/>

    For a simple way of finding the shortest path between two specific vertices,
    see <Ref Oper="EdgeWeightedDigraphShortestPath"/>. See also the non-weighted
    operation <Ref Oper="DigraphShortestPath"/>. <P/>

    <Example><![CDATA[
gap> D := EdgeWeightedDigraph([[2, 3], [4], [4], []],
>                             [[5, 1], [6], [11], []]);
<immutable digraph with 4 vertices, 4 edges>
gap> EdgeWeightedDigraphShortestPaths(D, 1);
rec( distances := [ 0, 5, 1, 11 ], edges := [ fail, 1, 2, 1 ], 
  parents := [ fail, 1, 1, 2 ] )
gap> D := EdgeWeightedDigraph([[2], [3], [1]], [[1], [2], [3]]);
<immutable digraph with 3 vertices, 3 edges>
gap> EdgeWeightedDigraphShortestPaths(D);
rec( distances := [ [ 0, 1, 3 ], [ 5, 0, 2 ], [ 3, 4, 0 ] ], 
  edges := [ [ fail, 1, 1 ], [ 1, fail, 1 ], [ 1, 1, fail ] ], 
  parents := [ [ fail, 1, 1 ], [ 2, fail, 2 ], [ 3, 3, fail ] ] )]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="EdgeWeightedDigraphShortestPath">
<ManSection>
  <Oper Name="EdgeWeightedDigraphShortestPath" Arg="digraph, source, dest"/>
  <Returns>A pair of lists, or <K>fail</K>.</Returns>
  <Description>
    If <A>digraph</A> is an edge-weighted digraph with vertices <A>source</A>
    and <A>dest</A>, this operation returns a directed path from <A>source</A>
    to <A>dest</A> with the smallest possible total weight.  The output is a
    pair of lists <C>[v, a]</C> of the form described in <Ref
    Oper="DigraphPath"/>.<P/>

    If <M><A>source</A> = <A>dest</A></M> or no path exists, then <K>fail</K> is
    returned.<P/>

    If <A>digraph</A> contains a negative-weighted cycle, then there is
    currently no applicable method for this attribute. <P/>

    See <Ref Attr="EdgeWeightedDigraphShortestPaths" Label="for a digraph"/>.
    See also the non-weighted operation <Ref Oper="DigraphShortestPath"/>. <P/>
    <Example><![CDATA[
gap> D := EdgeWeightedDigraph([[2, 3], [4], [4], []],
>                             [[5, 1], [6], [11], []]);
<immutable digraph with 4 vertices, 4 edges>
gap> EdgeWeightedDigraphShortestPath(D, 1, 4);
[ [ 1, 2, 4 ], [ 1, 1 ] ]
gap> EdgeWeightedDigraphShortestPath(D, 3, 2);
fail]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>
