Mikroökonomie
Vorlesung 2

Prof. Frank Pisch PhD

Einführung

Motivation: Nvidia

Die Nvidia Corporation ist einer der größten Entwickler von Grafikprozessoren und Chipsätzen für Personalcomputer, Server und Spielkonsolen

  • 1993 gegründet, heute vor allem durch seine GPUs bekannt, die für KI Anwendungen notwendig sind

Nvidia

Motivation: Herstellung von Halbleitern

Die Herstellung und der Vertrieb von GPUs und Chipsätzen benötigt

  • Silizium, Seltene Erden, sowie andere Chemikalien
  • “Fabs” (Taiwan, China, USA) und hochmoderne Maschinen (von ASML)
  • Forschung und Design, also Wissenschaftler und andere “high-skill” Mitarbeiter:innen + gut ausgebildete Mitarbeiter:innen im Dienstleistungsbereich (Administration, Marketing, Logistik, Catering etc.)

Aus diesem komplexen Gebilde ergeben sich wichtige Fragen

  • Wie sollen diese Inputs kombiniert werden, um möglichst gute Chips zu niedrigen Preisen zu produzieren?

  • Welche Mengen werden zu welchen Preisen angeboten, um maximale Gewinne zu erzielen?

  • Über Nvidia hinaus: wie sieht das Marktangebot für GPUs dementsprechend aus? Welche Wohlfahrtsimplikationen für Unternehmen ergeben sich aus Schocks?

Überblick und Resourcen

Ziele

  • Modellierung des individuellen Angebots einzelner Unternehmen durch Kostenminimierung und Gewinnmaximierung

  • Herleitung des Branchenangebots und der Produzentenrente als Wohlfahrtskonzept

Ressourcen

Kapitel im Varian: 19, 21 - 24

Produktion und Technologie

Technologie

Ein Unternehmen benutzt Produktionsfaktoren (Inputs) um Outputs zu erzeugen

  • z.B. Arbeit, Kapital, Rohstoffe, Wissen, Vor- und Zwischenprodukte werden zu Output verarbeitet

Image

Nvidia

Eine Technologie beschreibt, welche Kombinationen von Faktoren zu welchen Outputs führen können, also welche Produktionspläne durchführbar sind

Die Produktionsfunktion

Die Produktionsfunktion beschreibt die maximal mögliche Outputmenge bei verschiedenen Inputbündeln \[ y = f(x_1,...,x_n)=f(\boldsymbol{x}) \] Die Funktionen selbst ähneln unseren Nutzenfunktionen, da ähnliche Eigenschaften wichtig sind (Cobb-Douglas, perfekte Substitute, perfekte Komplemente etc.)

Zumeist sind Produktionsfunktionen monoton

  • Mehr von einem Input generiert mehr Output

  • Das Grenzprodukt (Marginal Product) eines Faktors ist also positiv: \(MP_i\equiv \partial y(\boldsymbol{x})/\partial x_i \geq 0\)

Meist sind sie auch konvex: “die Mischung macht’s”, denn Grenzprodukte fallen im Faktoreinsatz

\[ \partial MP_i/\partial x_i \leq 0 \]

Illustration: Grenzprodukte

Nach Varian, Abbildung 19.5

Isoquanten

Eine Isoquante ist die Menge aller möglichen Kombinationen von Faktoren, die genau ausreicht, um eine vorgegebene Menge des Outputs zu erzeugen

  • Jede Isoquante repräsentiert ein spezifisches Output-Niveau

Die Technische Rate der Substitution ist negativ und nimmt zu

\[ TRS_{i,j} \equiv -\frac{MP_i}{MP_j}, \ \ \ \ \ \ \frac{\partial \ TRS_{i,j}}{\partial x_i}>0 \]

Grafik: Produktion in Zweifaktorenfall

#| standalone: true
#| viewerHeight: 600

library(ggplot2)
library(shiny)
library(dplyr)
library(purrr)
library(bslib)
library(bs4Dash)



ui <- fluidPage(
  
  sidebarLayout(
    sidebarPanel(
      tabsetPanel(
        tabPanel("Funktion",
                 br(),
                 selectInput("type",
                             h4("Technologie"),
                             choices = c("Cobb-Douglas" = "cd", "Perfekte Substitute" = "ps", "Perfekte Komplemente" = "kp"),
                             selected = "cd"),
                 
                 sliderInput("alpha",
                             h5("Wahl von α:",
                                br(),
                                ""),
                             min = 0,
                             max = 1,
                             value = 0.5,
                             step = 0.1),
                 
                 uiOutput('formel'),
                  br(),
                 
                 checkboxInput("showIsoLine",
                                              h5("Isoquanten anzeigen"),
                                              value = FALSE
                                ),
                 checkboxInput("showIsoCost",
                               h5("Isokostenkurve anzeigen"),
                               value = FALSE
                 ),
                               
                 # 
                 # 
                 # checkboxInput("disp_opt",
                 #               h5("Optima Anzeigen"),
                 #               value = FALSE
                 # ),
                 br(),
                 uiOutput('optimum'),
                 br(),
                 actionButton("reset", "Reset"),
                 
                 
                 
                 
                 
                 
        ),
        
        tabPanel("Einstellungen",
                 br(),
                 
                 numericInput("P_1",
                              h5("Faktorentlohnung w\u2081"),
                              min = 1,
                              max = 200,
                              value = 1,
                              step = 1),
                 
                 numericInput("P_2",
                              h5("Faktorentlohnung w\u2082"),
                              min = 1,
                              max = 200,
                              value = 1,
                              step = 1),
                 numericInput("y",
                              h5("Output y"),
                              min = 1,
                              max = 200,
                              value = 20,
                              step = 1)
                 
        )
      )
    ),  
    
    mainPanel(
      align = "center",
      plotOutput(outputId = "techPlot", height = "500px", width = "600px"),
    )
    
  )
)


server <- function(input, output, session) {
  
  technologie <- function(x_1, x_2, alpha, type) {
    if (type == "cd") return(x_1 ^ alpha * x_2 ^ (1-alpha))
 #   if (type == "ps") return(alpha * x_1 + (1-alpha) * x_2)
    if (type == "ps") return((alpha * x_1) + x_2)
    if (type == "kp") return(pmin(alpha*x_1, (1-alpha) * x_2))
      
      }
  
  minKost <- function(y, alpha, P_1, P_2, type) {
    
    if (type == "cd") {
      x_2_id <- y*((P_1/P_2)^alpha)*(((1-alpha)/alpha)^alpha)
      x_1_id <- x_2_id^((alpha-1)/alpha)*(y^(1/alpha))
      kosten_min <- x_1_id*P_1 + x_2_id*P_2
      return(list(kosten_min = kosten_min, x_1_id = x_1_id, x_2_id = x_2_id))
      
    } else if (type == "ps") {
      
      if (P_1 - P_2 * alpha < 0) {
        x_1_id <- y/alpha
        x_2_id <- 0
        kosten_min <- x_1_id*P_1
        return(list(kosten_min = kosten_min, x_1_id = x_1_id, x_2_id = x_2_id))
        
        
      } else if (P_1-P_2*alpha > 0) {
        x_2_id <- y
        x_1_id <- 0
        kosten_min <- x_2_id*P_2
        return(list(kosten_min = kosten_min, x_1_id = x_1_id, x_2_id = x_2_id))
        
      } else if (P_1-P_2*alpha == 0) {
        x_2_id <- y
        x_1_id <- 0
        kosten_min <- x_2_id*P_2
        return(list(kosten_min = kosten_min, x_1_id = x_1_id, x_2_id = x_2_id))
        
        
      }
      
    } else if (type == "kp") {
      x_1_id <- y/alpha
      x_2_id <- y/(1-alpha)
      kosten_min <- x_1_id*P_1 + x_2_id*P_2
      return(list(kosten_min = kosten_min, x_1_id = x_1_id, x_2_id = x_2_id))
    }
    else {
      x_1_id <- 1
      x_2_id <- 1
      kosten_min <- 1
      return(list(kosten_min = kosten_min, x_1_id = x_1_id, x_2_id = x_2_id))
    }
  }
  
  observeEvent(input$reset, {
    updateSliderInput(inputId = "alpha", value = 0.5)
    updateSelectInput(inputId = "type", selected = "cd")
    updateCheckboxInput(inputId = "showIsoCost", value = FALSE)
    updateCheckboxInput(inputId = "showIsoLine", value = FALSE)
    updateNumericInput(inputId = "P_1", value = 1)
    updateNumericInput(inputId = "P_2", value = 1)
    updateNumericInput(inputId = "y", value = 20)
  })
  
  output$techPlot <- renderPlot({
    
    alpha <- input$alpha
    
    P_1 <- input$P_1
    P_2 <- input$P_2
    
    y <- input$y
    
    type <- input$type
    
    disp <- input$disp_opt
    
    
    Ergebnisse <- minKost(y, alpha, P_1, P_2, type)
    x_1_id <- Ergebnisse$x_1_id
    x_2_id <- Ergebnisse$x_2_id
    min_Kos <- Ergebnisse$kosten_min
    output <- Ergebnisse$kosten_min
    showIsoLine <- input$showIsoLine
    showIsoCost <- input$showIsoCost
    
    
    ikk <- function(P_1, P_2, x_1_id, x_2_id, type) {
      if (type == "ps") {
        intercept <- x_2_id + (x_1_id*(P_1/P_2))
        slope <- -P_1 / P_2
        abline <- list(
          geom_abline(intercept = intercept, slope = slope, color = "red", linetype = "solid"),
          geom_abline(intercept = 0.8 * intercept, slope = slope, color = "red", linetype = "dashed"),
          geom_abline(intercept = 1.2 * intercept, slope = slope, color = "red", linetype = "dashed"))
        return(abline)
      } else {
        slope <- -P_1 / P_2
        intercept <- x_2_id - slope * x_1_id
        abline <- list(
          geom_abline(intercept = intercept, slope = slope, color = "red", linetype = "solid"),
          geom_abline(intercept = 0.8 * intercept, slope = slope, color = "red", linetype = "dashed"),
          geom_abline(intercept = 1.2 * intercept, slope = slope, color = "red", linetype = "dashed"))
        return(abline)
      }
    }
    
    
    x_v <- seq(1, 100, by = 1)
    y_v <- seq(1, 100, by = 1)
    grid <- expand.grid(x = x_v, y = y_v)%>%
      rowwise() %>% 
      mutate(output = technologie(x, y, alpha, type))
    
    
    vert <- function(x_1_id) {
      vline <- geom_segment(aes(x = x_1_id, xend = x_1_id, y = 0, yend = x_2_id), color = "orange", linetype = "longdash", size = 0.7)
      return(vline)
    }
    hor <- function(x_2_id) {
      hline <- geom_segment(aes(x = 0, xend = x_1_id, y = x_2_id, yend = x_2_id), color = "orange", linetype = "longdash", size = 0.7)
      return(hline)
    }
    
    
    
    
    
    
    
    plot <- ggplot(grid, aes(x = x, y = y)) +
      geom_contour(aes(z = output), breaks = c(y), color = "blue", size = 0.8) +
      geom_contour(aes(z = output), breaks = c(y*0.8, y*1.2), color = "blue", linetype = "dashed", size = 0.6) +
      coord_cartesian(xlim = c(0, 100), ylim = c(0, 100)) +
      theme_minimal() +
      labs(x = expression(x[1]), y = expression(x[2])) +
      theme(
        axis.title.x = element_text(size = 20),  # Adjust the font size of x-axis label
        axis.title.y = element_text(size = 20)   # Adjust the font size of y-axis label
      ) 
    
    combined_plot <- ggplot(grid, aes(x = x, y = y)) +
      coord_cartesian(xlim = c(0, 100), ylim = c(0, 100)) +
      theme_minimal() +
      labs(x = expression(x[1]), y = expression(x[2])) +
      theme(
        axis.title.x = element_text(size = 20),  # Adjust the font size of x-axis label
        axis.title.y = element_text(size = 20)   # Adjust the font size of y-axis label
      )
    
    
    if (showIsoLine) {
      
      combined_plot <- plot 
      
    } 
    
    if (showIsoCost) {
      
      combined_plot <- ggplot(grid, aes(x = x, y = y)) + 
        ikk(P_1, P_2, x_1_id, x_2_id, type) +
        geom_blank() +
        coord_cartesian(xlim = c(0, 100), ylim = c(0, 100)) +
        theme_minimal() +
        labs(x = expression(x[1]), y = expression(x[2])) +
        theme(
          axis.title.x = element_text(size = 20),  # Adjust the font size of x-axis label
          axis.title.y = element_text(size = 20)   # Adjust the font size of y-axis label
        )
        
      
    } 
    if (showIsoLine && showIsoCost && type != "ps") {
      
      combined_plot <- plot + ikk(P_1, P_2, x_1_id, x_2_id, type) +
        
        annotate("segment", x = x_1_id, xend = x_1_id, y = 0, yend = x_2_id, linetype = "dashed")+
        annotate("segment", x = 0, xend = x_1_id, y = x_2_id, yend = x_2_id, linetype = "dashed")+
        annotate("label", x = x_1_id, y = 0, label = round(x_1_id, 2))+
        annotate("label", x = 0, y = x_2_id, label = round(x_2_id, 2))
        
        
        
    } else if (showIsoLine && showIsoCost && type == "ps") {
      
      if (P_1 - (P_2*alpha) < 0) {
        
        combined_plot <- plot + ikk(P_1, P_2, x_1_id, x_2_id, type) +
          
          annotate("segment", x = x_1_id, xend = x_1_id, y = 0, yend = x_2_id, linetype = "dashed")+
          annotate("segment", x = 0, xend = x_1_id, y = x_2_id, yend = x_2_id, linetype = "dashed")+
          annotate("label", x = x_1_id, y = 0, label = round(x_1_id, 2))+
          annotate("label", x = 0, y = x_2_id, label = "0")
        
        
      } else if (P_1-(P_2*alpha) > 0) {
        
        combined_plot <- plot + ikk(P_1, P_2, x_1_id, x_2_id, type) +
          
          annotate("segment", x = x_1_id, xend = x_1_id, y = 0, yend = x_2_id, linetype = "dashed")+
          annotate("segment", x = 0, xend = x_1_id, y = x_2_id, yend = x_2_id, linetype = "dashed")+
          annotate("label", x = x_1_id, y = 0, label = "0")+
          annotate("label", x = 0, y = x_2_id, label = round(x_2_id, 2))
      
      
      } else if (P_1-(P_2*alpha) == 0) {
        
        combined_plot <- plot + ikk(P_1, P_2, x_1_id, x_2_id, type)+ 
          
         annotate("segment", x = x_1_id, xend = x_1_id, y = 0, yend = x_2_id, linetype = "dashed")+
         annotate("segment", x = 0, xend = x_1_id, y = x_2_id, yend = x_2_id, linetype = "dashed")+
         annotate("label", x = x_1_id, y = 0, label = "0")+
         annotate("label", x = 0, y = x_2_id, label = round(x_2_id, 2))
        
        
      }
    }
    
    
      
    
      
      
      
    print(combined_plot)
    
    
    
    
    
  })
  
  output$formel <- renderUI({
    formel <- switch(input$type,
                     "cd" = "$$f(x_1, x_2) = x_1^\\alpha x_2^{1-\\alpha}$$",
                     "ps" = "$$f(x_1, x_2) = \\alpha x_1 + x_2$$",
                     "kp" = "$$f(x_1, x_2) = min(\\alpha x_1, (1-\\alpha) x_2)$$",
                     "")
    withMathJax("Formel:", formel)
  })
  

  # output$optimum <- renderUI({
  #   alpha <- input$alpha
  #   P_1 <- input$P_1
  #   P_2 <- input$P_2
  #   y <- input$y
  #   type <- input$type
  #   disp <- input$disp_opt
  #   showIsoLine <- input$showIsoLine
  #   showIsoCost <- input$showIsoCost
  #   Ergebnisse <- minKost(y, alpha, P_1, P_2, type)
  #   x_1_id <- Ergebnisse$x_1_id
  #   x_2_id <- Ergebnisse$x_2_id
  #   min_Kos <- Ergebnisse$kosten_min
  #   output <- Ergebnisse$kosten_min
  #   
  # if (showIsoCost && showIsoLine && type != "ps") {
  #     
  #     
  #     
  #     withMathJax(HTML(paste("Optimum x\u2081:", round(x_1_id), "<br>", 
  #                            "Optimum x\u2082:", round(x_2_id))))
  #     
  # } else  if (showIsoCost && showIsoLine && type == "ps") {
  #     
  #   if (P_1 - (P_2 * alpha) < 0) {
  #     
  #     withMathJax(HTML(paste("Optimum x\u2081:", round(x_1_id), "<br>", 
  #                            "Optimum x\u2082:", "0")))
  #     
  #     
  #   } else if (P_1-(P_2*alpha) > 0) {
  #     
  #     withMathJax(HTML(paste("Optimum x\u2081:", "0", "<br>", 
  #                            "Optimum x\u2082:", round(x_2_id))))
  #     
  #   } else if (P_1-(P_2*alpha) == 0) {
  #     
  #     withMathJax(HTML(paste("Optimum x\u2081:",round(x_1_id), "<br>", 
  #                            "Optimum x\u2082:", round(x_2_id))))
  #   }
  #   
  #   }
  #   
  # })
  
  
  
}  



shinyApp(ui = ui, server = server)

Die kurze und die lange Frist

Im Gegensatz zu Konsum-/Kaufentscheidungen können Produktionsfaktoren nicht immer sofort angepasst werden (wenn man so will, ein Aspekt von Technologie)

Kurzfristig wird es Faktoren geben, die auf vorherbestimmten Niveaus fixiert sind, also zu Fixkosten führen

  • Installation bzw. Entfernen von Maschinen

  • Arbeitsgesetze und andere langfrist-Verträge (z.B. Mietverträge)

Langfristig können alle Faktoren frei angepasst werden



Teamarbeit: Welche Faktoren kann Nvidia kurzfristig anpassen?

Skalenerträge

Oft hört man Sätze wie “Wir müssen das Geschäft schnell hochskalieren”, also alle Produktionsfaktoren erhöhen - warum??

  • Bestimmte Technologien bzw. Produktionsfunktionen implizieren, dass man produktiver wird, wenn man größer ist. Dann haben wir steigende Skalenerträge: \[ f(tx_1, tx_2) > tf(x_1, x_2), \ \ \ \ \ t \in \mathbb{R}^+ \]

  • Manchmal führen bspw. fixe Produktionsfaktoren wie Gebäude dazu, dass Skalenerträge fallen \[ f(tx_1, tx_2) < tf(x_1, x_2), \ \ \ \ \ t \in \mathbb{R}^+ \]

  • Auch wenn Skalenerträge gerade langfristig u.a. durch Synergien steigen, kann man oft mittelfristig Produktionskapazitäten eins-zu-eins kopieren; dann sprechen wir von konstanten Skalenerträgen \[ f(tx_1, tx_2) = tf(x_1, x_2), \ \ \ \ \ t \in \mathbb{R}^+ \]

Teamarbeit: Wo sehen Sie im konkreten Fall Nvidia diese drei Arten von Skalenerträgen?

Das Verhalten einer Firma: Kostenminimierung

Kostenminimierungproblem

Unser Ziel ist es, ein Marktangebot zu modellieren, das auf optimalen Entscheidungen von Unternehmen basiert

Dazu werden wir zunächst die Kostenfunktion einer Firma herleiten - anschließend kann sie entscheiden, welche Menge sie optimalerweise produziert

Das Kostenminimierungsproblem lautet \[ \min_{\boldsymbol{x}} \; \sum_{i} w_i x_i, \ \ \ u.d.N. \ \ f(\boldsymbol{x}) = y \]

  • wobei \(w_i\) die Faktorpreise angeben und \(y\) eine unbestimmte Outputmenge darstellt

Hinweis: Faktorpreise nehmen Unternehmen aufgrund vollkommenen Wettbewerbs auf den Faktormärkten als gegeben hin – mehr dazu später!

Lösung

Das Ergebnis des Problems ist eine Kostenfunktion \[ c(\boldsymbol{w},y) \]

  • Im Optimum müssen die relativen Kosten eines Faktors seinem relativen Grenzprodukt entsprechen

  • Formal haben wir also für alle Faktoren \(i\) und \(j\) \[ \frac{w_i}{w_j} = \frac{MP_i}{MP_j} \equiv - TRS_{i,j} \]

Grafische und intuive Lösung

Nehmen wir wieder den einfachen Zweifaktorenfall an

Wie bei der Nutzenmaximierung können wir die Kostenfunktion finden, indem wir einen Tangentialpunkt bestimmen

  • Auf Technologieseite betrachten wir die Isoquante, die dem Outputniveau \(y\) entspricht
  • Auf Kostenseite ergibt sich durch die Faktorpreise eine Isokostengerade mit Kostenniveau \(C\) \[ w_1 x_1 + w_2 x_2 = C \ \ \ \leftrightarrow \ \ \ x_2 = \frac{C}{w_2} - \frac{w_1}{w_2} x_1 \]

Im Optimimum muss die Steigung der Isokostengerade also der Steigung der Isoquanten entsprechen, \(-w_1/w_2=TRS_{i,j}\) (siehe nächste Folie)

Grafische Darstellung der Kostenminimierung

#| standalone: true
#| viewerHeight: 600

library(ggplot2)
library(shiny)
library(dplyr)
library(purrr)
library(bslib)
library(bs4Dash)



ui <- fluidPage(
  
  sidebarLayout(
    sidebarPanel(
      tabsetPanel(
        tabPanel("Funktion",
                 br(),
                 selectInput("type",
                             h4("Technologie"),
                             choices = c("Cobb-Douglas" = "cd", "Perfekte Substitute" = "ps", "Perfekte Komplemente" = "kp"),
                             selected = "cd"),
                 
                 sliderInput("alpha",
                             h5("Wahl von α:",
                                br(),
                                ""),
                             min = 0,
                             max = 1,
                             value = 0.5,
                             step = 0.1),
                 
                 uiOutput('formel'),
                  br(),
                 
                 checkboxInput("showIsoLine",
                                              h5("Isoquanten anzeigen"),
                                              value = FALSE
                                ),
                 checkboxInput("showIsoCost",
                               h5("Isokostenkurve anzeigen"),
                               value = FALSE
                 ),
                               
                 # 
                 # 
                 # checkboxInput("disp_opt",
                 #               h5("Optima Anzeigen"),
                 #               value = FALSE
                 # ),
                 br(),
                 uiOutput('optimum'),
                 br(),
                 actionButton("reset", "Reset"),
                 
                 
                 
                 
                 
                 
        ),
        
        tabPanel("Einstellungen",
                 br(),
                 
                 numericInput("P_1",
                              h5("Faktorentlohnung w\u2081"),
                              min = 1,
                              max = 200,
                              value = 1,
                              step = 1),
                 
                 numericInput("P_2",
                              h5("Faktorentlohnung w\u2082"),
                              min = 1,
                              max = 200,
                              value = 1,
                              step = 1),
                 numericInput("y",
                              h5("Output y"),
                              min = 1,
                              max = 200,
                              value = 20,
                              step = 1)
                 
        )
      )
    ),  
    
    mainPanel(
      align = "center",
      plotOutput(outputId = "techPlot", height = "500px", width = "600px"),
    )
    
  )
)


server <- function(input, output, session) {
  
  technologie <- function(x_1, x_2, alpha, type) {
    if (type == "cd") return(x_1 ^ alpha * x_2 ^ (1-alpha))
 #   if (type == "ps") return(alpha * x_1 + (1-alpha) * x_2)
    if (type == "ps") return((alpha * x_1) + x_2)
    if (type == "kp") return(pmin(alpha*x_1, (1-alpha) * x_2))
      
      }
  
  minKost <- function(y, alpha, P_1, P_2, type) {
    
    if (type == "cd") {
      x_2_id <- y*((P_1/P_2)^alpha)*(((1-alpha)/alpha)^alpha)
      x_1_id <- x_2_id^((alpha-1)/alpha)*(y^(1/alpha))
      kosten_min <- x_1_id*P_1 + x_2_id*P_2
      return(list(kosten_min = kosten_min, x_1_id = x_1_id, x_2_id = x_2_id))
      
    } else if (type == "ps") {
      
      if (P_1 - P_2 * alpha < 0) {
        x_1_id <- y/alpha
        x_2_id <- 0
        kosten_min <- x_1_id*P_1
        return(list(kosten_min = kosten_min, x_1_id = x_1_id, x_2_id = x_2_id))
        
        
      } else if (P_1-P_2*alpha > 0) {
        x_2_id <- y
        x_1_id <- 0
        kosten_min <- x_2_id*P_2
        return(list(kosten_min = kosten_min, x_1_id = x_1_id, x_2_id = x_2_id))
        
      } else if (P_1-P_2*alpha == 0) {
        x_2_id <- y
        x_1_id <- 0
        kosten_min <- x_2_id*P_2
        return(list(kosten_min = kosten_min, x_1_id = x_1_id, x_2_id = x_2_id))
        
        
      }
      
    } else if (type == "kp") {
      x_1_id <- y/alpha
      x_2_id <- y/(1-alpha)
      kosten_min <- x_1_id*P_1 + x_2_id*P_2
      return(list(kosten_min = kosten_min, x_1_id = x_1_id, x_2_id = x_2_id))
    }
    else {
      x_1_id <- 1
      x_2_id <- 1
      kosten_min <- 1
      return(list(kosten_min = kosten_min, x_1_id = x_1_id, x_2_id = x_2_id))
    }
  }
  
  observeEvent(input$reset, {
    updateSliderInput(inputId = "alpha", value = 0.5)
    updateSelectInput(inputId = "type", selected = "cd")
    updateCheckboxInput(inputId = "showIsoCost", value = FALSE)
    updateCheckboxInput(inputId = "showIsoLine", value = FALSE)
    updateNumericInput(inputId = "P_1", value = 1)
    updateNumericInput(inputId = "P_2", value = 1)
    updateNumericInput(inputId = "y", value = 20)
  })
  
  output$techPlot <- renderPlot({
    
    alpha <- input$alpha
    
    P_1 <- input$P_1
    P_2 <- input$P_2
    
    y <- input$y
    
    type <- input$type
    
    disp <- input$disp_opt
    
    
    Ergebnisse <- minKost(y, alpha, P_1, P_2, type)
    x_1_id <- Ergebnisse$x_1_id
    x_2_id <- Ergebnisse$x_2_id
    min_Kos <- Ergebnisse$kosten_min
    output <- Ergebnisse$kosten_min
    showIsoLine <- input$showIsoLine
    showIsoCost <- input$showIsoCost
    
    
    ikk <- function(P_1, P_2, x_1_id, x_2_id, type) {
      if (type == "ps") {
        intercept <- x_2_id + (x_1_id*(P_1/P_2))
        slope <- -P_1 / P_2
        abline <- list(
          geom_abline(intercept = intercept, slope = slope, color = "red", linetype = "solid"),
          geom_abline(intercept = 0.8 * intercept, slope = slope, color = "red", linetype = "dashed"),
          geom_abline(intercept = 1.2 * intercept, slope = slope, color = "red", linetype = "dashed"))
        return(abline)
      } else {
        slope <- -P_1 / P_2
        intercept <- x_2_id - slope * x_1_id
        abline <- list(
          geom_abline(intercept = intercept, slope = slope, color = "red", linetype = "solid"),
          geom_abline(intercept = 0.8 * intercept, slope = slope, color = "red", linetype = "dashed"),
          geom_abline(intercept = 1.2 * intercept, slope = slope, color = "red", linetype = "dashed"))
        return(abline)
      }
    }
    
    
    x_v <- seq(1, 100, by = 1)
    y_v <- seq(1, 100, by = 1)
    grid <- expand.grid(x = x_v, y = y_v)%>%
      rowwise() %>% 
      mutate(output = technologie(x, y, alpha, type))
    
    
    vert <- function(x_1_id) {
      vline <- geom_segment(aes(x = x_1_id, xend = x_1_id, y = 0, yend = x_2_id), color = "orange", linetype = "longdash", size = 0.7)
      return(vline)
    }
    hor <- function(x_2_id) {
      hline <- geom_segment(aes(x = 0, xend = x_1_id, y = x_2_id, yend = x_2_id), color = "orange", linetype = "longdash", size = 0.7)
      return(hline)
    }
    
    
    
    
    
    
    
    plot <- ggplot(grid, aes(x = x, y = y)) +
      geom_contour(aes(z = output), breaks = c(y), color = "blue", size = 0.8) +
      geom_contour(aes(z = output), breaks = c(y*0.8, y*1.2), color = "blue", linetype = "dashed", size = 0.6) +
      coord_cartesian(xlim = c(0, 100), ylim = c(0, 100)) +
      theme_minimal() +
      labs(x = expression(x[1]), y = expression(x[2])) +
      theme(
        axis.title.x = element_text(size = 20),  # Adjust the font size of x-axis label
        axis.title.y = element_text(size = 20)   # Adjust the font size of y-axis label
      ) 
    
    combined_plot <- ggplot(grid, aes(x = x, y = y)) +
      coord_cartesian(xlim = c(0, 100), ylim = c(0, 100)) +
      theme_minimal() +
      labs(x = expression(x[1]), y = expression(x[2])) +
      theme(
        axis.title.x = element_text(size = 20),  # Adjust the font size of x-axis label
        axis.title.y = element_text(size = 20)   # Adjust the font size of y-axis label
      )
    
    
    if (showIsoLine) {
      
      combined_plot <- plot 
      
    } 
    
    if (showIsoCost) {
      
      combined_plot <- ggplot(grid, aes(x = x, y = y)) + 
        ikk(P_1, P_2, x_1_id, x_2_id, type) +
        geom_blank() +
        coord_cartesian(xlim = c(0, 100), ylim = c(0, 100)) +
        theme_minimal() +
        labs(x = expression(x[1]), y = expression(x[2])) +
        theme(
          axis.title.x = element_text(size = 20),  # Adjust the font size of x-axis label
          axis.title.y = element_text(size = 20)   # Adjust the font size of y-axis label
        )
        
      
    } 
    if (showIsoLine && showIsoCost && type != "ps") {
      
      combined_plot <- plot + ikk(P_1, P_2, x_1_id, x_2_id, type) +
        
        annotate("segment", x = x_1_id, xend = x_1_id, y = 0, yend = x_2_id, linetype = "dashed")+
        annotate("segment", x = 0, xend = x_1_id, y = x_2_id, yend = x_2_id, linetype = "dashed")+
        annotate("label", x = x_1_id, y = 0, label = round(x_1_id, 2))+
        annotate("label", x = 0, y = x_2_id, label = round(x_2_id, 2))
        
        
        
    } else if (showIsoLine && showIsoCost && type == "ps") {
      
      if (P_1 - (P_2*alpha) < 0) {
        
        combined_plot <- plot + ikk(P_1, P_2, x_1_id, x_2_id, type) +
          
          annotate("segment", x = x_1_id, xend = x_1_id, y = 0, yend = x_2_id, linetype = "dashed")+
          annotate("segment", x = 0, xend = x_1_id, y = x_2_id, yend = x_2_id, linetype = "dashed")+
          annotate("label", x = x_1_id, y = 0, label = round(x_1_id, 2))+
          annotate("label", x = 0, y = x_2_id, label = "0")
        
        
      } else if (P_1-(P_2*alpha) > 0) {
        
        combined_plot <- plot + ikk(P_1, P_2, x_1_id, x_2_id, type) +
          
          annotate("segment", x = x_1_id, xend = x_1_id, y = 0, yend = x_2_id, linetype = "dashed")+
          annotate("segment", x = 0, xend = x_1_id, y = x_2_id, yend = x_2_id, linetype = "dashed")+
          annotate("label", x = x_1_id, y = 0, label = "0")+
          annotate("label", x = 0, y = x_2_id, label = round(x_2_id, 2))
      
      
      } else if (P_1-(P_2*alpha) == 0) {
        
        combined_plot <- plot + ikk(P_1, P_2, x_1_id, x_2_id, type)+ 
          
         annotate("segment", x = x_1_id, xend = x_1_id, y = 0, yend = x_2_id, linetype = "dashed")+
         annotate("segment", x = 0, xend = x_1_id, y = x_2_id, yend = x_2_id, linetype = "dashed")+
         annotate("label", x = x_1_id, y = 0, label = "0")+
         annotate("label", x = 0, y = x_2_id, label = round(x_2_id, 2))
        
        
      }
    }
    
    
      
    
      
      
      
    print(combined_plot)
    
    
    
    
    
  })
  
  output$formel <- renderUI({
    formel <- switch(input$type,
                     "cd" = "$$f(x_1, x_2) = x_1^\\alpha x_2^{1-\\alpha}$$",
                     "ps" = "$$f(x_1, x_2) = \\alpha x_1 + x_2$$",
                     "kp" = "$$f(x_1, x_2) = min(\\alpha x_1, (1-\\alpha) x_2)$$",
                     "")
    withMathJax("Formel:", formel)
  })
  

  # output$optimum <- renderUI({
  #   alpha <- input$alpha
  #   P_1 <- input$P_1
  #   P_2 <- input$P_2
  #   y <- input$y
  #   type <- input$type
  #   disp <- input$disp_opt
  #   showIsoLine <- input$showIsoLine
  #   showIsoCost <- input$showIsoCost
  #   Ergebnisse <- minKost(y, alpha, P_1, P_2, type)
  #   x_1_id <- Ergebnisse$x_1_id
  #   x_2_id <- Ergebnisse$x_2_id
  #   min_Kos <- Ergebnisse$kosten_min
  #   output <- Ergebnisse$kosten_min
  #   
  # if (showIsoCost && showIsoLine && type != "ps") {
  #     
  #     
  #     
  #     withMathJax(HTML(paste("Optimum x\u2081:", round(x_1_id), "<br>", 
  #                            "Optimum x\u2082:", round(x_2_id))))
  #     
  # } else  if (showIsoCost && showIsoLine && type == "ps") {
  #     
  #   if (P_1 - (P_2 * alpha) < 0) {
  #     
  #     withMathJax(HTML(paste("Optimum x\u2081:", round(x_1_id), "<br>", 
  #                            "Optimum x\u2082:", "0")))
  #     
  #     
  #   } else if (P_1-(P_2*alpha) > 0) {
  #     
  #     withMathJax(HTML(paste("Optimum x\u2081:", "0", "<br>", 
  #                            "Optimum x\u2082:", round(x_2_id))))
  #     
  #   } else if (P_1-(P_2*alpha) == 0) {
  #     
  #     withMathJax(HTML(paste("Optimum x\u2081:",round(x_1_id), "<br>", 
  #                            "Optimum x\u2082:", round(x_2_id))))
  #   }
  #   
  #   }
  #   
  # })
  
  
  
}  



shinyApp(ui = ui, server = server)

Kostenarten

Je nach Zeithorizont und Art der involvierten Faktoren kann man verschiedene Kostenarten unterscheiden:

  • Fixe Kosten sind unabhängig vom Produktionsniveau und fallen auch ohne Output an; sie sind ein Phänomen der kurzen Frist
  • Quasifixe Kosten sind unabhängig vom Outputniveau, entstehen aber nur, wenn das Unternehmen eine positive Outputmenge erzeugt
  • Variable Kosten sind Ausgaben, die sich mit der Produktionsmenge \(y\) verändern
  • Verlorene Kosten sind bereits angefallene, nicht wieder einholbare Ausgaben, die für zukünftige Entscheidungen irrelevant sind

Beispiel für Kostenarten

Teamarbeit: ordnen Sie gemeinsam die folgenden Kosten in der Tabelle ein

Kosten fix quasi-fix variabel verloren
Büromiete (Jahresvertrag)
Forschung und Entwicklung
Serverwartung
Marketing
Produktionsanlagen
Mitarbeiterschulungen
Grafikprozessorenentwicklung
Prototypen
Komponenten (z.B. Chips)
Strom für Produktionsstätten

Nützliche Konzepte und Eigenschaften von Kostenkurven

Die Gesamtkosten eines Unternehmens sind \[ c(y) = F + c_v(y). \]

Für \(y > 0\) sind die Durchschnittskosten (Average Costs) \[ AC(y) = \frac{F}{y} + \frac{c_v(y)}{y} = AFC(y) + AVC(y). \]

  • \(AFC(y)\) - Average Fixed Costs (durchschnittliche Fixkosten)

  • \(AVC(y)\) - Average Variable Costs (durchschnittliche variable Kosten)

Grenzkosten (Marginal Costs) sind die Änderungsrate der Produktionskosten bei einer Änderung der Outputmenge \[ MC(y) = \frac{\partial c(y)}{\partial y} \]

Grafische Illustration von Kostentypen

Nach Varian, Abbildung 22.2

Das Verhalten der Unternehmung: das individuelle Angebot

Gewinnmaximierung

Kostenminimierung: Dass Unternehmen ihre Kosten minimieren wollen, erscheint zunächst als plausibel und unkontrovers

Um Angebotsfunktionen und letztlich ein Marktangebot zu modellieren, nehmen wir zudem Gewinnmaximierung in der betrachteten Periode an

  • Realistisch? Alternativ könnten Marktanteile, philanthropische Ziele (viele non-profits), individuelle Interessen (Familienunternehmen) oder sogar Schäden (hacker, fake news) im Mittelpunkt stehen

  • Realistisch? Unternehmen müssen investieren und planen für unterschiedliche Zeithorizonte

  • Gewinnmaximierung ist eine gute Approximation, insbesondere für börsennotierte Unternehmen wie Nvidia, und die Frist wird durch die Kostenfunktion abgebildet

Aber was ist der ökonomische Gewinn?

  • Alle Umsätze abzüglich aller Faktorentlohnungen zu Marktpreisen

Das Marktumfeld

Für die Angebotsseite benötigen wir außerdem Annahmen darüber, wie Unternehmen mit Kunden interagieren

  • Für unseren Benchmark nehmen wir an, dass Unternehmen keinerlei  Marktmacht besitzen (dies ist eine der problematischen Annahmen, die wir später in der Vorlesung genau unter die Lupe nehmen)
  • Auf Output- und Faktormärkten sind sie Preisnehmer und bieten zum jeweiligen Preis eine bestimmte Menge an oder fragen bestimmte Mengen nach
  • Vollkommener Wettbewerb ist eine Möglichkeit, diese Annahme zu begründen



Teamarbeit: Welche Güter- oder Dienstleistungsmärkte sind mit diesem Modell gut oder weniger gut beschrieben?

Herleitung des kurzfristigen individuellen Angebots

Das Gewinnmaximierungsproblem lautet unter diesen Annahmen \[ \max_{y \geq 0} \pi(y) = py - c(y) \]

Die notwendige Bedingung erster Ordnung ist \[ \underbrace{p}_{\text{Grenzerlös} \\ \ \ \ \ \ MR} \leq \underbrace{ \frac{\partial c(y^*)}{\partial y}}_{\text{Grenzkosten} \\ \ \ \ \ \ \ \ MC} \underbrace{= \frac{\partial c_v(y^*)}{\partial y}}_{\text{kurzfristig}} \]

Unternehmen vergleichen also Grenzerlös (Marginal Revenue) mit Grenzkosten

  • Verdiene ich mit der nächsten produzierten Einheit mehr als sie kostet? Dann muss ich mehr produzieren und \(y^*\) ist kein Optimum

  • Verdiene ich weniger? Dann muss ich mein Angebot weiter reduzieren

Hinweise zum individuellen Angebot

Beachte: die Bedingung erster Ordnung ist eine schwache Ungleichung, denn es kann optimal sein, nichts zu produzieren

Beachte: Kurzfristig werden die Fixkosten ignoriert; es muss daher kurzfristig eine Stillegungsbedingung gelten \[ py^{*,s} - c_v(y^{*,s}) - F \geq -F \ \ \ \leftrightarrow \ \ \ p \geq \frac{c_v(y^{*,s})}{y^{*,s}} = AVC(y^{*,s}) \]

Zusammengefasst ist die inverse individuelle Angebotskurve

\[ p = MC(y) \] Typischerweise hat sie eine schwach positive Steigung, da die Grenzkosten bei größerer Menge ebenfalls höher sind (siehe Stillegungsbedingung)

Das Branchenangebot

Kurzfristiges Branchenangebot

Bei \(n\) Unternehmen im Markt ist die Angebotskurve

\[ S(p) = \sum_{i=1}^n y_i(p). \]

Dieses Marktangebot steigt typischerweise im Preis

Da alle Unternehmen annahmegemäß den gleichen Preis verlangen müssen, um zu verkaufen, haben wir u.U. eine spannende Situation

  • Liegt ein beliebiger Preis \(p'\) über den Durchschnittskosten \(AC_i(y_i(p'))\) eines Unternehmens \(i\), so macht dieses einen ökonomischen Gewinn

  • Liegt er darunter, macht es einen Verlust

Langfristiges Branchenangebot: Eintritt und Austritt

Diese Situation entsteht kurzfristig, da es keinen Marktein- oder -austritt gibt

  • Das langfristige Angebot sollte daher nicht nur die langfristige Kostenfunktion, sondern auch Ein- und Austritt berücksichtigen

Gibt es keine  Markteintrittsbarrieren, werden so lange Unternehmen eintreten bzw. Produktionskapazitäten geschaffen, bis alle Gewinne auf Null gedrückt werden

  • Die Angebotskurve wird somit flacher bzw. elastischer

  • Produzieren alle Unternehmen mit der gleichen Technologie, ist das langfristige Angebot flach bei \(p=AC(y^{min})\), wobei \(y^{min}\) das Minimum der Durchschnittskostenkurve beschreibt

Nützliches Konzept: Produzentenrente

Analog zur Konsumentenrente definieren wir die Produzentenrente

  • Wie jede ökonomische Rente entspricht sie der Differenz zwischen Preis und den Opportunitäts- bzw. Produktionskosten

  • Im Fall eines Unternehmens also Umsatz minus variable Produktionskosten

  • Da letztere einfach dem Integral der Grenzkosten bis zur Produktionsmenge entsprechen, ist die Produzentenrente die Fläche links der Angebotskurve unterhalb des relevanten Preises

Grafische Darstellung von Marktangebot und Produzentenrente

#| standalone: true
#| viewerHeight: 600

library(shiny)
library(shinydashboard)
library(ggplot2)
library(graphics)
library(ggpattern)
library(dplyr)
library(purrr)
library(bslib)
library(bs4Dash)




ui <- fluidPage(
  
  
  sidebarLayout(
    sidebarPanel(
      tabsetPanel(
        tabPanel(h5("Einstellungen"),
                 br(),
                 checkboxInput("supp", "Inverses Angebot anzeigen", value = FALSE),
                 
                 checkboxInput("dem", "Inverse Nachfrage anzeigen", value = FALSE),
                 
                 sliderInput("slope_s", "Steigung Angebot", min = 0, max = 10, value = 1, step = 0.5),
                 sliderInput("slope_d", "Steigung Nachfrage", min = -10, max = 0, value = -1, step = 0.5),
                 
                 numericInput("absch_d", "Achsenabschnitt Nachfrage", min = 0, max = 100, value = 75),
                 
                 actionButton("reset", "Reset")
        ),
        
        
        
        tabPanel(h5("Wohlfahrt"),
                 checkboxInput("cs", "Konsumentenrente anzeigen", value = FALSE),
                 
                 checkboxInput("ps", "Produzentenrente anzeigen", value = FALSE),
                 
                 br(),
                 
                 
                 uiOutput('kons_r')   
                 
        ),
        
        
        tabPanel(h5("Steuern"),
                 
                 sliderInput("tax", "Steuerrate t", min = -30, max = 30, value = 0, step = 1),
                 br(),
                 uiOutput("steu_totg")
                 
                 
        )
      )
    ),
    mainPanel(align = "center",
              plotOutput(outputId = "ggwplot", height = "500px", width = "600px"),
    ),
  )
)


server <- function(input, output, session) {
  
  angebot <- function(a_s, x) {
    
    # p_s <- (x - 5)/a_s
    
    p_s <- a_s * x + 5
    
    return(p_s)
  }
  
  nachfrage <- function(a_d, b_d, x){
    
    # p_d <- (x - b_d)/a_d
    
    p_d <- a_d * x + b_d
    
    return(p_d)
    
  }
  
  opt <- function(a_s, a_d, b_d) {
    
    # p_opt <- (b_d - 5) / (a_s - a_d)
    #  x_opt <- a_d * p_opt + b_d
    
    x_opt <- (b_d - 5) / (a_s - a_d)
    p_opt <- a_d * x_opt + b_d 
    
    return(list(p_opt = p_opt, x_opt = x_opt))
  }
  
  
  
  
  
  
  
  
  observeEvent(list(input$tax, input$cs, input$ps, input$supp, input$dem, input$slope_d, input$slope_s, input$absch_d), {
    a_s <- input$slope_s
    a_d <- input$slope_d
    b_d <- input$absch_d
    
    cs <- input$cs
    ps <- input$ps
    
    
    x_v <- seq(0, 100, by = 0.5)
    
    p_s <- angebot(a_s, x_v)
    p_d <- nachfrage(a_d, b_d, x_v)
    t <- input$tax
    
    if (t != 0) {
      
      
      grid <- tibble(
        
        x_val = x_v,
        
        S = p_s + t,
        
        D = p_d
      )
      
      Ergebnisse <- opt(a_s, a_d, b_d)
      #p_s_opt <- (Ergebnisse$p_opt + (t*a_d)/(a_s-a_d))
      # p_d_opt <- (Ergebnisse$p_opt + (t*a_s)/(a_s-a_d))
      
      p_s_opt <- (((t - b_d)/a_d)+(5/a_s))/((1/a_s)-(1/a_d))
      p_d_opt <- p_s_opt + t
      
      x_t <- (p_s_opt - 5)/a_s
      
      # p_opt <- (b_d-5)/(a_s-a_d)
      # x_opt <- a_s * p_opt + 5
      
      x_opt <- (b_d - 5) / (a_s - a_d)
      p_opt <- a_d * x_opt + b_d 
    }
    
    else {
      
      
      grid <- tibble(
        
        x_val = x_v,
        
        S = p_s,
        
        D = p_d
      )
      
      Ergebnisse <- opt(a_s, a_d, b_d)
      p_opt <- Ergebnisse$p_opt 
      x_opt <- Ergebnisse$x_opt
      
      
    }
    
    output$ggwplot <- renderPlot({
      if (input$dem == TRUE && input$supp == TRUE) {
        g_plot <- ggplot(grid) +
          geom_line(aes(x = x_val, y = D, color = "Nachfrage"), size = 1.3) +
          geom_line(aes(x = x_val, y = S, color = "Angebot"), size = ifelse(t != 0, 1, 1.3), linetype = ifelse(t != 0, "dashed", "solid")) +
          scale_color_manual(values = c("Angebot" = "blue", "Nachfrage" = "red")) +
          guides(color = guide_legend(title = "Kurven", position = "bottom", title.position = "left", title.hjust = 0.5)) +
          
          coord_cartesian(xlim = c(-10, 100), ylim = c(-5, 100)) +
          theme_minimal() +
          labs(x = "Menge y", y = "Preis p") +
          theme(
            axis.text = element_text(size = 14),
            axis.title = element_text(size = 16),
            plot.title = element_text(size = 20),
            legend.position = c(0.9, 0.9),  # position -> legend
            legend.justification = c(0.5, 0.5),  # Top right corner
            legend.background = element_rect(fill = "white", color = "black"),
            legend.key = element_rect(fill = "white", color = "white")
          )
        
        
        
      } else if (input$dem == TRUE && input$supp == FALSE) {
        
        g_plot <- ggplot(grid) +
          geom_line(aes(x = x_val, y = D, color = "Nachfrage"), size = 1.3) +
          scale_color_manual(values = c("Nachfrage" = "red")) +
          guides(color = guide_legend(title = "Kurven", position = "bottom", title.position = "left", title.hjust = 0.5)) +
          coord_cartesian(xlim = c(-10, 100), ylim = c(-5, 100)) +
          theme_minimal() +
          labs(x = "Menge y", y = "Preis p") +
          theme(
            axis.text = element_text(size = 14),
            axis.title = element_text(size = 16),
            plot.title = element_text(size = 20),
            legend.position = c(0.9, 0.9),  # Adjust this as necessary to position the legend
            legend.justification = c(0.5, 0.5),  # Top right corner
            legend.background = element_rect(fill = "white", color = "black"),
            legend.key = element_rect(fill = "white", color = "white")
          )
        
      } else if (input$dem == FALSE && input$supp == TRUE ) {
        
        g_plot <- ggplot(grid) +
          geom_line(aes(x = x_val, y = S, color = "Angebot"), size = ifelse(t != 0, 1, 1.3), linetype = ifelse(t != 0, "dashed", "solid")) +
          scale_color_manual(values = c("Angebot" = "blue")) +
          guides(color = guide_legend(title = "Kurven", position = "bottom", title.position = "left", title.hjust = 0.5)) +
          coord_cartesian(xlim = c(-10, 100), ylim = c(-5, 100)) +
          theme_minimal() +
          labs(x = "Menge y", y = "Preis p") +
          theme(
            axis.text = element_text(size = 14),
            axis.title = element_text(size = 16),
            plot.title = element_text(size = 20),
            legend.position = c(0.9, 0.9),  # Adjust this as necessary to position the legend
            legend.justification = c(0.5, 0.5),  # Top right corner
            legend.background = element_rect(fill = "white", color = "black"),
            legend.key = element_rect(fill = "white", color = "white")
          )
        
      } else {
        
        g_plot <- ggplot(grid) +
          geom_line(aes(x = x_val, y = D), color = "white", size = 0.1) +
          coord_cartesian(xlim = c(-5, 100), ylim = c(-5, 100)) +
          theme_minimal() +
          labs(x = "Menge y", y = "Preis p") +
          theme(
            axis.text = element_text(size = 14),
            axis.title = element_text(size = 16),
            plot.title = element_text(size = 20),
            legend.position = c(0.9, 0.9),  # Adjust this as necessary to position the legend
            legend.justification = c(0.5, 0.5),  # Top right corner
            legend.background = element_rect(fill = "white", color = "black"),
            legend.key = element_rect(fill = "white", color = "white")
          )
      }
      
      
      
      if (input$dem && !is.null(p_opt) && cs == TRUE && t == 0) {
        g_plot <- g_plot +
          geom_ribbon_pattern(data = grid %>% filter(x_val <= x_opt),
                              aes(x = x_val, ymin = p_opt, ymax = D, fill = "Konsumentenrente"),
                              # fill = "#FF9999", 
                              pattern = "stripe", 
                              pattern_fill = "red", 
                              pattern_angle = 45, 
                              pattern_density = 0.3, 
                              pattern_spacing = 0.01, 
                              alpha = 0.3) 
        #   annotate("Text", x = -5, y = p_opt + 15, label = "KR", color = "red", size = 7)
        
        
      } else if (input$dem && !is.null(p_opt) && cs == TRUE && t != 0) {
        
        g_plot <- g_plot +
          geom_ribbon_pattern(data = grid %>% filter(x_val <= x_t),
                              aes(x = x_val, ymin = p_d_opt, ymax = D, fill = "Konsumentenrente" ),
                              # fill = "#FF9999", 
                              pattern = "stripe", 
                              pattern_fill = "red", 
                              pattern_angle = 45, 
                              pattern_density = 0.3, 
                              pattern_spacing = 0.01, 
                              alpha = 0.3) 
        
        
      } 
      
      if (input$supp && !is.null(p_opt) && input$ps && t == 0) {
        g_plot <- g_plot +
          geom_ribbon_pattern(data = grid %>% filter(x_val <= x_opt),
                              aes(x = x_val, ymin = S, ymax = p_opt, fill = "Produzentenrente"),
                              #        fill = "#ADD8E6", 
                              pattern = "stripe", 
                              pattern_fill = "blue", 
                              pattern_angle = 135, 
                              pattern_density = 0.3, 
                              pattern_spacing = 0.01, 
                              alpha = 0.3) 
        #  annotate("text", x = -5, y = p_opt - 15, label = "PS", color = "blue", size = 7)
        
        
        
        
      } else if (input$supp && !is.null(p_opt) && input$ps && t != 0) {
        
        g_plot <- g_plot +
          geom_ribbon_pattern(data = grid %>% filter(x_val <= x_t),
                              aes(x = x_val, ymin = S - t, ymax = p_s_opt, fill = "Produzentenrente"),
                              #       fill = "#ADD8E6", 
                              pattern = "stripe", 
                              pattern_fill = "blue", 
                              pattern_angle = 135, 
                              pattern_density = 0.3, 
                              pattern_spacing = 0.01, 
                              alpha = 0.3) 
        
        
      } 
      
      if (input$supp && !is.null(p_opt) && t > 0) {
        g_plot <- g_plot +
          geom_ribbon(data = grid %>% filter(x_val <= x_t),
                      aes(x = x_val, ymin = p_s_opt, ymax = p_opt,  fill = "Steuererträge"),
                      #     fill = "grey", 
                      alpha = 1) +
          geom_ribbon(data = grid %>% filter(x_val <= x_t),
                      aes(x = x_val, ymin = p_opt, ymax = p_d_opt,  fill = "Steuererträge"),
                      #     fill = "grey", 
                      alpha = 1) +
          
          geom_ribbon(data = grid %>% filter(x_val >= x_t & x_val <= x_opt),
                      aes(x = x_val, ymin = S - t, ymax = D, fill = "Wohlfahrtsverlust"),
                      #     fill = "black", 
                      alpha = 1) 
        # annotate("text", x = -5, y = p_opt - 15, label = "PS", color = "blue", size = 7)
      }
      
      
      if (t != 0) {
        g_plot <- g_plot +
          
          geom_line(aes(x = x_val, y = S - t, color = "Angebot"), size = 1.3, linetype = "solid") 
      }  
      
      label1 <- bquote(p[d] ~ "≈")
      label2 <- bquote(p[s] ~ "≈")
      label3 <- bquote(x[t] ~ "≈")
      
      if (t != 0) {
        g_plot <- g_plot +
          geom_segment(aes(x = x_t, xend = x_t, y = -5, yend = p_d_opt), color = "violet", linetype = "longdash", size = 0.7) +
          geom_segment(aes(x = 0, xend = x_t, y = p_d_opt, yend = p_d_opt), color = "violet", linetype = "longdash", size = 0.7) +
          geom_segment(aes(x = 0, xend = x_t, y = p_s_opt, yend = p_s_opt), color = "violet", linetype = "longdash", size = 0.7) +
          annotate("text", x = x_t, y = -5, label = as.expression(bquote(.(label3) ~ .(round(x_t)))), vjust = 1, hjust = 1, color = "violet", size = 5) +
          annotate("text", x = 0, y = p_d_opt, label = as.expression(bquote(.(label1) ~ .(round(p_d_opt)))), vjust = 0.5, hjust = 1, color = "violet", size = 5) +
          annotate("text", x = 0, y = p_s_opt, label = as.expression(bquote(.(label2) ~ .(round(p_s_opt)))), vjust = 0.5, hjust = 1, color = "violet", size = 5)
      }
      
      if ( t < 0) {
        g_plot <- g_plot +
          geom_segment(aes(x = x_t, xend = x_t, y = -5, yend = p_s_opt), color = "violet", linetype = "longdash", size = 0.7)
      }
      
      
      
      if (input$dem == TRUE && input$supp == TRUE) {
        g_plot <- g_plot +
          geom_segment(aes(x = x_opt, xend = x_opt, y = 0, yend = p_opt), color = "orange", linetype = "longdash", size = 0.7) +
          geom_segment(aes(x = 0, xend = x_opt, y = p_opt, yend = p_opt), color = "orange", linetype = "longdash", size = 0.7) +
          annotate("text", x = x_opt, y = 0, label = paste("x* ≈ ", round(x_opt)), vjust = 1, hjust = 0.5, color = "orange", size = 5) +
          annotate("text", x = 0, y = p_opt, label = paste("p* ≈ ", round(p_opt)), vjust = 0.5, hjust = 1, color = "orange", size = 5)
      }
      
      
      g_plot <- g_plot +
        scale_color_manual(
          values = c("Angebot" = "blue", "Nachfrage" = "red"),
          name = "Kurven"
        ) +
        scale_fill_manual(
          values = c("Konsumentenrente" = "#FF9999", "Produzentenrente" = "#ADD8E6", "Steuererträge" = "grey", "Wohlfahrtsverlust" = "black"), name = "") +
        guides(color = guide_legend(title = "Geraden", position = "bottom", title.position = "left", title.hjust = 1))
      
      
      
      
      
      print(g_plot) 
      
    })
  })
  
  
  
  
  observeEvent(input$reset, {
    updateSliderInput(inputId = "slope_d", value = -1)
    updateSliderInput(inputId = "slope_s", value = 1)
    updateSliderInput(inputId = "tax", value = 0)
    
    updateNumericInput(inputId = "absch_d", value = 75)
    updateCheckboxInput(inputId = "cs", value = FALSE)
    updateCheckboxInput(inputId = "ps", value = FALSE)
    
  })
  
  
  kons_r <- reactiveVal(0)
  prod_r <- reactiveVal(0)
  
  observeEvent(list(input$cs, input$ps, input$supp, input$tax, input$dem, input$slope_d, input$slope_s, input$absch_d), {
    a_s <- input$slope_s
    a_d <- input$slope_d
    b_d <- input$absch_d
    Ergebnisse <- opt(a_s, a_d, b_d)
    p_opt <- Ergebnisse$p_opt
    x_opt <- Ergebnisse$x_opt
    t <- input$tax
    
    p_s_opt <- (((t - b_d)/a_d)+(5/a_s))/((1/a_s)-(1/a_d))
    p_d_opt <- p_s_opt + t
    x_t <- (p_s_opt - 5)/a_s
    
    if (input$cs == TRUE && input$supp == TRUE && input$dem == TRUE && t == 0) {
      kons_r(((b_d-p_opt) * x_opt) / 2)
    } else if (input$cs == TRUE && input$supp == TRUE && input$dem == TRUE && t != 0) {
      kons_r(((b_d-p_d_opt) * x_t) / 2)
    } else {
      kons_r(0)
    }
    
    if (input$ps == TRUE && input$supp == TRUE && input$dem == TRUE && t == 0) {
      prod_r((p_opt * x_opt) / 2)
    } else if (input$cs == TRUE && input$supp == TRUE && input$dem == TRUE && t != 0) {
      prod_r((p_s_opt * x_t) / 2)
    } else {
      prod_r(0)
    }
    
  })
  
  
  
  
  output$kons_r <- renderUI({
    
    kons_r_r <- round(kons_r(), digits = 2)
    prod_r_r <- round(prod_r(), digits = 2)
    
    withMathJax(HTML(paste("Konsumentenrente:", kons_r_r, "<br>",
                           "Produzentenrente:", prod_r_r))
    )
  })
  
  
  steu_ber <- reactiveVal(0)
  totg_ber <- reactiveVal(0)
  
  observeEvent(list(input$cs, input$ps, input$supp, input$tax, input$dem, input$slope_d, input$slope_s, input$absch_d), {
    a_s <- input$slope_s
    a_d <- input$slope_d
    b_d <- input$absch_d
    Ergebnisse <- opt(a_s, a_d, b_d)
    p_opt <- Ergebnisse$p_opt
    x_opt <- Ergebnisse$x_opt
    t <- input$tax
    
    p_s_opt <- (((t - b_d)/a_d)+(5/a_s))/((1/a_s)-(1/a_d))
    p_d_opt <- p_s_opt + t
    x_t <- (p_s_opt - 5)/a_s
    
    
    if (input$supp == TRUE && input$dem == TRUE && t > 0) {
      
      steu_ber(-1 * (x_t*(p_d_opt-p_s_opt)))
      
      totg_ber((p_opt-p_s_opt)*(x_opt-x_t)/2 + (p_d_opt-p_opt)*(x_opt-x_t)/2 )
    }
    
    if (input$supp == TRUE && input$dem == TRUE && t < 0) {
      
      steu_ber(x_t*(p_s_opt-p_d_opt))
      
      totg_ber((p_s_opt-p_opt)*(x_t-x_opt)/2 + (p_opt-p_d_opt)*(x_t-x_opt)/2 )
    }
    
  })
  
  
  
  
  output$steu_totg <- renderUI({
    
    steu <- round(steu_ber(), digits = 2)
    totg <- round(totg_ber(), digits = 2)
    
    withMathJax(HTML(paste("Steuereinnahmen:", -steu, "<br>",
                           "Wohlfahrtsverlust:", totg))
    )
  })
  
}

shinyApp(ui = ui, server = server)

Wiederholungsfragen

  • Inwiefern ist eine Unterscheidung zwischen kurzer und langer Frist für Unternehmen wichtig?

  • Laden Sie die Kostenminimierungsgrafik auf Folie 18. Erklären Sie in Ihren Worten, welche Kurven zu sehen sind, welche Interpretation sie haben, und wie man mit ihrer Hilfe die Kostenfunktion eines Unternehmens finden kann.

  • Laden Sie die Grafik auf Folie 32.

    • Machen Sie die Angebotskurve elastischer. Repräsentiert diese Kurve nun ein langfristigeres Angebot?

    • Erklären Sie den Begriff Produzentenrente in eigenen Worten. Blenden Sie diese in der Grafik ein und ergründen Sie, wovon die Höhe der Produzentenrente abhängt.