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

bgu.dcr.az.api.prob.cpack.KAryTreeConstraintPackage Maven / Gradle / Ivy

/* 
 * The MIT License
 *
 * Copyright 2016 Benny Lutati.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package bgu.dcr.az.api.prob.cpack;

import bgu.dcr.az.api.Agt0DSL;
import bgu.dcr.az.api.prob.ComposedKAryConstraint;
import bgu.dcr.az.api.prob.ConstraintCheckResult;
import bgu.dcr.az.api.prob.KAryConstraint;
import bgu.dcr.az.api.tools.Assignment;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

/**
 *
 * @author bennyl
 */
public class KAryTreeConstraintPackage extends AbstractConstraintPackage {

    private Node[] roots;

    public KAryTreeConstraintPackage(int numvar) {
        super(numvar);
        roots = new Node[numvar];
        for (int i = 0; i < numvar; i++) {
            roots[i] = new Node();
        }
    }

    @Override
    public void setConstraintCost(int owner, int x1, int v1, int x2, int v2, int cost) {
        Agt0DSL.panic("cannot use binary or unary version of constraints in k-ary problem, use the setConstraintCost(int, int[], KAryConstraint) method instead.");
    }

    @Override
    public void setConstraintCost(int owner, int x1, int v1, int cost) {
        Agt0DSL.panic("cannot use binary or unary version of constraints in k-ary problem, use the setConstraintCost(int, int[], KAryConstraint) method instead.");
    }

    @Override
    public void getConstraintCost(int owner, int x1, int v1, ConstraintCheckResult result) {
        getConstraintCost(owner, new Assignment(x1, v1), result);
    }

    @Override
    public void getConstraintCost(int owner, int x1, int v1, int x2, int v2, ConstraintCheckResult result) {
        getConstraintCost(owner, new Assignment(x1, v1, x2, v2), result);
    }

    @Override
    public void getConstraintCost(int owner, Assignment k, ConstraintCheckResult result) {

        KAryConstraint constraint = roots[owner].getConstraint(k);
        if (constraint == null) {
            result.set(0, 0);
        } else {
            constraint.getCost(k, result);
        }
    }

    private void insertKAryConstraint(int owner, KAryConstraint constraint, boolean replace){
        roots[owner].add(constraint, replace);

        //update neighbores
        for (int p : constraint.getParicipients()) {
            if (owner != p) {
                addNeighbor(owner, p);
            }
        }
    }
    
    @Override
    public void setConstraintCost(int owner, KAryConstraint constraint) {
        insertKAryConstraint(owner, constraint, true);
    }

    /**
     * calculate the cost for the given assignment
     * @param owner
     * @param a
     * @param result 
     */
    @Override
    public void calculateCost(int owner, Assignment a, ConstraintCheckResult result) {
        List constraintsToConsider = roots[owner].collectAllSubConstraints(a);

        int cost = 0;
        int cc = 0;
        if (constraintsToConsider != null) {
            for (KAryConstraint constraint : constraintsToConsider) {
                constraint.getCost(a, result);
                cost += result.getCost();
                cc += result.getCheckCost();
            }
        }

        result.set(cost, cc);
    }

    @Override
    public int calculateGlobalCost(Assignment a) {
        ConstraintCheckResult res = new ConstraintCheckResult();
        int cost = 0;
        for (int i = 0; i < getNumberOfVariables(); i++) {
            calculateCost(i, a, res);
            cost += res.getCost();
        }
        return cost;
    }

    @Override
    public void addConstraintCost(int owner, KAryConstraint constraint) {
        insertKAryConstraint(owner, constraint, false);
    }

    private static class Node {

        ComposedKAryConstraint constraint = new ComposedKAryConstraint();
        Map childrens;

        public Node() {
            this.childrens = new HashMap<>();
        }

        public void add(KAryConstraint constraint, boolean replace) {
            int[] participients = constraint.getParicipients();
            Arrays.sort(participients);
            _add(constraint, participients, 0, replace);
        }

        private void _add(KAryConstraint constraint, int[] participients, int idx, boolean replace) {

            if (idx < participients.length) {
                Node children = childrens.get(participients[idx]);
                if (children == null) {
                    children = new Node();
                    childrens.put(participients[idx], children);
                }

                children._add(constraint, participients, idx + 1, replace);
            } else {
                if (replace) {
                    this.constraint.getComposition().clear();
                }
                this.constraint.getComposition().add(constraint);
            }
        }

        public KAryConstraint getConstraint(Assignment a) {
            List participients = extractParticipients(a);
            Node currentNode = this;
            for (Integer p : participients) {
                currentNode = currentNode.childrens.get(p);
                if (currentNode == null) {
                    return null;
                }
            }

            return currentNode.constraint;
        }

        public List collectAllSubConstraints(Assignment a) {
            LinkedList ret = new LinkedList<>();
            _collectAllSubConstraints(a.assignedVariables(), ret);
            return ret;
        }

        private void _collectAllSubConstraints(Set participients, List result) {
            if (constraint != null) {
                result.add(constraint);
            }

            for (Entry children : childrens.entrySet()) {
                if (participients.contains(children.getKey())) {
                    children.getValue()._collectAllSubConstraints(participients, result);
                }
            }
        }

        private List extractParticipients(Assignment a) {
            List participients = new ArrayList<>(a.assignedVariables());
            Collections.sort(participients);
            return participients;
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy