From 7afbdbdf530d66866a59a47a5b47461a92b0fab4 Mon Sep 17 00:00:00 2001 From: Tijl Leenders Date: Sun, 24 Mar 2024 15:30:14 +0100 Subject: [PATCH 1/7] add failing test --- .../conflict-without-deadline/expected.json | 58 +++++++++++++++++++ .../conflict-without-deadline/input.json | 32 ++++++++++ .../conflict-without-deadline/observed.json | 58 +++++++++++++++++++ 3 files changed, 148 insertions(+) create mode 100644 tests/jsons/stable/conflict-without-deadline/expected.json create mode 100644 tests/jsons/stable/conflict-without-deadline/input.json create mode 100644 tests/jsons/stable/conflict-without-deadline/observed.json diff --git a/tests/jsons/stable/conflict-without-deadline/expected.json b/tests/jsons/stable/conflict-without-deadline/expected.json new file mode 100644 index 00000000..557c3011 --- /dev/null +++ b/tests/jsons/stable/conflict-without-deadline/expected.json @@ -0,0 +1,58 @@ +{ + "scheduled": [ + { + "day": "2022-01-01", + "tasks": [ + { + "taskid": 1, + "goalid": "4", + "title": "not-anytime", + "duration": 1, + "start": "2022-01-01T00:00:00", + "deadline": "2022-01-01T01:00:00" + }, + { + "taskid": 2, + "goalid": "3", + "title": "anytime-without-deadline", + "duration": 1, + "start": "2022-01-01T01:00:00", + "deadline": "2022-01-01T02:00:00" + }, + { + "taskid": 3, + "goalid": "free", + "title": "free", + "duration": 11, + "start": "2022-01-01T01:00:00", + "deadline": "2022-01-01T12:00:00" + }, + { + "taskid": 4, + "goalid": "1", + "title": "anytime-with-deadline", + "duration": 1, + "start": "2022-01-01T12:00:00", + "deadline": "2022-01-01T13:00:00" + }, + { + "taskid": 5, + "goalid": "2", + "title": "anytime-without-deadline", + "duration": 1, + "start": "2022-01-01T13:00:00", + "deadline": "2022-01-01T14:00:00" + }, + { + "taskid": 6, + "goalid": "free", + "title": "free", + "duration": 10, + "start": "2022-01-01T14:00:00", + "deadline": "2022-01-02T00:00:00" + } + ] + } + ], + "impossible": [] +} \ No newline at end of file diff --git a/tests/jsons/stable/conflict-without-deadline/input.json b/tests/jsons/stable/conflict-without-deadline/input.json new file mode 100644 index 00000000..3b42bc50 --- /dev/null +++ b/tests/jsons/stable/conflict-without-deadline/input.json @@ -0,0 +1,32 @@ + { + "startDate": "2022-01-01T00:00:00", + "endDate": "2022-01-02T00:00:00", + "goals": [ + { + "id": "1", + "title": "anytime-with-deadline", + "minDuration": 1, + "start": "2022-01-01T00:00:00", + "deadline": "2022-01-02T00:00:00" + }, + { + "id": "2", + "title": "anytime-without-deadline", + "minDuration": 1, + "start": "2022-01-01T00:00:00" + }, + { + "id": "3", + "title": "anytime-without-deadline-2", + "minDuration": 1, + "start": "2022-01-01T00:00:00" + }, + { + "id": "4", + "title": "not-anytime", + "minDuration": 1, + "start": "2022-01-01T00:00:00", + "deadline": "2022-01-01T12:00:00" + } + ] + } \ No newline at end of file diff --git a/tests/jsons/stable/conflict-without-deadline/observed.json b/tests/jsons/stable/conflict-without-deadline/observed.json new file mode 100644 index 00000000..c08aaf48 --- /dev/null +++ b/tests/jsons/stable/conflict-without-deadline/observed.json @@ -0,0 +1,58 @@ +{ + "scheduled": [ + { + "day": "2022-01-01", + "tasks": [ + { + "taskid": 0, + "goalid": "4", + "title": "not-anytime", + "duration": 1, + "start": "2022-01-01T00:00:00", + "deadline": "2022-01-01T01:00:00" + }, + { + "taskid": 1, + "goalid": "free", + "title": "free", + "duration": 11, + "start": "2022-01-01T01:00:00", + "deadline": "2022-01-01T12:00:00" + }, + { + "taskid": 2, + "goalid": "1", + "title": "anytime-with-deadline", + "duration": 1, + "start": "2022-01-01T12:00:00", + "deadline": "2022-01-01T13:00:00" + }, + { + "taskid": 3, + "goalid": "2", + "title": "anytime-without-deadline", + "duration": 1, + "start": "2022-01-01T13:00:00", + "deadline": "2022-01-01T14:00:00" + }, + { + "taskid": 4, + "goalid": "3", + "title": "anytime-without-deadline-2", + "duration": 1, + "start": "2022-01-01T14:00:00", + "deadline": "2022-01-01T15:00:00" + }, + { + "taskid": 5, + "goalid": "free", + "title": "free", + "duration": 9, + "start": "2022-01-01T15:00:00", + "deadline": "2022-01-02T00:00:00" + } + ] + } + ], + "impossible": [] +} \ No newline at end of file From d24f486d4752ea8d6d6c971566d188870daafa65 Mon Sep 17 00:00:00 2001 From: Tijl Leenders Date: Sun, 24 Mar 2024 19:32:03 +0100 Subject: [PATCH 2/7] improve debug prints --- src/models/activity.rs | 16 ++++++++-------- src/services/activity_placer.rs | 19 ++++++++++++------- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/src/models/activity.rs b/src/models/activity.rs index 2dcc7888..390aa8ab 100644 --- a/src/models/activity.rs +++ b/src/models/activity.rs @@ -131,8 +131,8 @@ impl Activity { flex } - pub fn get_best_scheduling_index_and_length(&self) -> Option<(usize, usize)> { - let mut best_scheduling_index_and_conflicts: Option<(usize, usize, usize)> = None; + pub fn get_best_scheduling_index_length_conflicts(&self) -> Option<(usize, usize, usize)> { + let mut best_scheduling_index_length_conflicts: Option<(usize, usize, usize)> = None; for hour_index in 0..self.calendar_overlay.len() { let mut conflicts = 0; if self.calendar_overlay[hour_index].is_some() { @@ -159,15 +159,15 @@ impl Activity { conflicts += weak.weak_count(); //if last position check if best so far - or so little we can break if offset == offset_size - 1 { - match best_scheduling_index_and_conflicts { + match best_scheduling_index_length_conflicts { None => { - best_scheduling_index_and_conflicts = - Some((hour_index, conflicts, offset_size)); + best_scheduling_index_length_conflicts = + Some((hour_index, offset_size, conflicts)); } Some((_, best_conflicts, _)) => { if conflicts < best_conflicts || conflicts == 0 { - best_scheduling_index_and_conflicts = - Some((hour_index, conflicts, offset_size)); + best_scheduling_index_length_conflicts = + Some((hour_index, offset_size, conflicts)); } } } @@ -177,7 +177,7 @@ impl Activity { } } } - best_scheduling_index_and_conflicts.map(|(best_index, _, size)| (best_index, size)) + best_scheduling_index_length_conflicts } pub(crate) fn get_simple_activities(goal: &Goal, calendar: &Calendar) -> Vec { diff --git a/src/services/activity_placer.rs b/src/services/activity_placer.rs index c9c9cfdc..fcbbe553 100644 --- a/src/services/activity_placer.rs +++ b/src/services/activity_placer.rs @@ -11,17 +11,17 @@ pub fn place(calendar: &mut Calendar, mut activities: Vec) -> Vec Option { { continue; } + let current_act_flex = activities[index].flex(); + println!( + "Flex {:?} for {:?}", + current_act_flex, activities[index].title + ); match act_index_to_schedule { None => act_index_to_schedule = Some(index), - Some(_) => match activities[index].flex() { + Some(_) => match current_act_flex { 0 => { println!("Found activity index {:?} with flex 0...", &index); continue; @@ -94,7 +99,7 @@ fn find_act_index_to_schedule(activities: &[Activity]) -> Option { } } _ => { - if activities[act_index_to_schedule?].flex() < activities[index].flex() { + if activities[act_index_to_schedule?].flex() < current_act_flex { act_index_to_schedule = Some(index); } } From 2b465986080276fcc26abf91bd1309e8dc55b8c2 Mon Sep 17 00:00:00 2001 From: Tijl Leenders Date: Sun, 24 Mar 2024 20:38:20 +0100 Subject: [PATCH 3/7] correct expectation --- .../conflict-without-deadline/expected.json | 46 ++++++++----------- 1 file changed, 19 insertions(+), 27 deletions(-) diff --git a/tests/jsons/stable/conflict-without-deadline/expected.json b/tests/jsons/stable/conflict-without-deadline/expected.json index 557c3011..dc6f66a3 100644 --- a/tests/jsons/stable/conflict-without-deadline/expected.json +++ b/tests/jsons/stable/conflict-without-deadline/expected.json @@ -4,51 +4,43 @@ "day": "2022-01-01", "tasks": [ { - "taskid": 1, - "goalid": "4", - "title": "not-anytime", + "taskid": 0, + "goalid": "1", + "title": "anytime-with-deadline", "duration": 1, "start": "2022-01-01T00:00:00", "deadline": "2022-01-01T01:00:00" }, { - "taskid": 2, - "goalid": "3", - "title": "anytime-without-deadline", + "taskid": 1, + "goalid": "4", + "title": "not-anytime", "duration": 1, "start": "2022-01-01T01:00:00", "deadline": "2022-01-01T02:00:00" }, { - "taskid": 3, - "goalid": "free", - "title": "free", - "duration": 11, - "start": "2022-01-01T01:00:00", - "deadline": "2022-01-01T12:00:00" - }, - { - "taskid": 4, - "goalid": "1", - "title": "anytime-with-deadline", + "taskid": 2, + "goalid": "2", + "title": "anytime-without-deadline", "duration": 1, - "start": "2022-01-01T12:00:00", - "deadline": "2022-01-01T13:00:00" + "start": "2022-01-01T02:00:00", + "deadline": "2022-01-01T03:00:00" }, { - "taskid": 5, - "goalid": "2", - "title": "anytime-without-deadline", + "taskid": 3, + "goalid": "3", + "title": "anytime-without-deadline-2", "duration": 1, - "start": "2022-01-01T13:00:00", - "deadline": "2022-01-01T14:00:00" + "start": "2022-01-01T03:00:00", + "deadline": "2022-01-01T04:00:00" }, { - "taskid": 6, + "taskid": 4, "goalid": "free", "title": "free", - "duration": 10, - "start": "2022-01-01T14:00:00", + "duration": 20, + "start": "2022-01-01T04:00:00", "deadline": "2022-01-02T00:00:00" } ] From db9739c8b327811ebfa8b91688605b5613f5aa1c Mon Sep 17 00:00:00 2001 From: Tijl Leenders Date: Sun, 24 Mar 2024 20:39:49 +0100 Subject: [PATCH 4/7] fix conflict-without-deadline --- src/lib.rs | 3 +++ src/models/activity.rs | 2 ++ src/services/activity_placer.rs | 21 +++++++++++++++++++++ 3 files changed, 26 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index a6f71dc7..1fe8cd74 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -118,6 +118,9 @@ pub fn run_scheduler( // So MinDayBudget will get chosen last unless flex is equal and order happens to favor MinDayBudget // => TODO: order activities before placing? + base_activities = activity_placer::reset_postponed(base_activities); + base_activities = activity_placer::place(&mut calendar, base_activities); + calendar.log_impossible_base_activities(base_activities); calendar.print() diff --git a/src/models/activity.rs b/src/models/activity.rs index 390aa8ab..2a1bd3f5 100644 --- a/src/models/activity.rs +++ b/src/models/activity.rs @@ -533,6 +533,8 @@ pub enum Status { Processed, Scheduled, Impossible, + Postponed, + BestEffort, } #[derive(Clone, Debug, PartialEq)] diff --git a/src/services/activity_placer.rs b/src/services/activity_placer.rs index fcbbe553..8e05ff02 100644 --- a/src/services/activity_placer.rs +++ b/src/services/activity_placer.rs @@ -23,6 +23,17 @@ pub fn place(calendar: &mut Calendar, mut activities: Vec) -> Vec 0 + && activities[act_index_to_schedule].deadline.is_none() + && activities[act_index_to_schedule].status != Status::BestEffort + { + println!( + "Postponing placement of {:?} - since no deadline and conflicts > 0...\n", + activities[act_index_to_schedule].title + ); + activities[act_index_to_schedule].status = Status::Postponed; + continue; + } println!("reserving {:?} hours...", best_size); for duration_offset in 0..best_size { Rc::make_mut(&mut calendar.hours[best_hour_index + duration_offset]); @@ -75,6 +86,7 @@ fn find_act_index_to_schedule(activities: &[Activity]) -> Option { if activities[index].status == Status::Scheduled || activities[index].status == Status::Impossible || activities[index].status == Status::Processed + || activities[index].status == Status::Postponed { continue; } @@ -108,3 +120,12 @@ fn find_act_index_to_schedule(activities: &[Activity]) -> Option { } act_index_to_schedule } + +pub(crate) fn reset_postponed(mut base_activities: Vec) -> Vec { + for activity in base_activities.iter_mut() { + if activity.status == Status::Postponed { + activity.status = Status::BestEffort; + } + } + base_activities +} From d2f85ec5a7133e477356c88e2cf1ceb15b1c26c8 Mon Sep 17 00:00:00 2001 From: Tijl Leenders Date: Sun, 24 Mar 2024 21:09:35 +0100 Subject: [PATCH 5/7] fix bug wrong variable --- src/models/activity.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/models/activity.rs b/src/models/activity.rs index 2a1bd3f5..3c634795 100644 --- a/src/models/activity.rs +++ b/src/models/activity.rs @@ -164,7 +164,7 @@ impl Activity { best_scheduling_index_length_conflicts = Some((hour_index, offset_size, conflicts)); } - Some((_, best_conflicts, _)) => { + Some((_, _, best_conflicts)) => { if conflicts < best_conflicts || conflicts == 0 { best_scheduling_index_length_conflicts = Some((hour_index, offset_size, conflicts)); From 6431e3723fd58da2e5cf878194fb281a40484017 Mon Sep 17 00:00:00 2001 From: Tijl Leenders Date: Sun, 24 Mar 2024 21:14:21 +0100 Subject: [PATCH 6/7] update expected --- .../conflict-without-deadline/expected.json | 32 ++++++++++++------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/tests/jsons/stable/conflict-without-deadline/expected.json b/tests/jsons/stable/conflict-without-deadline/expected.json index dc6f66a3..c9bb47f8 100644 --- a/tests/jsons/stable/conflict-without-deadline/expected.json +++ b/tests/jsons/stable/conflict-without-deadline/expected.json @@ -5,42 +5,50 @@ "tasks": [ { "taskid": 0, - "goalid": "1", - "title": "anytime-with-deadline", + "goalid": "4", + "title": "not-anytime", "duration": 1, "start": "2022-01-01T00:00:00", "deadline": "2022-01-01T01:00:00" }, { "taskid": 1, - "goalid": "4", - "title": "not-anytime", + "goalid": "2", + "title": "anytime-without-deadline", "duration": 1, "start": "2022-01-01T01:00:00", "deadline": "2022-01-01T02:00:00" }, { "taskid": 2, - "goalid": "2", - "title": "anytime-without-deadline", + "goalid": "3", + "title": "anytime-without-deadline-2", "duration": 1, "start": "2022-01-01T02:00:00", "deadline": "2022-01-01T03:00:00" }, { "taskid": 3, - "goalid": "3", - "title": "anytime-without-deadline-2", - "duration": 1, + "goalid": "free", + "title": "free", + "duration": 9, "start": "2022-01-01T03:00:00", - "deadline": "2022-01-01T04:00:00" + "deadline": "2022-01-01T12:00:00" }, { "taskid": 4, + "goalid": "1", + "title": "anytime-with-deadline", + "duration": 1, + "start": "2022-01-01T12:00:00", + "deadline": "2022-01-01T13:00:00" + }, + { + "taskid": 5, "goalid": "free", "title": "free", - "duration": 20, - "start": "2022-01-01T04:00:00", + "duration": 11, + "start": "2022-01-01T13:00:00", "deadline": "2022-01-02T00:00:00" } ] From 1ade3ea2073eda6cd6a68b6cfe588c8e4a830c83 Mon Sep 17 00:00:00 2001 From: Tijl Leenders Date: Sun, 24 Mar 2024 21:14:49 +0100 Subject: [PATCH 7/7] fix conflict-without deadline --- src/services/activity_placer.rs | 1 + .../conflict-without-deadline/observed.json | 38 +++++++++---------- 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/src/services/activity_placer.rs b/src/services/activity_placer.rs index 8e05ff02..d77777fd 100644 --- a/src/services/activity_placer.rs +++ b/src/services/activity_placer.rs @@ -25,6 +25,7 @@ pub fn place(calendar: &mut Calendar, mut activities: Vec) -> Vec 0 && activities[act_index_to_schedule].deadline.is_none() + && !calendar.is_budget(activities[act_index_to_schedule].goal_id.clone()) && activities[act_index_to_schedule].status != Status::BestEffort { println!( diff --git a/tests/jsons/stable/conflict-without-deadline/observed.json b/tests/jsons/stable/conflict-without-deadline/observed.json index c08aaf48..c9bb47f8 100644 --- a/tests/jsons/stable/conflict-without-deadline/observed.json +++ b/tests/jsons/stable/conflict-without-deadline/observed.json @@ -13,42 +13,42 @@ }, { "taskid": 1, - "goalid": "free", - "title": "free", - "duration": 11, + "goalid": "2", + "title": "anytime-without-deadline", + "duration": 1, "start": "2022-01-01T01:00:00", - "deadline": "2022-01-01T12:00:00" + "deadline": "2022-01-01T02:00:00" }, { "taskid": 2, - "goalid": "1", - "title": "anytime-with-deadline", + "goalid": "3", + "title": "anytime-without-deadline-2", "duration": 1, - "start": "2022-01-01T12:00:00", - "deadline": "2022-01-01T13:00:00" + "start": "2022-01-01T02:00:00", + "deadline": "2022-01-01T03:00:00" }, { "taskid": 3, - "goalid": "2", - "title": "anytime-without-deadline", - "duration": 1, - "start": "2022-01-01T13:00:00", - "deadline": "2022-01-01T14:00:00" + "goalid": "free", + "title": "free", + "duration": 9, + "start": "2022-01-01T03:00:00", + "deadline": "2022-01-01T12:00:00" }, { "taskid": 4, - "goalid": "3", - "title": "anytime-without-deadline-2", + "goalid": "1", + "title": "anytime-with-deadline", "duration": 1, - "start": "2022-01-01T14:00:00", - "deadline": "2022-01-01T15:00:00" + "start": "2022-01-01T12:00:00", + "deadline": "2022-01-01T13:00:00" }, { "taskid": 5, "goalid": "free", "title": "free", - "duration": 9, - "start": "2022-01-01T15:00:00", + "duration": 11, + "start": "2022-01-01T13:00:00", "deadline": "2022-01-02T00:00:00" } ]