package flare.analytics.graph
{
import flare.animate.Transitioner;
import flare.util.Property;
import flare.vis.data.Data;
import flare.vis.data.EdgeSprite;
import flare.vis.data.NodeSprite;
import flare.vis.operator.Operator;
import flash.utils.Dictionary;
/**
* Calculates the maximum flow along edges of a graph using the
* Edmonds-Karp method. Each edge in the graph will be annotated with its
* final flow value, as well as a boolean value indicating if the edge
* is part of the minimum cut of the flow graph. Nodes are annotated with
* their partition according to the minimum cut: a partition value of 0
* indicates the source-side of the cut, a value of 1 indicates the
* sink-side of the cut.
*/
public class MaxFlowMinCut extends Operator
{
private var _c:Property = Property.$("props.capacity");
private var _f:Property = Property.$("props.flow");
private var _p:Property = Property.$("props.predecessor");
private var _k:Property = Property.$("props.mincut");
private var _cap:Function = null;
/** The property in which to store computed flow values. This property
* is used to annotate edges with the computed flow. The default
* value is "props.flow". */
public function get flowField():String { return _f.name; }
public function set flowField(f:String):void { _f = Property.$(f); }
/** The property in which to store minimum-cut data. The default value
* is "props.mincut". This property is used to annotate nodes with
* their partition (0 for source-side, 1 for sink-side) and to
* annotate edges with min-cut membership (true if part of the
* minimum cut, false otherwise). */
public function get mincutField():String { return _k.name; }
public function set mincutField(f:String):void { _k = Property.$(f); }
/** The source node for which to compute the max flow. */
public var source:NodeSprite;
/** The sink node for which to compute the max flow. */
public var sink:NodeSprite;
/** A function defining the edge capacities for flow. When setting
* this value, one can pass in either a Function, which should take an
* EdgeSprite as input and return a Number as output, or a String, in
* which case the string will be used as a property name from which to
* retrieve the edge capacity value from an EdgeSprite instance.
* If the value is null (the default) all edges will be assumed to have
* capacity 1.
*
* <p><b>NOTE:</b> Capacities must be greater than or equal to zero!
* </p> */
public function get edgeCapacity():Function { return _cap; }
public function set edgeCapacity(c:*):void {
if (c==null) {
_cap = null;
} else if (c is String) {
_cap = Property.$(String(c)).getValue;
} else if (c is Function) {
_cap = c;
} else {
throw new Error("Unrecognized edgeCapacity value. " +
"The value should be a Function or String.");
}
}
/** The computed maximum flow value. This value is zero by default
* and is populated once the max flow calculation is run. */
public function get maxFlow():Number { return _maxFlow; }
private var _data:Data, _s:NodeSprite, _t:NodeSprite;
private var _maxFlow:Number = 0;
/**
* Creates a new MaxFlowMinCut operator.
* @param source the source node in the flow graph
* @param sink the sink node in the flow graph
* @param edgeCapacity the edge capacity values. This can either be a
* <code>Function</code> that returns capacity values or a
* <code>String</code> providing the name of a property to look up on
* <code>EdgeSprite</code> instances.
*/
public function MaxFlowMinCut(source:NodeSprite=null,
sink:NodeSprite=null, edgeCapacity:*=n