如何预先确定互斥比较?

时间:2017-01-26 09:59:23

标签: r algorithm

人眼可以看到没有值x满足条件

    static void Main(string[] args)
    {
        CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
       "Your storage connection string");

        RsaKey key = new RsaKey("mykey" /* key identifier */);

        // Create the encryption policy to be used for upload and download.
        TableEncryptionPolicy policy = new TableEncryptionPolicy(key, null);

        TableRequestOptions options = new TableRequestOptions
        {
            EncryptionPolicy = policy
        };


        CloudTableClient tableClient = storageAccount.CreateCloudTableClient();

        // Create the CloudTable object that represents the "tomtest" table.
        CloudTable table = tableClient.GetTableReference("tomtest");

        table.CreateIfNotExists();

        var insertList = new List<CloudModelDetail>();

        var cloudModelDetailEntity = new CloudModelDetail { ConsumerId = "0001-"+Guid.NewGuid() };

        table.Execute(TableOperation.Insert(cloudModelDetailEntity), options);

        TableRequestOptions retrieveoptions = new TableRequestOptions
        {
            EncryptionPolicy = policy
        };

        var query =
            new TableQuery<CloudModelDetail>().Where(TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.Equal, cloudModelDetailEntity.RowKey));

       var list = table.ExecuteQuery(query, retrieveoptions);
        foreach (CloudModelDetail entity in list)
        {
            Console.WriteLine($"PartionKey:{entity.PartitionKey},RowKey:{entity.RowKey},ConsumerId: {entity.ConsumerId}");
        }

        Console.ReadKey();
    }



    public class CloudModelDetail : TableEntity
    {
        [EncryptProperty]
        public string ConsumerId { get; set; }
        public CloudModelDetail()
        {
            PartitionKey = "Name";
            RowKey = Guid.NewGuid().ToString();

        }
    }

但是我怎么能让R看到它。我想在一个通过比较(比如字符串)而不一定是数据的函数中使用它。假设我想编写一个函数来检查是否可以完成比较组合,比如这个

x<1 & x>2

我的意思是通过解释作为比较符号的子串等可以做到这一点,但我觉得必须有更好的方法。 R比较函数('&lt;','&gt;','='等)本身实际上可能就是答案,对吗?

5 个答案:

答案 0 :(得分:10)

另一种选择是使用库validatetools(免责声明,我是它的作者)。

library(validatetools)

rules <- validator( r1 = x < 1, r2 = x > 2)
is_infeasible(rules)
# [1] TRUE

make_feasible(rules)
# Dropping rule(s): "r1"
# Object of class 'validator' with 1 elements:
#  r2: x > 2
# Rules are evaluated using locally defined options

# create a set of rules that all must hold:
rules <- validator( x > 1, x < 2, x < 2.5)
is_infeasible(rules)
# [1] FALSE

remove_redundancy(rules)
# Object of class 'validator' with 2 elements:
#  V1: x > 1
#  V2: x < 2

rules <- validator( x >= 1, x < 1)
is_infeasible(rules)
# [1] TRUE

答案 1 :(得分:2)

要在范围之间进行比较,范围max(s)的最小值应始终大于范围min(s)的最大值,如下所示:

library(dplyr)

library(stringr)

areTherePossibleValues <- function(s) {

  str_split(s, pattern = " *& *", simplify = TRUE)[1, ] %>% 

    {lapply(c("max" = "<", "min" = ">"), function(x) str_subset(., pattern = x) %>% str_extract(., pattern = "[0-9]+"))} %>% 

    {as.numeric(min(.$max)) > as.numeric(max(.$min))}

}

更新:添加包含比较

唯一的区别是范围max(s)的最小值可以等于范围min(s)的最大值。

library(dplyr)

library(stringr)

areTherePossibleValues <- function(s) {

  str_split(s, pattern = " *& *", simplify = TRUE)[1, ] %>% 

    {lapply(c("max" = "<", "min" = ">"), function(x) str_subset(., pattern = x) %>% str_remove(., pattern = paste0("^.*", x)))} %>% 

    {ifelse(sum(grepl(pattern = "=", unlist(.))), 

            as.numeric(min(str_remove(.$max, "="))) >= as.numeric(max(str_remove(.$min, "="))), 

            as.numeric(min(.$max)) > as.numeric(max(.$min)))}

}

areTherePossibleValues("x<1 & x>2")

areTherePossibleValues("x>1 & x<2")

areTherePossibleValues("x>=1 & x<1")

答案 2 :(得分:1)

这是我解决问题的方法,它可能不是最好的方法,但是即使您有很多比较,它也应该可以工作。

让我们将比较中出现的数字称为“临界值”,然后我们要做的就是测试每对临界值之间的1个数字,大于最大临界值的1个数字和小于最大临界值的1个数字。最低截止时间。

直觉用图解说明:

enter image description here

代码如下:

areTherePossibleValues <- function(s){

  # first get the numbers that appeared in your string, sort them, and call them the cutoffs
  cutoffs = sort(as.numeric(gsub("\\D", "", strsplit(s,  "&")[[1]])))

  # get the numbers that in between each cutoffs, and a bit larger/smaller than the max/min in the cutoffs
  testers = (c(min(cutoffs)-1, cutoffs) + c( cutoffs ,max(cutoffs) + 1))/2

  # take out each comparisons
  comparisons = strsplit(s,  "&")[[1]]

  # check if ANY testers statisfy all comparisons
  any(sapply(testers, function(te){

    # check if a test statisfy ALL comparisons
    all(sapply(comparisons, function(co){eval(parse(text =gsub(pattern = 'x',replacement =te, co)))}))
  }))
}

areTherePossibleValues("x<1 & x>2")
#[1] FALSE

areTherePossibleValues("x>1 & x<2 & x < 2.5")
#[1] TRUE

areTherePossibleValues("x=> 1 & x < 1")
#[1] FALSE

答案 3 :(得分:0)

<强>功能

该函数将处理包含<>>=,{{的比较的组合组合列表1}},或<=(或=)。

==

<强> USAGE

areTherePossibleValues = function(condition = "x<1 & x>2", tolerance = 1e-10){

    #Attach all comparison into one
    condition = paste(condition, collapse = "&")

    #PARSE
    condition = tolower(condition) #make everything lowercase just in case    
    condition = gsub("[ ,x]","",condition) #Remove whitespace and 'x'    
    condition = gsub(">=","g",condition) # >= to g(reater than or equal to)
    condition = gsub("<=","s",condition) # <= to s(maller than or equal to) 
    condition = gsub("[==,=]","e",condition) # == or = to e(qual)

    #Separate conditions into a list
    condition = unlist(strsplit(condition,"&"))

    #Initiate vector of upper and lower bounds with NA
    Upper = rep(x = NA, times = length(condition))
    Lower = rep(x = NA, times = length(condition))

    #Fill the vector of upper and lower bounds based on comparators and numbers
    for (i in 1:length(condition)){
        number = as.numeric(gsub(pattern = "[<,>,e,g,s]", replacement = "", condition[i]))    
        comparator = substr(condition[i], start = 1, stop = 1)
        if (comparator == ">"){
            Lower[i] = number + tolerance   #just to the right of the number so as to exclude it
        } else if (comparator == "<"){
            Upper[i] = number - tolerance   #just to the left of the number so as to exclude it
        } else if (comparator == "g"){
            Lower[i] = number           #Include the number
        } else if (comparator == "s"){
            Upper[i] = number           #Include the number
        } else if (comparator == "e"){
            Upper[i] = number           #For =, make upper and lower bounds same
            Lower[i] = number
        }
    }

    Upper = as.numeric(Upper[which(is.na(Upper) == FALSE)]) #Remove NAs
    Lower = as.numeric(Lower[which(is.na(Lower) == FALSE)]) #Remove NAs

    if (length(Upper) == 0 & length(Lower) > 0){
        #1. If Upper has 0 length and Lower has more than 0, it means
        # x is constrained only by lower bounds. x will always be fulfilled
        ans = TRUE
    } else if (length(Lower) == 0 & length(Upper) > 0){
        #2. If Lower has 0 length and Upper has more than 0, it means
        # x is constrained only by upper bounds. x will always be fulfilled
        ans = TRUE
    } else {
        # If the smallest upper bound is bigger than the largest lower bound,
        #x will be fulfilled.
        ans = (min(Upper) - max(Lower)) >= 0
    }

    if (ans == FALSE){
    return(ans)
    } else {
    return(paste(ans," for (",max(Lower)," < x < ",min(Upper),")",sep = ""))
    }
}

答案 4 :(得分:0)

我们看到x <1&x> 2是不可能的,因为我们得到了一个简单的规则:如果一个数字 x 小于另一个数字 a ,那么它就不可能大于另一个大于 a 的数字,或更根本地讲,我们使用的是部分有序集的传递性属性。我们没有理由不能教计算机(或R)看到这一点。如果问题中的逻辑字符串仅包含形式为x#a的语句,其中#可以是<,>,<=和> =,并且运算符始终为&,则上面的岳Y解决方案将完美地回答您的问题。它甚至可以概括为包括|。操作员。除此之外,您还必须更具体地说明逻辑表达式可以是什么。