Skip to content

Commit

Permalink
Merge pull request #1251 from SRetip/estimate_function
Browse files Browse the repository at this point in the history
READY : estimate function
  • Loading branch information
Wandalen authored Mar 26, 2024
2 parents 9d027b0 + 46572e1 commit eeaf10e
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 29 deletions.
67 changes: 38 additions & 29 deletions module/move/willbe/src/entity/features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ mod private
{
use crate::*;
use std::collections::{ BTreeSet, HashSet };
use error_tools::err;
// aaa : for Petro : don't use cargo_metadata and Package directly, use facade
// aaa : ✅
use error_tools::for_app::{ bail, Result };
Expand Down Expand Up @@ -67,7 +68,7 @@ mod private
.cloned()
.collect();

if esimate_with( filtered_features.len(), power, with_all_features, with_none_features, enabled_features, package.features().len() ) > variants_cap as usize
if estimate_with( filtered_features.len(), power, with_all_features, with_none_features, enabled_features, package.features().len() ) > variants_cap as usize
{
bail!( "Feature powerset longer then cap." )
}
Expand Down Expand Up @@ -100,46 +101,54 @@ mod private
Ok( features_powerset )
}


fn esimate_with( filtered_length : usize, power : usize, with_all : bool, with_none : bool, enabled : &[ String ], unfiltred_length : usize ) -> usize
/// Calculate estimate for `features_powerset.length`
pub fn estimate_with
(
n : usize,
power : usize,
with_all_features : bool,
with_none_features : bool,
enabled_features : &[ String ],
total_features : usize
)
-> usize
{
let mut e = esimate( filtered_length, power);
if !enabled.is_empty() && with_none
{
e += 1;
}
if with_all && power + enabled.len() >= unfiltred_length
{
e += 1;
}
e
}
let mut estimate = 0;
let mut binom = 1;
let power = power.min( n );

fn esimate( filtered_length : usize, power : usize ) -> usize
{
let mut r = 0;
for p in 1..power
for k in 0..=power
{
r += factorial( filtered_length ) / (factorial(p) * factorial( filtered_length - p ) );
estimate += binom;
binom = binom * ( n - k ) / ( k + 1 );
}
r
}

fn factorial( n : usize ) -> usize
{
return if n == 1
{
1
}
else
if with_all_features { estimate += 1; }
if with_none_features { estimate += 1; }

if !enabled_features.is_empty()
{
n * factorial(n - 1)
let len = enabled_features.len();
let combinations = ( 0..=len.min( total_features ) ).map( | k |
{
let mut binom = 1;
for i in 0..k
{
binom = binom * ( len - i ) / ( i + 1 );
}
binom
}).sum::< usize >();
estimate += combinations;
}

estimate
}

}

crate::mod_interface!
{
/// Features
protected use features_powerset;
protected use estimate_with;
}
11 changes: 11 additions & 0 deletions module/move/willbe/tests/inc/entity/features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use the_module::features::features_powerset;
use std::collections::HashMap;
use serde::Deserialize;
use the_module::workspace::WorkspacePackage;
use willbe::features::estimate_with;

/// Constructs a mock `Package` with specified features for testing.
fn mock_package( features : Vec< ( &str, Vec< &str > ) > ) -> WorkspacePackage
Expand Down Expand Up @@ -254,4 +255,14 @@ fn case_6()
assert!( result.contains( &vec![ "f2".to_string() ].into_iter().collect()) );

assert_eq!( result.len(), 2 );
}

#[ test ]
fn estimate()
{
assert_eq!( estimate_with( 5, 2, false, false, &[], 0 ), 16 );
assert_eq!( estimate_with( 5, 2, true, false, &[], 0 ), 17 );
assert_eq!( estimate_with( 5, 2, false, true, &[], 0 ), 17 );
assert_eq!( estimate_with( 5, 2, false, false, &[ "feature1".to_string(), "feature2".to_string() ], 2 ), 20 );
assert_eq!( estimate_with( 5, 2, true, true, &[ "feature1".to_string(), "feature2".to_string() ], 2 ), 22 );
}

0 comments on commit eeaf10e

Please sign in to comment.