2017-01-26 4 views
4

Das kann menschliches Auge sehen, dass kein Wert x die Bedingung, dassWie kann ich sich gegenseitig ausschließende Vergleiche vorbestimmen?

x<1 & x>2 

aber wie kann ich machen R siehe erfüllt. Ich möchte dies in einer Funktion verwenden, die Vergleiche (etwa als Strings) und nicht unbedingt Daten erhält. Lassen Sie sich sagen, dass ich eine Funktion schreiben will, das eine Kombination von Vergleich überprüft, ob jemals ohnehin erfüllt werden kann, wie diese

areTherePossibleValues <- function(someString){ 
    someCode 
} 

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

ich eine bedeuten tun könnte, dass durch den Teil Interpretation, die einen Vergleich Zeichen ist und so weiter, aber ich Fühlen Sie sich, als müsste es einen besseren Weg geben. Die R-Vergleichsfunktionen ('<', '>', '=' und so weiter) selbst könnten tatsächlich die Antwort darauf sein, oder?

+4

Dies ist ein ziemlich komplexes Thema, das Sie einen Algorithmus erstellen erfordert, die symbolische Analyse der Expression führt und schafft für faule Intervalle eine Wahrheitstabelle. Dies erfordert die Fähigkeit, Intervalle symbolisch zu codieren und äquivalente Transformationen von booleschen Termen anzuwenden (siehe De Morgans Gesetze), gefolgt von einer Reduktion. Moderne optimierende Compiler führen diese Art von Analyse durch. –

+0

@DarshanBaral Das ist ein probabilistischer Ansatz. Je mehr Zahlen Sie abtasten, desto wahrscheinlicher ist es, die richtige Antwort zu erhalten, aber Sie können nicht garantieren, dass die Antwort immer richtig ist. –

+0

@DarshanBaral Insbesondere gibt es keine Möglichkeit, die Fehlerrate zu begrenzen. In einigen Fällen wird die Fehlerrate sehr schlecht sein. Natürlich gibt es Zahlen, die $ 10

Antwort

0

FUNCTION

Die Funktion Kombinationen oder Liste von Kombinationen von Vergleiche, die < oder >, >=, <= oder = (oder ==) enthalten, verarbeitet.

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)" 
Verwandte Themen