org.chocosolver.solver.constraints.graph.tree.PropReachability Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of choco-solver Show documentation
Show all versions of choco-solver Show documentation
Open-source constraint solver.
/*
* This file is part of choco-solver, http://choco-solver.org/
*
* Copyright (c) 2023, IMT Atlantique. All rights reserved.
*
* Licensed under the BSD 4-clause license.
*
* See LICENSE file in the project root for full license information.
*/
package org.chocosolver.solver.constraints.graph.tree;
import org.chocosolver.solver.exception.ContradictionException;
import org.chocosolver.solver.variables.DirectedGraphVar;
import org.chocosolver.util.ESat;
/**
* Every vertex is reachable from the root
* Removes unreachable nodes
* Enforces dominator nodes
* Enforces dominator arc
*
* @author Jean-Guillaume Fages
*/
public class PropReachability extends PropArborescence {
//***********************************************************************************
// CONSTRUCTORS
//***********************************************************************************
public PropReachability(DirectedGraphVar graph, int root) {
super(graph, root);
}
public PropReachability(DirectedGraphVar graph, int root, boolean simple) {
super(graph, root, simple);
}
//***********************************************************************************
// METHODS
//***********************************************************************************
protected void remBackArcs() throws ContradictionException {
// reachability allows circuits
// it does not have to remove backward arcs
}
@Override
public ESat isEntailed() {
if (!g.getPotentialNodes().contains(root)) {
return ESat.FALSE;
}
// Test reachability from root to mandatory nodes through potential edges with a DFS
boolean[] visited = new boolean[g.getNbMaxNodes()];
int[] parent = new int[g.getNbMaxNodes()];
visited[root] = true;
parent[root] = root;
int[] stack = new int[g.getNbMaxNodes()];
int last = 0;
stack[last] = root;
while (last >= 0) {
int current = stack[last--];
for (int j : g.getPotentialSuccessorsOf(current)) {
if (!visited[j]) {
visited[j] = true;
parent[j] = current;
stack[++last] = j;
}
}
}
for (int i : g.getMandatoryNodes()) {
if (!visited[i]) {
return ESat.FALSE;
}
}
if (g.isInstantiated()) {
return ESat.TRUE;
}
return ESat.UNDEFINED;
}
}