All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.electric.database.topology.SteinerTree Maven / Gradle / Ivy

There is a newer version: 9.02-e
Show newest version
/* -*- tab-width: 4 -*-
 *
 * Electric(tm) VLSI Design System
 *
 * File: SteinerTree.java
 * Written by: Steven Rubin.
 *
 * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
 *
 * Electric(tm) is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * Electric(tm) is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Electric(tm); see the file COPYING.  If not, write to
 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 * Boston, Mass 02111-1307, USA.
 */
package com.sun.electric.database.topology;

import com.sun.electric.database.geometry.EPoint;

import java.util.ArrayList;
import java.util.List;

/**
 * Class for constructing a Steiner Tree.
 */
public class SteinerTree
{
	private List pairs;

	/**
	 * Interface to define a point in the Steiner Tree that needs to be organized properly.
	 * The PortInst class implements this.
	 */
	public interface SteinerTreePort
	{
		public EPoint getCenter();
	}

	/**
	 * Class that defines a branch of the Steiner Tree, with two SteinerTreePort objects.
	 */
	public static class SteinerTreePortPair
	{
		private SteinerTreePort p1, p2;

		public SteinerTreePortPair(SteinerTreePort p1, SteinerTreePort p2)
		{
			this.p1 = p1;
			this.p2 = p2;
		}

		public SteinerTreePort getPort1() { return p1; }

		public SteinerTreePort getPort2() { return p2; }
	}

	/**
	 * Constructor takes a list of 
	 * @param portList a List of SteinerTreePort objects that are to be organized into a Steiner Tree.
	 */
	public SteinerTree(List portList)
	{
		// the final list of edges in the Steiner tree
		pairs = new ArrayList();
		if (portList.size() < 2) return;

		// a list of points that are already in the tree (initially contains the first point, a random choice)
		List seen = new ArrayList();
		seen.add(portList.get(0));

		// initial list of points to be added to the tree (excluding the first point)
		List remaining = new ArrayList();
		for(int i=1; i 0)
		{
			// find the closest to anything in the Steiner tree
			double bestDist = Double.MAX_VALUE;
			SteinerTreePort bestRem = null, bestSeen = null;
			for(SteinerTreePort piRem : remaining)
			{
				for(SteinerTreePort piSeen : seen)
				{
					double dist = piRem.getCenter().distance(piSeen.getCenter());
					if (dist < bestDist)
					{
						bestDist = dist;
						bestRem = piRem;
						bestSeen = piSeen;
					}
				}					
			}
			if (bestRem != null)
			{
				SteinerTreePortPair pp = makeTreeBranch(bestRem, bestSeen);
				pairs.add(pp);
				remaining.remove(bestRem);
				seen.add(bestRem);
			}
		}
	}

	/**
	 * Overridable method to create a SteinerTreePortPair from two SteinerTreePort objects.
	 * @param p1 the first SteinerTreePort.
	 * @param p2 the second SteinerTreePort.
	 * @return a SteinerTreePortPair that encapsulates this branch of the Steiner Tree.
	 */
	public SteinerTreePortPair makeTreeBranch(SteinerTreePort p1, SteinerTreePort p2)
	{
		return new SteinerTreePortPair(p1, p2);
	}

	/**
	 * Method to return the Steiner Tree.
	 * @return a List of SteinerTreePortPair objects that describes the Steiner Tree.
	 */
	public List getTreeBranches()
	{
		return pairs;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy