Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: adding edge-finding for disjunctive #141

Draft
wants to merge 9 commits into
base: develop
Choose a base branch
from

Conversation

ImkoMarijnissen
Copy link
Contributor

@ImkoMarijnissen ImkoMarijnissen commented Jan 31, 2025

Currently, we decompose the disjunctive

This PR aims to address this by implementing edge-finding based on this PhD thesis. Any feedback would be appreciated!

TODOS

  • Add documentation

Copy link
Contributor

@maartenflippo maartenflippo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should go through the edge finding algorithm together

@maartenflippo
Copy link
Contributor

Also run a benchmark to see the performance implications compared to decomposition

@ImkoMarijnissen
Copy link
Contributor Author

Also run a benchmark to see the performance implications compared to decomposition

I have ran benchmarks on some MiniZinc challenge/MiniZinc benchmark repository instances with these results:

Result Disjunctive Develop
OPTIMAL 17 15
Average Solution 2351 2418
Average Primal Integral 47952 50587

It is a limited dataset and, of course, on some instances there is a deterioration but these results indicate that it can be beneficial to make use of the disjunctive propagator. It could also indicate that for other instances we need different reasoning (e.g. detectable precedences)

use crate::propagators::disjunctive_task::ArgDisjunctiveTask;

#[test]
fn propagator_propagates_lower_bound() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only lower bounds?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we use a view to update the upper-bounds!

/// # Bibliography
/// \[1\] P. Vilím, ‘Filtering algorithms for the unary resource constraint’, Archives of Control
/// Sciences, vol. 18, no. 2, pp. 159–202, 2008.
pub(crate) struct Disjunctive<Var: IntegerVariable + 'static> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't specify bounds on struct definitions. Or is there a reason why they exist here? DisjunctiveTask also does not enforce a trait bound.

Comment on lines 66 to 67
/// TODO: this explanation could be lifted and should take into account which subset of tasks was
/// responsible for the propagation itself.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clarify why this is not done yet

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have added it now and I am running experiments again to see the impact!

Comment on lines 192 to 200
let reverse_tasks = self
.tasks
.iter()
.map(|task| DisjunctiveTask {
start_variable: task.start_variable.offset(task.processing_time).scaled(-1),
processing_time: task.processing_time,
id: task.id,
})
.collect::<Vec<_>>();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this not be done once, in Disjunctive::new?

/// # Bibliography
/// \[1\] P. Vilím, ‘Filtering algorithms for the unary resource constraint’, Archives of Control
/// Sciences, vol. 18, no. 2, pp. 159–202, 2008.
#[allow(dead_code, reason = "Will be part of the public API")]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which parts are now dead_code? And will this be part of the public API? It seems like an implementation detail of the Disjunctive propagator.

This is enforced by the fact that everything on ThetaTree is pub(super).

Copy link
Contributor Author

@ImkoMarijnissen ImkoMarijnissen Feb 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ThetaTree is currently not constructed since we only create a ThetaLambdaTree.

It depends a bit, currently, it is only used in the Disjunctive but we might consider making a generic ThetaTree which is also applicable for the cumulative

@ImkoMarijnissen ImkoMarijnissen marked this pull request as draft February 28, 2025 09:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants