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

net.sf.opendse.optimization.constraints.SpecificationCapacityConstraints Maven / Gradle / Ivy

There is a newer version: 1.8
Show newest version
/**
 * OpenDSE is free software: you can redistribute it and/or modify it under the
 * terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation, either version 3 of the License, or (at your option) any
 * later version.
 * 
 * OpenDSE 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 Lesser General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with OpenDSE. If not, see http://www.gnu.org/licenses/.
 */
package net.sf.opendse.optimization.constraints;

import static net.sf.opendse.model.Models.filterCommunications;
import static net.sf.opendse.model.Models.getLinks;
import static net.sf.opendse.optimization.encoding.variables.Variables.p;
import static net.sf.opendse.optimization.encoding.variables.Variables.var;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import net.sf.opendse.model.Application;
import net.sf.opendse.model.Architecture;
import net.sf.opendse.model.Dependency;
import net.sf.opendse.model.Element;
import net.sf.opendse.model.Link;
import net.sf.opendse.model.Mapping;
import net.sf.opendse.model.Mappings;
import net.sf.opendse.model.Resource;
import net.sf.opendse.model.Routings;
import net.sf.opendse.model.Specification;
import net.sf.opendse.model.Task;
import net.sf.opendse.model.Models.DirectedLink;
import net.sf.opendse.optimization.SpecificationWrapper;

import org.opt4j.satdecoding.Constraint;
import org.opt4j.satdecoding.Constraint.Operator;
import org.opt4j.satdecoding.Literal;
import org.opt4j.satdecoding.Model;
import org.opt4j.satdecoding.Term;

import com.google.inject.Inject;

public class SpecificationCapacityConstraints extends AbstractSpecificationConstraints implements SpecificationConstraints {

	protected final Specification specification;
	protected final Set> capacityConstraints = new HashSet>();

	@Inject
	public SpecificationCapacityConstraints(SpecificationWrapper specification) {
		super();
		this.specification = specification.getSpecification();
		this.capacityConstraints.addAll(getCapacityConstraints(this.specification));

		initConstraints();
	}

	protected void initConstraints() {
		Architecture architecture = specification.getArchitecture();
		Routings routings = specification.getRoutings();

		for (CapacityConstraint capacityConstraint : capacityConstraints) {
			Element element = capacityConstraint.getElement();
			String attribute = capacityConstraint.getAttribute();
			Map elements = capacityConstraint.getElements();

			ParameterObject cap = getParameter(element, attribute + CAPACITY);
			ParameterObject min = getParameter(element, attribute + CAPACITY_MIN);
			ParameterObject max = getParameter(element, attribute + CAPACITY_MAX);

			if (cap.isNull() && max.isNull() && min.isNull()) {
				throw new IllegalArgumentException("No capacity bound set for " + element + " with attribute "
						+ attribute);
			}

			if (min.isNull() && max.isNull()) {
				max = cap;
			}

			List terms = new ArrayList();

			for (Entry entry : elements.entrySet()) {
				Element e = entry.getKey();
				int value = entry.getValue();
				if (e instanceof Mapping) {
					Term term = new Term(value, p(e));
					terms.add(term);
				} else if (e instanceof Task) { // assume its a
												// communication task
					Task task = (Task) e;
					Architecture routing = routings.get(task);
					if (element instanceof Resource && routing.containsVertex((Resource) element)) {
						Term term = new Term(value, p(var(task, (Resource) element)));
						terms.add(term);
					} else if (element instanceof Link && routing.containsEdge((Link) element)) {
						for (DirectedLink lrr : getLinks(architecture, (Link) element)) {
							Term term = new Term(value, p(var(task, lrr)));
							terms.add(term);
						}
					}
				}
			}

			// System.out.println(elements);
			// System.out.println(terms);

			// TODO Scale?
			//Integer scale = element.getAttribute(attribute + CAPACITY_SCALE);

			if (!max.isNull()) {
				Constraint cmax = new Constraint("<=", 0);
				cmax.addAll(terms);

				if (!max.isParameter()) {
					cmax.setRhs(max.getInteger());
				} else {
					Constraint eq = new Constraint("=", 0);
					for (Term term : getParameterTerms(element, max)) {
						Term t = new Term(-term.getCoefficient(), term.getLiteral());
						cmax.add(t);
						eq.add(1, term.getLiteral());
					}
					eq.add(-1, p(element));
					constraints.add(eq);
				}
				constraints.add(cmax);
			}

			if (!min.isNull()) {
				Constraint cmin = new Constraint(">=", 0);
				cmin.addAll(terms);

				if (!min.isParameter()) {
					cmin.add(-min.getInteger(), p(element));
				} else {
					Constraint eq = new Constraint("=", 0);
					for (Term term : getParameterTerms(element, min)) {
						Term t = new Term(-term.getCoefficient(), term.getLiteral());
						cmin.add(t);
						eq.add(1, term.getLiteral());
					}
					eq.add(-1, p(element));
					constraints.add(eq);
				}
				constraints.add(cmin);
			}
		}
	}

	protected Set> getCapacityConstraints(Specification specification) {
		Set> capacityConstraints = new HashSet>();

		Architecture architecture = specification.getArchitecture();
		Application application = specification.getApplication();
		Mappings mappings = specification.getMappings();
		Routings routings = specification.getRoutings();

		Set allElements = new HashSet();
		allElements.addAll(architecture.getVertices());
		allElements.addAll(architecture.getEdges());

		for (Element e : allElements) {
			Set attributeNames = e.getAttributeNames();

			Set visited = new HashSet();

			for (String attributeName : attributeNames) {
				if (isCapacity(attributeName)) {
					String name = getName(attributeName);

					if (!visited.contains(name)) {
						visited.add(name);

						String action = e.getAttribute(name + CAPACITY_ACTION);

						boolean bM = (action != null) ? action.contains("M") : true;
						boolean bT = (action != null) ? action.contains("T") : true;
						boolean bC = (action != null) ? action.contains("C") : true;

						Map elements = new HashMap();

						if ((bM || bT) && e instanceof Resource) {
							for (Mapping mapping : mappings.get((Resource) e)) {
								Integer v = null;
								if (bM) {
									v = mapping.getAttribute(name);
								}
								if (bT && v == null) {
									v = mapping.getSource().getAttribute(name);
								}
								if (v != null && v != 0) {
									elements.put(mapping, v);
								}
							}
						}

						if (bC) {
							for (Task communication : filterCommunications(application)) {
								Integer v = communication.getAttribute(name);

								if (v != null && v != 0) {
									Architecture routing = routings.get(communication);

									boolean isIn = false;
									if (e instanceof Resource && routing.containsVertex((Resource) e)) {
										isIn = true;
									} else if (e instanceof Link && routing.containsEdge((Link) e)) {
										isIn = true;
									}

									if (isIn) {
										elements.put(communication, v);
									}
								}

							}
						}

						CapacityConstraint capacityConstraint = null;

						if (e instanceof Resource) {
							capacityConstraint = new CapacityConstraint((Resource) e, name, elements);
						} else { // e instanceof Link
							capacityConstraint = new CapacityConstraint((Link) e, name, elements);
						}
						capacityConstraints.add(capacityConstraint);
					}
				}

			}
		}
		return capacityConstraints;
	}

	private static class CapacityConstraint {

		protected final E element;
		protected final String attribute;
		protected final Map elements;

		public CapacityConstraint(E element, String attribute, Map elements) {
			super();
			this.element = element;
			this.attribute = attribute;
			this.elements = elements;
		}

		public E getElement() {
			return element;
		}

		public String getAttribute() {
			return attribute;
		}

		public Map getElements() {
			return elements;
		}

	}

	protected static boolean isCapacity(String attributeName) {
		return attributeName.contains(CAPACITY);
	}

	public static String getName(String attributeName) {
		return attributeName.split(":")[0];
	}

	@Override
	public void doInterpreting(Specification implementation, Model model) {

		for (CapacityConstraint capacityConstraint : getCapacityConstraints(implementation)) {
			Element element = capacityConstraint.getElement();
			String attribute = capacityConstraint.getAttribute();
			Map elements = capacityConstraint.getElements();

			ParameterObject cap = getParameter(element.getParent(), attribute + CAPACITY);
			ParameterObject min = getParameter(element.getParent(), attribute + CAPACITY_MIN);
			ParameterObject max = getParameter(element.getParent(), attribute + CAPACITY_MAX);

			// System.err.println(ViewUtil.getTooltip(element));

			if (!cap.isNull() && cap.isParameter()) {
				Set terms = getParameterTerms(element.getParent(), cap);
				for (Term term : terms) {
					if (model.get(term.getLiteral().variable())) {
						element.setAttribute(attribute + CAPACITY, term.getCoefficient());
					}
				}
			}
			if (!max.isNull() && max.isParameter()) {
				Set terms = getParameterTerms(element.getParent(), max);
				for (Term term : terms) {
					if (model.get(term.getLiteral().variable())) {
						element.setAttribute(attribute + CAPACITY_MAX, term.getCoefficient());
					}
				}
			}
			if (!min.isNull() && min.isParameter()) {
				Set terms = getParameterTerms(element.getParent(), min);
				for (Term term : terms) {
					if (model.get(term.getLiteral().variable())) {
						element.setAttribute(attribute + CAPACITY_MIN, term.getCoefficient());
					}
				}
			}

			int value = 0;
			for (int v : elements.values()) {
				value += v;
			}

			element.setAttribute(attribute + CAPACITY_VALUE, value);

			Integer vcap = element.getAttribute(attribute + CAPACITY);
			Integer vmin = element.getAttribute(attribute + CAPACITY_MIN);
			Integer vmax = element.getAttribute(attribute + CAPACITY_MAX);

			int c = 0;

			if (vcap != null) {
				c = vcap;
			} else if (vmax != null) {
				c = vmax;
			} else if (vmin != null) {
				c = vmin;
			}

			double ratio = (double) value / (double) c;

			element.setAttribute(attribute + CAPACITY_RATIO, ratio);

		}
	}



	@Deprecated
	protected Constraint scale(Constraint constraint, int scale) {
		if (constraint.getRhs() <= scale) {
			return constraint;
		}

		int rhs = constraint.getRhs();
		Operator op = constraint.getOperator();

		Constraint c = new Constraint(op, scale);

		double r = (double) scale / (double) rhs;

		for (Term term : constraint) {
			Literal lit = term.getLiteral();
			double coeff = term.getCoefficient() * r;

			switch (constraint.getOperator()) {
			case LE:
				coeff = Math.ceil(coeff);
				break;
			case GE:
				coeff = Math.floor(coeff);
				break;
			default:
				throw new IllegalArgumentException("cannot scale constraint " + constraint);
			}

			c.add((int) coeff, lit);
		}

		return c;
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy