2017-01-26 2 views
4

人間の目には値xが条件どのように相互排他的な比較を事前に決定するのですか?

x<1 & x>2 

を満たしていないことがわかりますが、どのように私はRがそれを見ることができます。私は渡された比較(文字列など)を取得し、必ずしもデータではない関数でこれを使用したいと思います。のは、私は私は1つが行うことができます意味この

areTherePossibleValues <- function(someString){ 
    someCode 
} 

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

などのように、比較の兆候であり、部分文字列を解釈することによって、比較の組み合わせが今までとにかく満たすことができるかどうかをチェックする機能を書きたいとしましょう、私もっと良い方法があるように感じる。 Rの比較関数( '<'、 '>'、 '='など)自体が実際これに対する答えかもしれません。

+4

これは、式の記号解析を実行し、怠惰な間隔の真理値表を作成するアルゴリズムを作成する必要があり、かなり複雑なトピックです。これには、記号的に区間を符号化し、ブール代数の等価変換を適用する(De Morganの法則を調べる)ことができ、それに続いて還元が可能であることが必要です。現代の最適化コンパイラは、この種の分析を実行しています。 –

+0

@DarshanBaralそれは確率的アプローチです。回答数が多いほど答えが得られる可能性は高くなりますが、回答が常に正しいとは保証できません。 –

+0

@DarshanBaral特に、エラー率を制限する方法はありません。エラー率が非常に悪い場合もあります。明らかに、$ 10

答えて

0

関数は組み合わせまたはそれらの組み合わせ<又は>>=<=、または=(又は==)を含む比較ののリストを処理する関数

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 = "")) 
    } 
} 

USAGE

areTherePossibleValues(">=5 & <50 & >30 & >45") 
#[1] "TRUE for (45.0000000001 < x < 49.9999999999)" 

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

areTherePossibleValues(c("<5",">=2 & =4")) 
#[1] "TRUE for (4 < x < 4)" 
関連する問題