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

Bidirectional algorithm is not finding valid paths when using non-zero minimum resource values #89

Closed
steveharenberg opened this issue Dec 31, 2021 · 8 comments
Assignees
Labels
BiDirectional bug Something isn't working waiting Waiting for other issues before release
Milestone

Comments

@steveharenberg
Copy link

Describe the bug
Bidirectional is not finding valid paths when using non-zero minimum resource values.

To Reproduce

from networkx import *
from cspy import BiDirectional

max_res = [10, 100]
min_res = [0, 1]
rc = [1,0]

# Example 1
# Source -> 0 -> Sink is valid, but not returned.
H = DiGraph(directed=True, n_res=2)
H.add_nodes_from([0,1,2,3,4,5,6,7])

H.add_edge(0, 3, res_cost=rc, weight=1)
H.add_edge(0, 5, res_cost=rc, weight=1)
H.add_edge(0, 'Sink', res_cost=rc, weight=1)
H.add_edge(1, 3, res_cost=rc, weight=1)
H.add_edge(1, 5, res_cost=rc, weight=1)
H.add_edge(1, 'Sink', res_cost=rc, weight=1)
H.add_edge(2, 1, res_cost=rc, weight=1)
H.add_edge(2, 4, res_cost=rc, weight=1)
H.add_edge(2, 'Sink', res_cost=rc, weight=1)
H.add_edge(3, 1, res_cost=rc, weight=1)
H.add_edge(3, 4, res_cost=rc, weight=1)
H.add_edge(3, 'Sink', res_cost=rc, weight=1)
H.add_edge(4, 0, res_cost=rc, weight=1)
H.add_edge(4, 2, res_cost=rc, weight=1)
H.add_edge(4, 'Sink', res_cost=rc, weight=1)
H.add_edge(5, 0, res_cost=rc, weight=1)
H.add_edge(5, 2, res_cost=rc, weight=1)
H.add_edge(5, 'Sink', res_cost=rc, weight=1)
H.add_edge('Source', 0, res_cost=[1,1], weight=1)
H.add_edge('Source', 1, res_cost=rc, weight=1)
H.add_edge('Source', 2, res_cost=rc, weight=1)
H.add_edge('Source', 3, res_cost=rc, weight=1)
H.add_edge('Source', 4, res_cost=rc, weight=1)
H.add_edge('Source', 5, res_cost=rc, weight=1)

bidirec = BiDirectional(H, max_res, min_res, elementary=True, direction="forward")
bidirec.run()
print(bidirec.path)


# Example 2 (subgraph of example 1)
# Source -> 0 -> Sink is valid, and is correctly returned.
H2 = DiGraph(directed=True, n_res=2)
H2.add_nodes_from([0,1,2,3,4,5,6,7])

H2.add_edge(0, 'Sink', res_cost=rc, weight=1)
H2.add_edge(1, 'Sink', res_cost=rc, weight=1)
H2.add_edge('Source', 0, res_cost=[1,1], weight=1)
H2.add_edge('Source', 1, res_cost=rc, weight=1)

bidirec = BiDirectional(H2, max_res, min_res, elementary=True, direction="forward")
bidirec.run()
print(bidirec.path)

Expected behavior
First example if failing to find Source->0->Sink path, which is valid. Using a subgraph, the second example is able to find this path.

Desktop (please complete the following information):

  • OS: Linux
  • Version 1.0.1

Suggestions
TBD

@torressa
Copy link
Owner

torressa commented Jan 1, 2022

Thanks for the report!
I've pushed a unit test for this on the branch I'm using for development. It seems to work there (see here).
Need to investigate why the previous release doesn't work but haven't managed to replicate it.

@steveharenberg
Copy link
Author

Thanks! That patch seems to have fixed it. At least, this test case is working.

@torressa
Copy link
Owner

torressa commented Jan 9, 2022

The fix discussed in #90 should be generic enough for this too.
Let me know if you have any suggestions.

@steveharenberg
Copy link
Author

The fix discussed in #90 should be generic enough for this too. Let me know if you have any suggestions.

Hey, thanks for looking at this and sorry for the delay in my response. I saw the changes from #90 on the patch90 branch, and I think the min_res changes make sense. I am not sure I fully understand checkFeasibility, but I do think the changes make it better.

I am still learning the algorithm/code, but a couple comments regarding:

cspy/src/cc/labelling.cc

Lines 131 to 137 in 8d3cc36

if (i == c_res || !soft || (soft && min_res[i] <= 0))
if (resource_consumption[i] >= min_res[i]) {
;
} else {
// The label is infeasible because of violating a minimum resource
// bound
return false;

  1. Should c_res be included in that conditional? Suppose min_res[c_res] is greater than 0. Can't this prune labels too early, since resource_consumption[c_res] will be increasing?
  2. More broadly, should this feasibility step only be applied to resources that have monotonic resource consumption? If not, couldn't this prune labels prematurely?

@torressa
Copy link
Owner

No worries at all!

1. Should c_res be included in that conditional? Suppose min_res[c_res] is greater than 0. Can't this prune labels too early, since resource_consumption[c_res] will be increasing?

2. More broadly, should this feasibility step only be applied to resources that have monotonic resource consumption? If not, couldn't this prune labels prematurely?

Yep both of these points are totally correct.
For 2 we can probably have a preprocessing routine that detects which resources are monotonic.
And/or maybe let the user input this information.

@steveharenberg
Copy link
Author

Yeah sounds good. On the cspy side, I guess this belongs in preprocessing. I also think we must let the user specify this (I guess a simple setter method), because we don't know what the REFs are doing and that may change things (or the REFs may do everything and rc values are dummy values).

Of course, if it's not required to be specified, it may not be as clear to the user that it needs to be specified if their REFs cause non-montonicity...

I'd be happy to do a PR adding monotonicity checks, but if you want to handle it that's fine. I also don't know what branch I should be working out of, there seem to be a couple branches that are ahead of master.

@torressa
Copy link
Owner

Yeah sounds good. On the cspy side, I guess this belongs in preprocessing.

Yep.

I also think we must let the user specify this (I guess a simple setter method), because we don't know what the REFs are doing and that may change things (or the REFs may do everything and rc values are dummy values).

Yeh that's probably safest.

I'd be happy to do a PR adding monotonicity checks, but if you want to handle it that's fine.

That'd be grand, really happy for you to do it!

I also don't know what branch I should be working out of, there seem to be a couple branches that are ahead of master.

Yeh, sorry thought I'd cleared things up for the patch90 branch..
Let me clean out the unrelated stuff and set up a new branch for this.
You can just send a PR to the new branch, which can then easily be merged to master for release.

@torressa
Copy link
Owner

torressa commented Jan 13, 2022

New branch monotonic-resource-checks.

Removed the irrelevant bits (the pickup delivery stuff) and fixed some workflows (macos-11 still not building on python but I think it's cause of actions/setup-python#279).
Python tests build and test (not on macos-11 but OK everywhere else), just fail due to the test mentioned at #90 (comment).

torressa added a commit that referenced this issue Jan 19, 2022
…ment version (#95)

* Add pickup delivery for use in label dominance

* FetchContent updates to LEMON and googletest

* Turn tests for LEMON off

* Simplify open requests logic

* Clean up C++ test directory (finish merge of header files)

* Add test for #89, add python3.10 to actions

* Remove LEMON installation steps, add python"3.10"

* Add tests and initial experiments #90

* Add soft feasibility check, refactor python tests

* Fix shared libs logic after fetching LEMON

* Refactor C++ unittests

* Remove pickup-delivery functionality

- Refactor workflows
- Add nuget release action

* Fix Python workflow

* Fix typo

* Add new benchmarks, fix elementary logic

* Fix elementary check for dominance check, add test #94

* Add end of second container for equality check #94

* Forgot one!

* Build docs using github actions

* Debug docs step on ci

* Navigate to cloned repo in doc ci

* Path fix attempt

* Switch to this branch temporarily

* Remove custom domain, add xml files

* Change theme, add index.html to root for gh-pages

* Clean up and update of links in README
@torressa torressa added this to the v1.0.2 milestone Feb 3, 2022
@torressa torressa added waiting Waiting for other issues before release and removed help wanted Extra attention is needed labels Mar 4, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
BiDirectional bug Something isn't working waiting Waiting for other issues before release
Projects
None yet
Development

No branches or pull requests

2 participants