text:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<TITLE>
Uses of Interface org.apache.hadoop.contrib.utils.join.ResetableIterator (Hadoop 1.0.4-SNAPSHOT API)
</TITLE>

<META NAME="date" CONTENT="2013-04-09">

<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../../../stylesheet.css" TITLE="Style">

      Overview
      Package
      Class
    Use
      Tree
      Deprecated
      Index
      Help

 PREV
 NEXT

  FRAMES
 NO FRAMES

  All Classes

Uses of Interface
org.apache.hadoop.contrib.utils.join.ResetableIterator

Packages that use ResetableIterator

org.apache.hadoop.contrib.utils.join

Uses of ResetableIterator in org.apache.hadoop.contrib.utils.join

Classes in org.apache.hadoop.contrib.utils.join that implement ResetableIterator

 class
ArrayListBackedIterator

          This class provides an implementation of ResetableIterator.

Methods in org.apache.hadoop.contrib.utils.join that return ResetableIterator

protected  ResetableIterator
DataJoinReducerBase.createResetableIterator()

          The subclass can provide a different implementation on ResetableIterator.

      Overview
      Package
      Class
    Use
      Tree
      Deprecated
      Index
      Help

 PREV
 NEXT

  FRAMES
 NO FRAMES

  All Classes

Copyright © 2009 The Apache Software Foundation


text:
//********************************************************************
//  FlipRace.java       Author: Lewis/Loftus/Cocking
//
//  Demonstrates the existence of separate data space in multiple
//  instantiations of a programmer-defined class.
//********************************************************************
public class FlipRace
{
    //-----------------------------------------------------------------
    //  Flips two coins until one of them comes up heads three times
    //  in a row.
    //-----------------------------------------------------------------
    public static void main (String[] args)
    {
        final int GOAL = 3;
        int count1 = 0, count2 = 0;
        // Create two separate coin objects
        Coin coin1 = new Coin();
        Coin coin2 = new Coin();
        while (count1 < GOAL && count2 < GOAL)
        {
            coin1.flip();
            coin2.flip();
            // Print the flip results (uses Coin's toString method)
            System.out.print ("Coin 1: " + coin1);
            System.out.println (" Coin 2: " + coin2);
            // Increment or reset the counters
            if (coin1.isHeads())
                count1++;
            else
                count1 = 0;
            if (coin2.isHeads())
                count2++;
            else
                count2 = 0;
        }
        // Determine the winner
        if (count1 < GOAL)
            System.out.println ("Coin 2 Wins!");
        else
        if (count2 < GOAL)
            System.out.println ("Coin 1 Wins!");
        else
            System.out.println ("It's a TIE!");
    }
}

redpajama_set_name: RedPajamaGithub


text:
from os.path import dirname, join
from sys import path
path.append(join(dirname(__file__), '..'))

from KINCluster import KINCluster
from pipeline import PipelineServer
from test_app import settings

if __name__ == '__main__':
    kin = KINCluster(PipelineServer(), settings= settings)
    kin.run()


text:
ACCEPTED

#### According to
Index Fungorum

#### Published in
Michelia 1(no. 4): 444 (1878)

#### Original name
Geoglossum umbratile var. umbratile

### Remarks
null


text:
        <title>Puffin's settings panel</title>
        <link href='/style.css' rel='stylesheet' type='text/css'>

Puffin's setting panel

Where Puffins change their settings

Go back

            Note: Lack of the image means something went wrong. Try accesing your image url manually and see if it still works


text:
package example;

import java.awt.*;
import java.awt.event.MouseEvent;
import javax.swing.*;
import javax.swing.event.MouseInputAdapter;
import javax.swing.event.MouseInputListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableColumn;
import javax.swing.table.TableModel;

public final class MainPanel extends JPanel {
  private MainPanel() {
    super(new BorderLayout());
    String[] columnNames = {"String", "Integer", "Boolean"};
    Object[][] data = {
        {"aaa", 12, true}, {"bbb", 5, false}, {"CCC", 92, true}, {"DDD", 0, false}
    };
    TableModel model = new DefaultTableModel(data, columnNames) {
      @Override public Class<?> getColumnClass(int column) {
        return getValueAt(0, column).getClass();
      }
    };

    JTable table = new JTable(model) {
      private transient MouseInputListener handler;
      @Override public void updateUI() {
        getTableHeader().removeMouseListener(handler);
        getTableHeader().removeMouseMotionListener(handler);
        super.updateUI();
        handler = new ColumnWidthResizeHandler();
        getTableHeader().addMouseListener(handler);
        getTableHeader().addMouseMotionListener(handler);
      }
    };
    add(new JScrollPane(table));
    // JWindow window = new JWindow();
    // JToolTip tip = new JToolTip();
    // window.add(tip);
    // JTable table2 = new JTable(model);
    // table2.getTableHeader().addPropertyChangeListener(e -> {
    //   // System.out.println(e.getPropertyName());
    //   JTableHeader h = (JTableHeader) e.getSource();
    //   TableColumn column = h.getResizingColumn();
    //   if (column != null) {
    //     tip.setTipText(String.format("Width: %dpx", column.getWidth()));
    //     Point pt = h.getHeaderRect(column.getModelIndex()).getLocation();
    //     SwingUtilities.convertPointToScreen(pt, h);
    //     window.pack();
    //     window.setLocation(pt);
    //     window.setVisible(true);
    //   } else {
    //     window.setVisible(false);
    //   }
    // });
    // add(new JScrollPane(table2));
    setPreferredSize(new Dimension(320, 240));
  }

  public static void main(String[] args) {
    EventQueue.invokeLater(MainPanel::createAndShowGui);
  }

  private static void createAndShowGui() {
    try {
      UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
      ex.printStackTrace();
      Toolkit.getDefaultToolkit().beep();
    }
    JFrame frame = new JFrame("@title@");
    frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    frame.getContentPane().add(new MainPanel());
    frame.pack();
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
  }
}

class ColumnWidthResizeHandler extends MouseInputAdapter {
  private final JWindow window = new JWindow();
  private final JToolTip tip = new JToolTip();
  private String prev = "";

  private Point getToolTipLocation(MouseEvent e) {
    Point p = e.getPoint();
    Component c = e.getComponent();
    SwingUtilities.convertPointToScreen(p, c);
    p.translate(0, -tip.getPreferredSize().height);
    return p;
  }

  private static TableColumn getResizingColumn(MouseEvent e) {
    Component c = e.getComponent();
    if (c instanceof JTableHeader) {
      return ((JTableHeader) c).getResizingColumn();
    }
    return null;
  }

  private void updateTooltipText(MouseEvent e) {
    TableColumn column = getResizingColumn(e);
    if (column != null) {
      String txt = String.format("Width: %dpx", column.getWidth());
      tip.setTipText(txt);
      if (prev.length() != txt.length()) {
        window.pack();
      }
      window.setLocation(getToolTipLocation(e));
      prev = txt;
    }
  }

  @Override public void mouseDragged(MouseEvent e) {
    if (!window.isVisible() && getResizingColumn(e) != null) {
      window.add(tip);
      window.setAlwaysOnTop(true);
      window.setVisible(true);
    }
    updateTooltipText(e);
  }

  @Override public void mouseReleased(MouseEvent e) {
    window.setVisible(false);
  }
}


text:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace RPi.SenseHat.Demo.Demos
{
    class SnakeHead
    {
        int snakeHeadX;
        int snakeHeadY;
        internal SnakeHead(int x, int y)
        {
            snakeHeadX = x;
            snakeHeadY = y;
        }
        public int GetSnakeHeadX()
        {
            return snakeHeadX;
        }
        public void SetSnakeHeadX(int x)
        {
            snakeHeadX = x;
        }
        public int GetSnakeHeadY()
        {
            return snakeHeadY;
        }
        public void SetSnakeHeadY(int y)
        {
            snakeHeadY = y;
        }
        internal SnakeHead returnHead()
        {
            return this;
        }
    }
}


text:
"use strict";

/**
 * <%= name %>Controller
 * @description :: Server-side logic for ...
 */

module.exports = {
  index(req, res) {
    res.ok();
  }
};


text:
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <string>

#include "chrome/browser/extensions/api/declarative/test_rules_registry.h"

namespace extensions {

TestRulesRegistry::TestRulesRegistry(content::BrowserThread::ID owner_thread,
                                     const std::string& event_name)
    : RulesRegistry(NULL /*profile*/,
                    event_name,
                    owner_thread,
                    NULL) {}

TestRulesRegistry::TestRulesRegistry(
    Profile* profile,
    const std::string& event_name,
    content::BrowserThread::ID owner_thread,
    RulesCacheDelegate* cache_delegate)
    : RulesRegistry(profile,
                    event_name,
                    owner_thread,
                    cache_delegate) {}

std::string TestRulesRegistry::AddRulesImpl(
    const std::string& extension_id,
    const std::vector<linked_ptr<RulesRegistry::Rule> >& rules) {
  return result_;
}

std::string TestRulesRegistry::RemoveRulesImpl(
    const std::string& extension_id,
    const std::vector<std::string>& rule_identifiers) {
  return result_;
}

std::string TestRulesRegistry::RemoveAllRulesImpl(
    const std::string& extension_id) {
  return result_;
}

void TestRulesRegistry::SetResult(const std::string& result) {
  result_ = result;
}

TestRulesRegistry::~TestRulesRegistry() {}

}  // namespace extensions


text:
using System.Collections;

/// <summary>
/// CoroutineScheduler.cs
///
/// Port of the Javascript version from
/// http://www.unifycommunity.com/wiki/index.php?title=CoroutineScheduler
///
/// Linked list node type used by coroutine scheduler to track scheduling of coroutines.
///
///
/// BMBF Researchproject http://playfm.htw-berlin.de
/// PlayFM - Serious Games für den IT-gestützten Wissenstransfer im Facility Management
///	Gefördert durch das bmb+f - Programm Forschung an Fachhochschulen profUntFH
///
///	<author>Frank.Otto@htw-berlin.de</author>
///
///
/// A simple coroutine scheduler. Coroutines can yield until the next update
/// "yield;", until a given number of updates "yield anInt", until a given
/// amount of seconds "yield aFloat;", or until another coroutine has finished
/// "yield scheduler.StartCoroutine(Coroutine())".
///
/// Multiple scheduler instances are supported and can be very useful. A
/// coroutine running under one scheduler can yield (wait) for a coroutine
/// running under a completely different scheduler instance.
///
/// Unity's YieldInstruction classes are not used because I cannot
/// access their internal data needed for scheduling. Semantics are slightly
/// different from Unity's scheduler. For example, in Unity if you start a
/// coroutine it will run up to its first yield immediately, while in this
/// scheduler it will not run until the next time UpdateAllCoroutines is called.
/// This feature allows any code to start coroutines at any time, while
/// making sure the started coroutines only run at specific times.
///
/// You should not depend on update order between coroutines running on the same
/// update. For example, StartCoroutine(A), StartCoroutine(B), StartCoroutine(C)
/// where A, B, C => while(true) { print(A|B|C); yield; }, do not expect "ABC" or
/// "CBA" or any other specific ordering.
/// </summary>
///
///
namespace TrueSync {
	public class CoroutineScheduler
	{

		CoroutineNode first = null;
		FP currentTime;

		AbstractLockstep lockStep;

		public CoroutineScheduler(AbstractLockstep lockStep) {
			this.lockStep = lockStep;
		}

		/**
	   * Starts a coroutine, the coroutine does not run immediately but on the
	   * next call to UpdateAllCoroutines. The execution of a coroutine can
	   * be paused at any point using the yield statement. The yield return value
	   * specifies when the coroutine is resumed.
	   */

		public CoroutineNode StartCoroutine (IEnumerator fiber)
		{
			// if function does not have a yield, fiber will be null and we no-op
			if (fiber == null) {
				return null;
			}
			// create coroutine node and run until we reach first yield
			CoroutineNode coroutine = new CoroutineNode (fiber);
			AddCoroutine (coroutine);

			return coroutine;
		}

		/**
	   * Stops all coroutines running on this behaviour. Use of this method is
	   * discouraged, think of a natural way for your coroutines to finish
	   * on their own instead of being forcefully stopped before they finish.
	   * If you need finer control over stopping coroutines you can use multiple
	   * schedulers.
	   */
		public void StopAllCoroutines ()
		{
			first = null;
		}

		/**
	   * Returns true if this scheduler has any coroutines. You can use this to
	   * check if all coroutines have finished or been stopped.
	   */
		public bool HasCoroutines ()
		{
			return first != null;
		}

		public void UpdateAllCoroutines ()
		{
			InputDataBase oldInputData = TrueSyncInput.CurrentSimulationData;
			UpdateAllCoroutines (lockStep.Ticks, TrueSyncManager.Time);
			TrueSyncInput.CurrentSimulationData = (InputData) oldInputData;
		}

		/**
	   * Runs all active coroutines until their next yield. Caller must provide
	   * the current frame and time. This allows for schedulers to run under
	   * frame and time regimes other than the Unity's main game loop.
	   */
		public void UpdateAllCoroutines (int frame, FP time)
		{
			currentTime = time;
			CoroutineNode coroutine = this.first;
			while (coroutine != null) {
				// store listNext before coroutine finishes and is removed from the list
				CoroutineNode listNext = coroutine.listNext;

				if (coroutine.waitForFrame > 0 && frame >= coroutine.waitForFrame) {
					coroutine.waitForFrame = -1;
					UpdateCoroutine (coroutine);
				} else if (coroutine.waitForTime > 0.0f && time >= coroutine.waitForTime) {
					coroutine.waitForTime = -1.0f;
					UpdateCoroutine (coroutine);
				} else if (coroutine.waitForCoroutine != null && coroutine.waitForCoroutine.finished) {
					coroutine.waitForCoroutine = null;
					UpdateCoroutine (coroutine);
				} else if (coroutine.waitForFrame == -1 && coroutine.waitForTime == -1.0f && coroutine.waitForCoroutine == null) {
					// initial update
					UpdateCoroutine (coroutine);
				}
				coroutine = listNext;
			}
		}

		/**
	   * Executes coroutine until next yield. If coroutine has finished, flags
	   * it as finished and removes it from scheduler list.
	   */
		private void UpdateCoroutine (CoroutineNode coroutine)
		{
			IEnumerator fiber = coroutine.fiber;

			if (coroutine.playerId > -1) {
				TrueSyncInput.CurrentSimulationData = (InputData) lockStep.GetInputData (coroutine.playerId);
			}

			if (coroutine.fiber.MoveNext ()) {
				System.Object yieldCommand = fiber.Current == null ? (System.Object) 1 : fiber.Current;

				if (yieldCommand.GetType () == typeof(int)) {
					coroutine.waitForTime = (FP) ((int) yieldCommand);
					coroutine.waitForTime += (FP)currentTime;
				} else if (yieldCommand.GetType () == typeof(float)) {
					coroutine.waitForTime = (FP) ((float) yieldCommand);
					coroutine.waitForTime += (FP) currentTime;
				} else if (yieldCommand.GetType () == typeof(FP)) {
					coroutine.waitForTime = (FP) yieldCommand;
					coroutine.waitForTime += (FP) currentTime;
				} else if (yieldCommand.GetType () == typeof(CoroutineNode)) {
					coroutine.waitForCoroutine = (CoroutineNode) yieldCommand;
				} else {
					throw new System.ArgumentException ("CoroutineScheduler: Unexpected coroutine yield type: " + yieldCommand.GetType ());
				}
			} else {
				// coroutine finished
				coroutine.finished = true;
				RemoveCoroutine (coroutine);
			}
		}

		private void AddCoroutine (CoroutineNode coroutine)
		{

			if (this.first != null) {
				coroutine.listNext = this.first;
				first.listPrevious = coroutine;
			}
			first = coroutine;
		}

		private void RemoveCoroutine (CoroutineNode coroutine)
		{
			if (this.first == coroutine) {
				// remove first
				this.first = coroutine.listNext;
			} else {
				// not head of list
				if (coroutine.listNext != null) {
					// remove between
					coroutine.listPrevious.listNext = coroutine.listNext;
					coroutine.listNext.listPrevious = coroutine.listPrevious;
				} else if (coroutine.listPrevious != null) {
					// and listNext is null
					coroutine.listPrevious.listNext = null;
					// remove last
				}
			}
			coroutine.listPrevious = null;
			coroutine.listNext = null;
		}

	}//class
}


text:
package com.github.spiro.storm.gadgets;

import com.github.spirom.storm.gadgets.mock.QueueSinkBolt;
import com.github.spirom.storm.gadgets.mock.QueueSpout;
import com.github.spirom.storm.gadgets.test.AsyncTupleQueue;
import com.github.spirom.storm.gadgets.test.TestSetup;
import com.github.spirom.storm.gadgets.test.TestState;
import org.apache.storm.tuple.Fields;
import org.apache.storm.tuple.Values;
import org.junit.*;

public class CacheJoiningBoltGuaranteedDeliveryTest {

    private static TestSetup _setup = new TestSetup();

    @BeforeClass
    public static void oneTimeSetup() {
        _setup.before();
    }

    @AfterClass
    public static void onTimeTeardown() {
        _setup.after();
    }

    @Before
    public void setUp() {

    }

    @After
    public void tearDown() {
        _setup.killTopology();
    }

    @Test
    public void testBasic() {

        JoinTestSpec js = new SingleJoinTestSpec(false);

        TestState state = js.makeTopology(false);
        _setup.submitTopology(state.topology());

        // set up the hash table by sending a couple of hash tuples

        QueueSpout.getQueue("hashSpout").add(new Values(1, 11, "101"));
        QueueSpout.getQueue("hashSpout").add(new Values(2, 12, "102"));

        // wait for cache state to quiesce

        QueueSinkBolt.getQueue("hashSink")
                .waitForTuple(30,
                        new Fields("h1", "h2", "h3"),
                        new Values(1, 11, "101"));
        QueueSinkBolt.getQueue("hashSink")
                .waitForTuple(30,
                        new Fields("h1", "h2", "h3"),
                        new Values(2, 12, "102"));

        assert (QueueSinkBolt.getQueue("hashSink").isEmpty());

        // send in some records and check for correct joining

        QueueSpout.getQueue("left1").add(new Values(1, 1001, "1001"));
        QueueSpout.getQueue("left1").add(new Values(2, 1002, "1002"));

        // fail the second one and watch for retransmission
        QueueSinkBolt.getQueue("joined1")
                .waitForTuple(30,
                        new Fields("a1o", "a2o", "a3o", "h2o", "h3o"),
                        new Values(1, 1001, "1001", 11, "101"),
                        AsyncTupleQueue.Response.ACK);
        QueueSinkBolt.getQueue("joined1")
                .waitForTuple(30,
                        new Fields("a1o", "a2o", "a3o", "h2o", "h3o"),
                        new Values(2, 1002, "1002", 12, "102"),
                        AsyncTupleQueue.Response.FAIL);
        QueueSinkBolt.getQueue("joined1")
                .waitForTuple(30,
                        new Fields("a1o", "a2o", "a3o", "h2o", "h3o"),
                        new Values(2, 1002, "1002", 12, "102"),
                        AsyncTupleQueue.Response.ACK);

        assert (QueueSinkBolt.getQueue("joined1").isEmpty());

    }
}


text:
package algorithms.bipartite;

import algorithms.matrix.MatrixUtil;
import algorithms.util.PairInt;
import gnu.trove.iterator.TIntIntIterator;
import gnu.trove.iterator.TIntIterator;
import gnu.trove.iterator.TIntObjectIterator;
import gnu.trove.iterator.TObjectIntIterator;
import gnu.trove.map.TIntIntMap;
import gnu.trove.map.TIntObjectMap;
import gnu.trove.map.hash.TIntFloatHashMap;
import gnu.trove.map.hash.TIntIntHashMap;
import gnu.trove.map.hash.TIntObjectHashMap;
import gnu.trove.map.hash.TObjectFloatHashMap;
import gnu.trove.map.hash.TObjectIntHashMap;
import gnu.trove.set.TIntSet;
import gnu.trove.set.hash.TIntHashSet;
import java.util.logging.Logger;

/**
 * class representing a flow network for
 * MinCostUnbalancedAssignment.java
   If the sink and source nodes and weights are set in the
   origin graph, sink and source logic is used in code.
 *
 * @author nichole
 */
public class FlowNetwork {

    private Logger log = Logger.getLogger(this.getClass().getName());

    /*
     matchings M in Graph g are integral flows f in the
     FlowNetwork.

     If allows for conditions which are not integral, one uses
     linear programming terms to replace the term slackness
     with "proper"ness on properties f and p where f is flow and p is prices.
     - a node has a per unit price.
     - adopting the cost to dispose of a unit as the model p_d(v)
     - (the dispose cost is equal with opposite sign to acquire cost)
     - the cost of each arc is the difference between the
     disposal cost of the two encasing nodes.
     - the net cost is cp(v, w)
     - the benefits of the arc is bp(v,w) and the sum of it
     and cp(v,w) is 0.
     cp(v, w) := c(v, w) + pa(v) − pa(w)
     = c(v, w) − pd(v) + pd(w)
     bp(v, w) := b(v, w) − pa(v) + pa(w)
     = b(v, w) + pd(v) − pd(w)

     cp(v, w) = c(v, w) − pd(v) + pd(w)

     - cost and net flow are related as:
     cp(f) = summation over arcs in flow network
     f(v,w) * cp(v,w)
         = summation over arcs in flow network
     f(v,w) * (c(v,w) − pd(v) + pd(w))
         = c(f) − |f| * pd(⊢) − pd(⊣)
     note that the value |f| is the total flow out of the
     source ⊢ and into the sink ⊣,
     while flow is conserved at all other nodes.

     - each arc w/ f(v,w) = 0 and cp(x, y) ≥ 0
     and is idle
     and each arc w/ f(v,w) = 1 and cp(x, y) ≤ 0
     is saturated.
     (the pair of f and p are proper under those conditions)
     - arcs with fractional flow have zero net cost
     - (edges w/ 0 net cost are "tight")
     */

    /**
     *

     * |-
     *

     */
    private final int sourceNode;

    /**
     *

     * -|
     *

     */
    private int sinkNode;

    /**
     * left (==X) vertices in graph
     */
    private final int nLeft;

    /**
     * right (==Y) vertices in graph
     */
    private final int nRight;

    /**
     * prices for left (author's adopted price to dispose of product).
     * The source node is at position nLeft.
     */
    private final float[] pLeft;

    /**
     * prices for right (author's adopted price to dispose of product).
     * The sink node is at position nRight.
     */
    private final float[] pRight;

    // the maximum cost
    private int maxC = Integer.MIN_VALUE;

    // the minimum cost
    private int minC = Integer.MAX_VALUE;

    /** forward arcs only in the flow graph
    may represent these differently soon.
    they are also known as "bipartite arcs".
    */
    private final TIntObjectHashMap<TIntSet> forwardArcs
        = new TIntObjectHashMap<TIntSet>();

    /** forward arcs from source to the left (a.k.a. X nodes).
     * If an arc is saturated, it will have flux=1 along this
     * arc.
    */
    private final TIntSet sourceForwardArcs =
        new TIntHashSet();

    /** forward arcs from the right (a.k.a. Y nodes) to sink node
    If an arc is saturated, it will have flux=1 along this arc.
    */
    private final TIntSet sinkForwardArcs =
        new TIntHashSet();

    /**
     * per unit flow costs are the same as the edges given in G.
     * key = index in left (==X==v) and index in right (==Y==w),
     * value = cost of the arc. might
     * change to use sparse matrix format
     */
    private final TObjectIntHashMap<PairInt> c
        = new TObjectIntHashMap<PairInt>();

    /**
     * the flow on the arc. key = index in left (==X==v) and index in right
     * (==Y==w), value = number from 0 to 1 inclusive if it's a "pseudoflow":
     * the value 0 is "idle" and corresponds to an unmatched link in the
     * residual graph. the value 1 is "saturated" and corresponds to a matched
     * link in the residual graph (but in the residual graph, it would be
     * specified in format right to left). might change to use sparse matrix
     * format
     */
    private final TObjectFloatHashMap<PairInt> f
        = new TObjectFloatHashMap<PairInt>();

    /**
     * per unit dummy flow costs from source to X nodes
     * (initialized as 0).
     * key = index in left (==X==v)
     * value = cost of the arc. might
     * change to use sparse matrix format
     */
    private final TIntIntHashMap sourceToLeftC =
        new TIntIntHashMap();

    /**
     * per unit dummy flow costs from sink to X nodes
     * (initialized as 0).
     * key = index of right node (== Y)
     * value = cost of the arc
     */
    private final TIntIntHashMap rightToSinkC =
        new TIntIntHashMap();

    /**
     * flux from source to x node
     */
    private final TIntFloatHashMap sourceToLeftF =
        new TIntFloatHashMap();

    /**
     * flux from y node to sink
     */
    private final TIntFloatHashMap rightToSinkF =
        new TIntFloatHashMap();

    // nodes placed here for convenience.  they're an adaptation of
    // the graph used in path algorithms.
    private PathNodes pathNodes = null;

    public FlowNetwork(Graph g, TIntIntMap m) {

        this.nLeft = g.getNLeft();
        this.nRight = g.getNRight();
        this.sourceNode = nLeft;
        this.sinkNode = nRight;
        pLeft = new float[nLeft + 1];
        pRight = new float[nRight + 1];

        TObjectIntIterator<PairInt> iter = g.getEdgeWeights().iterator();
        for (int i = g.getEdgeWeights().size(); i-- > 0;) {

            iter.advance();

            PairInt p = iter.key();

            int idx1 = p.getX();
            int idx2 = p.getY();

            TIntSet indexes2 = forwardArcs.get(idx1);
            if (indexes2 == null) {
                indexes2 = new TIntHashSet();
                forwardArcs.put(idx1, indexes2);
            }
            indexes2.add(idx2);

            int cost = g.getEdgeWeights().get(p);
            c.put(p, cost);
            f.put(p, 0);

            if (Math.abs(cost) > maxC) {
                maxC = Math.abs(cost);
            }
            if (Math.abs(cost) < minC) {
                minC = Math.abs(cost);
            }

            sourceForwardArcs.add(idx1);
            sinkForwardArcs.add(idx2);

            // set source and sink arcs to 0 and overwrite
            // those for matched vertexes in next block
            sourceToLeftF.put(idx1, 0);
            rightToSinkF.put(idx2, 0);

            // cost of dummy edge is 0
            sourceToLeftC.put(idx1, 0);
            rightToSinkC.put(idx2, 0);
        }

        TIntIntIterator iter2 = m.iterator();
        for (int ii = m.size(); ii-- > 0;) {
            iter2.advance();
            int leftIdx = iter2.key();
            int rightIdx = iter2.value();
            sourceToLeftF.put(leftIdx, 1);
            PairInt p = new PairInt(leftIdx, rightIdx);
            f.put(p, 1);
            rightToSinkF.put(rightIdx, 1);
        }

        assert (maxC > 1);

        /*
        For each vertex x in X, there is a left-dummy arc |- -> x,
           directed from the source node |- to the node x.
           The per-unit cost of a left-dummy arc is zero:
           c(|-, x) := 0.
        For each vertex y in Y , there is a right-dummy arc y -> -|,
           directed from the node
           y to the sink node -| and of cost zero:
           c(y, -|) := 0.
        */

    }

    public int getMaxC() {
        return maxC;
    }

    public int getMinC() {
        return minC;
    }

    /**
     *

     * cp(f) = c(f) - |f|*(pd(|-) - pd(-|))
     *

     * @return
     */
    public double calcNetCost() {

        double cf = calcFluxCost();
        double flux = calcTotalFlow();

        double cp = cf - (flux * (pLeft[sourceNode] - pRight[sinkNode]));

        return cp;
    }

    /**
     * total flow out of the source (or equivalently,
     * into the sink or equivalently out of all bipartite arcs).
     * @return
     */
    public double calcTotalFlow() {

        // excludes source and sink nodes too

        double sum = 0;

        TIntObjectIterator<TIntSet> iter3 = forwardArcs.iterator();
        for (int ii = forwardArcs.size(); ii-- > 0;) {
            iter3.advance();
            int idx1 = iter3.key();
            TIntSet idxs2 = iter3.value();

            TIntIterator iter4 = idxs2.iterator();
            while (iter4.hasNext()) {
                int idx2 = iter4.next();
                PairInt p = new PairInt(idx1, idx2);
                float unitFlow = f.get(p);
                sum += unitFlow;
            }
        }

        return sum;
    }

    /**
     * c(f) = summation over arcs of (f(v,w) * c(v,w))
     * @return
     */
    public double calcFluxCost() {

        // includes source and sink nodes too, but their costs are 0

        double sum = 0;

        TIntObjectIterator<TIntSet> iter = forwardArcs.iterator();
        for (int i = forwardArcs.size(); i-- > 0;) {

            iter.advance();
            int idx1 = iter.key();
            TIntIterator iter2 = iter.value().iterator();
            while (iter2.hasNext()) {
                int idx2 = iter2.next();
                PairInt p = new PairInt(idx1, idx2);
                float unitFlow = f.get(p);
                float cost = c.get(p);
                sum += (unitFlow * cost);
            }
        }

        TIntIterator iter2 = sourceForwardArcs.iterator();
        while (iter2.hasNext()) {
            int idx1 = iter2.next();
            float unitFlow = sourceToLeftF.get(idx1);
            float cost = sourceToLeftC.get(idx1);
            sum += (unitFlow * cost);
        }

        iter2 = sinkForwardArcs.iterator();
        while (iter2.hasNext()) {
            int idx1 = iter2.next();
            float unitFlow = rightToSinkF.get(idx1);
            float cost = rightToSinkC.get(idx1);
            sum += (unitFlow * cost);
        }

        return sum;
    }

    public float getSourceToLeftFlow(int idx) {
        return sourceToLeftF.get(idx);
    }
    public float getRightToSinkFlow(int idx) {
        return rightToSinkF.get(idx);
    }
    public int getSourceToLeftCost(int idx) {
        return sourceToLeftC.get(idx);
    }

    public float calcNetCost(int u, int v) {

        if (u == sourceNode) {
            return calcSourceNetCost(v);
        } else if (v == sinkNode) {
            return calcSinkNetCost(u);
        }

        PairInt p = new PairInt(u, v);
        int cost = c.get(p);
        float pdX = pLeft[u];
        float pdY = pRight[v];

        float cp = cost - pdX + pdY;

        return cp;
    }

    public float getFlow(int u, int v) {

        if (u == sourceNode) {
            return sourceToLeftF.get(v);
        } else if (v == sinkNode) {
            return rightToSinkF.get(u);
        }

        return f.get(new PairInt(u, v));
    }

    protected float calcSourceNetCost(int v) {

        int cost = sourceToLeftC.get(v);
        float pdX = pLeft[sourceNode];
        float pdY = pLeft[v];

        float cp = cost - pdX + pdY;

        return cp;
    }

    protected float calcSinkNetCost(int u) {

        int cost = rightToSinkC.get(u);
        float pdX = pRight[u];
        float pdY = pRight[sinkNode];

        float cp = cost - pdX + pdY;

        return cp;
    }

    public float calcNetCost(PairInt p) {
        return calcNetCost(p.getX(), p.getY());
    }

    /**
     * assertion, pg 44, I1.
     * The flux f on NG is a flow of value |f|=s
     * @param s
     * @return
     */
    boolean assertFlowValue(int s) {

        //Should this be for the integral flow only?
        double flow = calcTotalFlow();

        log.fine("assert I1: flow=" + flow + " s=" + s);

        return (Math.abs(flow - s) < 1);
    }

    boolean printFlowValueIncludingSrcSnk(int s) {

        log.fine("s=" + s);

        double flow = 0;

        flow += calcTotalFlow();

        log.fine("bipartite flow sum=" + flow);

        flow += calcTotalSourceFlow();

        log.fine("bipartite + source flow sum=" + flow);

        flow += calcTotalSinkFlow();

        log.fine("bipartite + source + sink flow sum=" + flow);

        return true;
    }

    /**
     * assert pg 52, I1'.
     * assert that flux f on NG is a flow of value |f|=s
     * @param nMatchingsHK the number of matched
     * nodes from hopcroft-karp before refine is invoked.
     * @return the number of surplus nodes which is the same
     * as the number of deficit nodes.  this may be smaller
     * than nMatchingsHK after an iteration of refine
     */
    boolean assertFlowValueIncludingSrcSnk(int nMatchingsHK) {

        double flow = 0;

        // NOTE: not completely sure about the intended assertion,
        // but I'm assuming that in refine, after zeroing
        // the bipartite matched flow then raising prices
        // and changing arc lengths, and then augemtning paths,
        // one has a matching
        // between the surplus and deficit nodes.
        // the matching might only be one node for example,
        // the the bipartite flow sum is 1, and the
        // that equals the number of hopcroftkarp matchings
        // minus the updated number of surplus matchings

        flow += calcTotalFlow();

        log.fine("bipartite flow sum=" + flow);

        // nSurplus is the number of nodes, excluding the
        // sink where the flow into the node is larger
        // than the flow leaving the sink.

        TIntHashSet surplus = new TIntHashSet();
        getSurplusRightIndexes(surplus);
        assert(surplus.isEmpty());

        getSurplusLeftIndexes(surplus);

        int nSurplus = surplus.size();

        log.fine("s=" + nMatchingsHK + " h=" + nSurplus);

        return (Math.abs(flow - (nMatchingsHK - nSurplus)) < 1);
    }

    public boolean printSurplusAndDeficit() {

        TIntHashSet surplus = new TIntHashSet();
        getSurplusLeftIndexes(surplus);

        TIntHashSet deficit = new TIntHashSet();
        getDeficitRightIndexes(deficit);

        StringBuilder sb = new StringBuilder("surplus=(");
        TIntIterator iter = surplus.iterator();
        while (iter.hasNext()) {
            int s = iter.next();
            sb.append(Integer.toString(s)).append(", ");
        }
        sb.append(")");
        log.fine(sb.toString());

        sb = new StringBuilder("deficit=(");
        iter = deficit.iterator();
        while (iter.hasNext()) {
            int d = iter.next();
            sb.append(Integer.toString(d)).append(", ");
        }
        sb.append(")");
        log.fine(sb.toString());

        return true;
    }

    double calcTotalSourceFlow() {

        double flow = 0;

        TIntIterator iter = sourceForwardArcs.iterator();
        while (iter.hasNext()) {
            int idx = iter.next();
            float unitFlow = sourceToLeftF.get(idx);
            flow += unitFlow;
        }

        return flow;
    }

    double calcTotalSinkFlow() {

        double flow = 0;

        TIntIterator iter = sinkForwardArcs.iterator();
        while (iter.hasNext()) {
            int idx = iter.next();
            float unitFlow = rightToSinkF.get(idx);
            flow += unitFlow;
        }

        return flow;
    }

    /**
     * assert pg 44, I2.
     * the prices at all nodes are multiples of eps
     * @param eps
     * @return
     */
    boolean assertPricesAreQuantizedEps(float eps) {

        double tolerance = 0.01;

        for (int i = 0; i < pLeft.length; ++i) {
            float p = pLeft[i];
            float div = p/eps;
            double r = div - Math.floor(div);
            if (r > 0.05) {
                return false;
            }
        }

        return true;
    }

    /**
     * raise prices on all nodes so that every arc becomes eps-proper,
     * for the resulting pseudoflow f
     * @param eps
     * @param q
     */
    public void raisePricesUntilEpsProper(float eps, int q) {

        float delta = (q - 1.f) * eps;

        float qEps = q * eps;

        log.fine("delta=" + delta + " qEps=" + qEps);

        //see Figure 7.4, pg 53
        // looks like the price raise is multiples of (q-1)*eps

        TIntIterator iter = sourceForwardArcs.iterator();
        // calc for source dummy arcs
        while (iter.hasNext()) {
            int xIdx = iter.next();
            float unitFlow = sourceToLeftF.get(xIdx);
            float cp = calcSourceNetCost(xIdx);

            if (unitFlow == 0) {
                // idle, cp > -qEps
                //cp = cost - pdX + pdY so inr pdY
                float count = 1.f;
                while (cp <= -qEps) {
                    pLeft[xIdx] += (count * delta);
                    cp = calcSourceNetCost(xIdx);
                    log.fine("raise price of left for source arc"
                        + xIdx + " to cp=" + cp);
                }
            } else if (Math.abs(unitFlow - 1) < 0.01f) {
                // saturated
                //cp = cost - pdX + pdY so incr pdX
                float count = 1.f;
                while (cp > qEps) {
                    pLeft[sourceNode] += (count * delta);
                    cp = calcSourceNetCost(xIdx);
                    log.fine("lower price of left for source arc"
                        + xIdx + " to cp=" + cp);
                }
            }
        }

        TIntObjectIterator<TIntSet> iter2 = forwardArcs.iterator();
        for (int ii = forwardArcs.size(); ii-- > 0;) {
            iter2.advance();
            int idx1 = iter2.key();
            TIntIterator iter3 = iter2.value().iterator();
            while (iter3.hasNext()) {
                int idx2 = iter3.next();
                PairInt p = new PairInt(idx1, idx2);
                float unitFlow = f.get(p);
                float cp = calcNetCost(p);
                if (unitFlow == 0) {
                    // idle, cp > -qEps
                    //cp = cost - pdX + pdY, so incr pdY
                    float count = 1.f;
                    while (cp <= -qEps) {
                        pRight[idx2] += (count * delta);
                        cp = calcNetCost(p);
                        log.fine("raise price of right " + idx2 +
                            " to cp=" + cp);
                    }
                } else if (Math.abs(unitFlow - 1) < 0.01f) {
                    // saturated, cp <= qEps
                    //cp = cost - pdX + pdY, so incr pdX
                    while (cp > qEps) {
                        float count = 1.f;
                        pLeft[idx1] += (count * delta);
                        cp = calcNetCost(p);
                        log.fine("lower price of left " + idx1 +
                            " to cp=" + cp);
                    }
                }
            }
        }

        TIntIterator iter3 = sinkForwardArcs.iterator();
        // calc for sink dummy arcs
        while (iter3.hasNext()) {
            int yIdx = iter3.next();
            float unitFlow = rightToSinkF.get(yIdx);
            float cp = calcSinkNetCost(yIdx);

            if (unitFlow == 0) {
                // idle, cp > -qEps
                //cp = cost - pdX + pdY so inr pdY
                // where pdX is pRight and pdY is pRight[sink]
                float count = 1.f;
                while (cp <= -qEps) {
                    pRight[sinkNode] += (count * delta);
                    cp = calcSinkNetCost(yIdx);
                    log.fine("raise price of right for sink arc"
                        + sinkNode + " to cp=" + cp);
                }
            } else if (Math.abs(unitFlow - 1) < 0.01f) {
                // saturated
                //cp = cost - pdX + pdY so incr pdX
                float count = 1.f;
                while (cp > qEps) {
                    pRight[yIdx] += (count * delta);
                    cp = calcSinkNetCost(yIdx);
                    log.fine("lower price of right for sink arc"
                        + yIdx + " to cp=" + cp);
                }
            }
        }
    }

    /**
     * Every arc of NG, idle or saturated, is eps-proper.
     * all bipartite arcs are asserted, but not sink and source
     * @param eps
     * @return
     */
    boolean integralBipartiteFlowIsEpsProper(float eps) {

        TIntObjectIterator<TIntSet> iter2 = forwardArcs.iterator();
        for (int ii = forwardArcs.size(); ii-- > 0;) {
            iter2.advance();
            int idx1 = iter2.key();
            TIntIterator iter3 = iter2.value().iterator();
            while (iter3.hasNext()) {
                int idx2 = iter3.next();

                PairInt p = new PairInt(idx1, idx2);
                float unitFlow = f.get(p);
                int cp = (int)Math.ceil(calcNetCost(p));
                if (unitFlow == 0) {
                    // idle, cp > -epsT
                    if (cp <= -eps) {
                        return false;
                    }
                } else if (Math.abs(unitFlow - 1) < 0.01f) {
                    // saturated
                    if (cp > eps) {
                        return false;
                    }
                }
            }
        }

        return true;
    }

    /**
     * assert pg 44 I3.
     * Every arc of NG, idle or saturated, is eps-proper.
     * all bipartite arcs and sink and source arcs should be eps-proper.
     * @param eps
     * @return
     */
    boolean integralFlowIsEpsProper(float eps) {

        TIntObjectIterator<TIntSet> iter2 = forwardArcs.iterator();
        for (int ii = forwardArcs.size(); ii-- > 0;) {
            iter2.advance();
            int idx1 = iter2.key();
            TIntIterator iter3 = iter2.value().iterator();
            while (iter3.hasNext()) {
                int idx2 = iter3.next();

                PairInt p = new PairInt(idx1, idx2);
                float unitFlow = f.get(p);
                int cp = (int)Math.ceil(calcNetCost(p));
                if (unitFlow == 0) {
                    // idle, cp > -epsT
                    if (cp <= -eps) {
                        log.severe(String.format(
                            "NOT EPS-PROPER f=%.2f  cp=%.3f  eps=%.3f idx=%d to %d",
                            unitFlow, cp, eps, idx1, idx2));
                        return false;
                    }
                } else if (Math.abs(unitFlow - 1) < 0.01f) {
                    // saturated
                    if (cp > eps) {
                        log.severe(String.format(
                            "NOT EPS-PROPER f=%.2f  cp=%.3f  eps=%.3f idx=%s td %d",
                            unitFlow, cp, eps, idx1, idx2));
                        return false;
                    }
                }
            }
        }

        TIntIterator iter = sourceForwardArcs.iterator();
        while (iter.hasNext()) {
            int idx1 = iter.next();
            float unitFlow = sourceToLeftF.get(idx1);
            int cp = (int)Math.ceil(calcSourceNetCost(idx1));
            if (unitFlow == 0) {
                // idle, cp > -epsT
                if (cp <= -eps) {
                    log.severe(String.format(
                        "NOT EPS-PROPER f=%.2f  cp=%.3f  eps=%.3f source to %d",
                        unitFlow, cp, eps, idx1));
                }
            } else if (Math.abs(unitFlow - 1) < 0.01f) {
                // saturated
                if (cp > eps) {
                    log.severe(String.format(
                        "NOT EPS-PROPER f=%.2f  cp=%.3f  eps=%.3f source to %d",
                        unitFlow, cp, eps, idx1));
                    return false;
                }
            }
        }

        TIntIterator iter1 = sinkForwardArcs.iterator();
        while (iter1.hasNext()) {
            int idx1 = iter1.next();
            float unitFlow = rightToSinkF.get(idx1);
            int cp = (int)Math.ceil(calcSinkNetCost(idx1));
            if (unitFlow == 0) {
                // idle, cp > -epsT
                if (cp <= -eps) {
                    log.severe(String.format(
                        "NOT EPS-PROPER f=%.2f  cp=%.3f  eps=%.3f %d to sink",
                        unitFlow, cp, eps, idx1));
                    return false;
                }
            } else if (Math.abs(unitFlow - 1) < 0.01f) {
                // saturated
                if (cp > eps) {
                    log.severe(String.format(
                        "NOT EPS-PROPER f=%.2f  cp=%.3f  eps=%.3f %d to sink",
                        unitFlow, cp, eps, idx1));
                    return false;
                }
            }
        }

        return true;
    }

    /**
     * Every arc of the network flow, idle or saturated, is proper.
     * @return
     */
    public boolean integralFlowIsProper() {

        TIntObjectIterator<TIntSet> iter = forwardArcs.iterator();
        for (int ii = forwardArcs.size(); ii-- > 0;) {
            iter.advance();
            int idx1 = iter.key();
            TIntIterator iter2 = iter.value().iterator();
            while (iter2.hasNext()) {
                int idx2 = iter2.next();
                PairInt p = new PairInt(idx1, idx2);
                float unitFlow = f.get(p);
                int cp = (int)Math.ceil(calcNetCost(p));
                if (unitFlow == 0) {
                    // idle, cp >= 0
                    if (cp < -0.0f) {
                        return false;
                    }
                } else if (Math.abs(unitFlow - 1) < 0.01f) {
                    // saturated
                    if (cp > 0.0f) {
                        return false;
                    }
                }
            }
        }

        return true;
    }

    /**
     * assert pg 44, I4.
     * Every saturated bipartite arc is eps-snug.
     * @param eps
     * @return
     */
    boolean assertSaturatedBipartiteIsEpsSnug(float eps) {

        TIntObjectIterator<TIntSet> iter = forwardArcs.iterator();
        for (int ii = forwardArcs.size(); ii-- > 0;) {
            iter.advance();
            int idx1 = iter.key();

            if (idx1 == sourceNode) {
                continue;
            }

            TIntIterator iter3 = iter.value().iterator();
            while (iter3.hasNext()) {
                int idx2 = iter3.next();
                if (idx2 == sinkNode) {
                    continue;
                }
                PairInt p = new PairInt(idx1, idx2);
                float unitFlow = f.get(p);
                int cp = (int)Math.ceil(calcNetCost(p));
                if (Math.abs(unitFlow - 1) < 0.01f) {
                    // saturated
                    // snug is -eps < cp <= eps
                    if ((cp <= -eps) || (cp > eps)) {
                        log.severe(String.format(
                            "NOT EPS-SNUG f=%.2f  cp=%.3f  eps=%.3f idx=%d to %d",
                            unitFlow, cp, eps, idx1, idx2));
                        return false;
                    }
                }
            }
        }

        return true;
    }

    public void getSurplusLeftIndexes(TIntSet surplus) {

        for (int i = 0; i < nLeft; ++i) {

            float flowInto = 0;
            float flowOutOf = 0;
            // flow into left from source
            if (sourceForwardArcs.contains(i)) {
                flowInto += sourceToLeftF.get(i);
            }
            TIntSet set = forwardArcs.get(i);
            if (set != null) {
                TIntIterator iter2 = set.iterator();
                while (iter2.hasNext()) {
                    int idx2 = iter2.next();
                    PairInt p = new PairInt(i, idx2);
                    flowOutOf += f.get(p);
                }
            }
            if (flowInto > flowOutOf) {
                surplus.add(i);
            }
        }
    }

    public void getDeficitRightIndexes(TIntSet deficit) {

        // key = right, values = left
        TIntObjectMap<TIntSet> revMap = MatrixUtil.createReverseMap(forwardArcs);

        for (int i = 0; i < nRight; ++i) {

            float flowInto = 0;
            float flowOutOf = 0;
            // flow out of right to sink
            if (sinkForwardArcs.contains(i)) {
                flowOutOf += rightToSinkF.get(i);
            }
            TIntSet set = revMap.get(i);
            if (set != null) {
                TIntIterator iter2 = set.iterator();
                while (iter2.hasNext()) {
                    int left = iter2.next();
                    PairInt p = new PairInt(left, i);
                    flowInto += f.get(p);
                }
            }

            if (flowInto < flowOutOf) {
                deficit.add(i);
            }
        }
    }

    private void getSurplusRightIndexes(TIntSet surplus) {

        for (int i = 0; i < nRight; ++i) {

            float flowInto = 0;
            float flowOutOf = 0;
            // flow into right from left node

            TIntObjectIterator<TIntSet> iter2 = forwardArcs.iterator();
            for (int ii = forwardArcs.size(); ii-- > 0;) {
                iter2.advance();
                int idx1 = iter2.key();
                TIntSet set = iter2.value();
                if (set.contains(i)) {
                    PairInt p = new PairInt(idx1, i);
                    flowInto += f.get(p);
                }
            }

            // flow from right to sink
            if (sinkForwardArcs.contains(i)) {
                flowOutOf += rightToSinkF.get(i);
            }

            if (flowInto > flowOutOf) {
                surplus.add(i);
            }
        }
    }

    /*
     the flow network uses forward arcs with "ceiling quantization".
     - the ceiling quantization is the choice of
     "eps-properness" for idle and saturated arcs whose
     net cost are equal to eps.
     those have been incorporated into integralFlowIsEpsProper
     - an idle arc v->w is eps-tight when -eps < cp(v,w) <= 0,
     while a saturated arc v->w is eps-tight when
     0 < cp(v,w) <= eps
     NOTE that eps-tight arcs are just barely eps-proper.
    */

    public TIntObjectHashMap<TIntSet> getForwardArcs() {
        return forwardArcs;
    }

    public TObjectIntHashMap<PairInt> getCosts() {
        return c;
    }

    public TObjectFloatHashMap<PairInt> getFlow() {
        return f;
    }

    public void setLeftPrice(int idx, float value) {
        pLeft[idx] = value;
    }

    public void setRightPrice(int idx, float value) {
        log.fine("add to right " + idx + " : " + pRight[idx]
            + "  + " + value + " = " + (pRight[idx] + value));
        pRight[idx] = value;
    }

    public void addToLeftPrice(int idx, float value) {
        log.fine("add to left " + idx + " : " + pLeft[idx]
            + " + " + value + " = " + (pLeft[idx] + value));
        pLeft[idx] += value;
    }

    public void addToSourcePrice(float value) {
        log.fine("add to source : " + pLeft[sourceNode]
            + " + " + value + " = " + (pLeft[sourceNode] + value));
        pLeft[sourceNode] += value;
    }

    public void addToSinkPrice(float value) {
        log.fine("add to sink : " + pLeft[sinkNode]
            + " + " + value + " = " + (pLeft[sinkNode] + value));
        pLeft[sinkNode] += value;
    }

    public void addToRightPrice(int idx, float value) {
        pRight[idx] += value;
    }

    public float getLeftPrice(int idx) {
        return pLeft[idx];
    }

    public float getRightPrice(int idx) {
        return pRight[idx];
    }

    /**
     * @return the number of left vertices
     */
    public int getNLeft() {
        return nLeft;
    }

    /**
     * @return the number of right vertices
     */
    public int getNRight() {
        return nRight;
    }

    public int getSinkNode() {
        return sinkNode;
    }

    public int getSourceNode() {
        return sourceNode;
    }

    public TIntSet getSourceForwardArcs() {
        return sourceForwardArcs;
    }

    public TIntSet getSinkForwardArcs() {
        return sinkForwardArcs;
    }

    public void augmentSourceToLeftFlowAndArc(int idx) {

        if (sourceToLeftC.containsKey(idx)) {
            float flow = sourceToLeftF.get(idx);
            if (Math.abs(flow) < 0.01) {
                // idle, so change to "saturated"
                sourceToLeftF.put(idx, 1);
                sourceForwardArcs.add(idx);
            } else if (Math.abs(flow - 1.) < 0.01) {
                // saturated, so change to "idle"
                sourceToLeftF.put(idx, 0);
                //TODO: consider not removing this
                //sourceForwardArcs.remove(index);
            } else {
                throw new IllegalStateException(
                "Error in algorithm.  not expecting"
                + " a fractional flow");
            }
        }
    }

    public void augmentRightToSinkFlowAndArc(int idx) {

        if (rightToSinkF.containsKey(idx)) {
            float flow = rightToSinkF.get(idx);
            if (Math.abs(flow) < 0.01) {
                // idle, so change to "saturated"
                rightToSinkF.put(idx, 1);
                sinkForwardArcs.add(idx);
            } else if (Math.abs(flow - 1.) < 0.01) {
                // saturated, so change to "idle"
                rightToSinkF.put(idx, 0);
                // TODO: consider not removing this:
                //sinkForwardArcs.remove(idx);
            } else {
                throw new IllegalStateException(
                    "Error in algorithm.  not expecting"
                    + " a fractional flow");
            }
        }
    }

    public void augmentFlowAndArc(int idx1, int idx2) {

        assert(forwardArcs.containsKey(idx1)
            && forwardArcs.get(idx1)
            .contains(idx2));

        PairInt p = new PairInt(idx1, idx2);

        float flow = f.get(p);
        if (Math.abs(flow - 1.) < 0.01) {
            // saturated, so change to "idle"
            f.put(p, 0);
        } else if (Math.abs(flow) < 0.01) {
            // idle, so change to "saturated"
            f.put(p, 1);

            // should the source and sink
            // arcs be reversed too?

        } else {
            throw new IllegalStateException(
                "Error in algorithm.  not expecting"
                + " a fractional flow");
        }
    }

    public int calculateNumberOfSaturatedArcs() {

        int n = 0;

        TIntObjectIterator<TIntSet> iter = forwardArcs.iterator();
        for (int ii = forwardArcs.size(); ii-- > 0;) {
            iter.advance();
            int idx1 = iter.key();
            TIntSet rightIdxs = iter.value();
            TIntIterator iter2 = rightIdxs.iterator();
            while (iter2.hasNext()) {
                int idx2 = iter2.next();
                PairInt p = new PairInt(idx1, idx2);
                float unitFlow = f.get(p);
                float cp = calcNetCost(p);
                if (Math.abs(unitFlow - 1) < 0.01f) {
                    n++;
                }
            }
        }

        return n;
    }

    public void printSaturatedLinks() {

        TIntObjectIterator<TIntSet> iter = forwardArcs.iterator();
        for (int ii = forwardArcs.size(); ii-- > 0;) {
            iter.advance();
            int idx1 = iter.key();
            TIntSet rightIdxs = iter.value();
            TIntIterator iter2 = rightIdxs.iterator();
            while (iter2.hasNext()) {
                int idx2 = iter2.next();
                PairInt p = new PairInt(idx1, idx2);
                float unitFlow = f.get(p);
                float cp = calcNetCost(p);
                if (Math.abs(unitFlow - 1) < 0.01f) {
                    // saturated are matched arcs
                    log.fine("saturated bipartite arc from " +
                        idx1 + " to " + idx2);
                }
            }
        }

    }

    public void printNetCosts() {

        StringBuilder sb = new StringBuilder();

        TIntObjectIterator<TIntSet> iter = forwardArcs.iterator();
        for (int ii = forwardArcs.size(); ii-- > 0;) {
            iter.advance();
            int idx1 = iter.key();
            TIntSet rightIdxs = iter.value();
            TIntIterator iter2 = rightIdxs.iterator();
            while (iter2.hasNext()) {
                int idx2 = iter2.next();
                PairInt p = new PairInt(idx1, idx2);
                float unitFlow = f.get(p);
                float cp = calcNetCost(p);

                sb.append(String.format("%d to %d cp=%.2f f=%.2f%n",
                    idx1, idx2, cp, unitFlow));
            }
        }
        log.fine(sb.toString());

        sb = new StringBuilder();

        TIntIterator iter2 = sourceForwardArcs.iterator();
        while (iter2.hasNext()) {
            int idx1 = iter2.next();

            float unitFlow = sourceToLeftF.get(idx1);
            float cp = calcSourceNetCost(idx1);
            sb.append(String.format("source to %d cp=%.2f f=%.2f%n",
                idx1, cp, unitFlow));
        }
        log.fine(sb.toString());

        sb = new StringBuilder();
        iter2 = sinkForwardArcs.iterator();
        while (iter2.hasNext()) {
            int idx1 = iter2.next();
            float unitFlow = rightToSinkF.get(idx1);
            float cp = calcSinkNetCost(idx1);
            sb.append(String.format("%d to sink cp=%.2f f=%.2f%n",
                idx1, cp, unitFlow));
        }
        log.fine(sb.toString());
    }

    public TIntIntMap extractMatches() {

        TIntIntMap m = new TIntIntHashMap();

        TIntObjectIterator<TIntSet> iter = forwardArcs.iterator();
        for (int ii = forwardArcs.size(); ii-- > 0;) {
            iter.advance();
            int idx1 = iter.key();
            TIntSet rightIdxs = iter.value();
            TIntIterator iter2 = rightIdxs.iterator();
            while (iter2.hasNext()) {
                int idx2 = iter2.next();
                PairInt p = new PairInt(idx1, idx2);
                float unitFlow = f.get(p);
                float cp = calcNetCost(p);
                if (Math.abs(unitFlow - 1) < 0.01f) {
                    m.put(idx1, idx2);
                }
            }
        }

        return m;
    }

    /**
     * given value, modify prices such that
     * //pd^~(v) = math.floor(pd(v) + value)
     * @param value
     */
    public void addToAllPrices(float value) {

        for (int i = 0; i < nLeft; ++i) {
            pLeft[i] = (float)Math.floor(pLeft[i] + value);
        }

        for (int i = 0; i < nRight; ++i) {
            pRight[i] = (float)Math.floor(pRight[i] + value);
        }
    }

    public void zeroTheMatchedBipartiteFlow(TIntSet outPutSurplus,
        TIntSet outPutDeficit) {

        outPutSurplus.clear();
        outPutDeficit.clear();

        TIntObjectIterator<TIntSet> iter = forwardArcs.iterator();
        for (int ii = forwardArcs.size(); ii-- > 0;) {
            iter.advance();
            int idx1 = iter.key();
            TIntSet rightIdxs = iter.value();
            TIntIterator iter2 = rightIdxs.iterator();
            while (iter2.hasNext()) {
                int idx2 = iter2.next();
                PairInt p = new PairInt(idx1, idx2);
                float unitFlow = f.get(p);
                float cp = calcNetCost(p);

                if (Math.abs(unitFlow - 1) < 0.01f) {
                    // saturated are matched arcs
                    outPutSurplus.add(idx1);
                    outPutDeficit.add(idx2);
                    f.put(p, 0);
                }
            }
        }
    }

    public void createPathNodes() {
        if (pathNodes == null) {
            pathNodes = new PathNodes(nLeft, nRight);
        }
    }

    public void resetPathNodes(long key) {
        if (pathNodes == null) {
            pathNodes = new PathNodes(nLeft, nRight);
        } else {
            pathNodes.resetNodeExceptData(key);
        }
    }

    public PathNodes getPathNodes() {
        return pathNodes;
    }

}