Sou estudante de graduação em matemática (vou começar meu terceiro ano muito em breve). Estou tentando me ensinar complexidade computacional. Infelizmente, não existem cursos na minha universidade sobre o assunto e não há especialistas (na verdade, parece que minha universidade não tem nenhum especialista em CS teórico). Portanto, não tenho escolha para aprender o tópico, exceto por auto-estudo. Eu já passei pelos primeiros capítulos da complexidade computacional: Uma abordagem moderna [mas não resolvi nenhum dos exercícios (exceto dois ou três no primeiro capítulo, expondo o que são problemas de MT e de Halting)]
Eu enfrento alguns problemas com os exercícios de no texto:
uma coisa é que eu sinto que o tipo de pensamento necessário na complexidade computacional é bem diferente daquele da matemática com a qual estou familiarizado (há ênfase no pensamento algorítmico etc.) e como reduzir problemas a outros problemas e fazer uma TM simulando outra TM etc), o que acho difícil.
Existe alguma maneira que você recomenda para me ajudar a desenvolver esse nível de maturidade sobre algoritmos, reduções, etc.?
Uma das razões da dificuldade "1" é que não sei até que ponto devo ser rigoroso? Por exemplo, quando estou fazendo uma redução ou uma simulação, é possível ver intuitivamente que algo está claro e que pode ser feito, mas os detalhes seriam muito entediantes de se realizar e, portanto, sinto que não entenda a coisa muito bem. O ponto é que, eu sei que deve haver um compromisso entre rigor e pensamento intuitivo. Mas como não tenho guia nem instrutor, não sei onde essa linha deve estar.
quando devo executar todos os detalhes se algo estiver claro e quando devo ficar satisfeito com a intuição? Parece que há muito mais detalhes na complexidade computacional do que normalmente está presente na matemática que conheço e, portanto, onde deveria estar o compromisso?
Eu me pergunto se existe alguma fonte de exercícios \ problemas que são bem mais fáceis do que os fornecidos na complexidade computacional: Uma abordagem moderna para que eu possa me treinar com as noções básicas, construções etc. antes de enfrentar exercícios mais complicados. Além disso, uma fonte de provas (bastante detalhadas) dos principais teoremas seria ótima, pois muitos teoremas têm apenas um esboço da prova no texto.
Para os meus conhecimentos, aprendi noções básicas de programação (treinei por algum tempo em python, C e C ++), mas não muito, mas estou bastante familiarizado com a matemática, especialmente com a lógica matemática (até os teoremas da completude e da incompletude), conjunto avançado teoria (forçar), álgebra (linear, abstrata, álgebra universal e teoria de algumas categorias) e noções básicas de topologia e análise de reais. Também fiz um curso de matemática discreta (combinatória + teoria dos grafos).
Peço desculpas se minha pergunta está fora do tópico, mas não conheço um lugar melhor para propor essa pergunta do que aqui.
fonte
Respostas:
Minha recomendação é focar em duas coisas: pré-requisitos e prática.
Pré-requisitos: Vai ser mais difícil aprender a complexidade computacional sem primeiro entender bem os algoritmos. Em muitas escolas, uma aula de algoritmos é um pré-requisito para a aula de complexidade computacional. Você menciona que sente falta de maturidade em algoritmos e em sua posição, quem não gostaria? É um assunto não trivial que você não estudou. Portanto, meu primeiro conselho é: antes de gastar muito tempo com complexidade computacional, primeiro dedique algum tempo estudando algoritmos. Existem muitos bons livros didáticos de algoritmos e cursos on-line (por exemplo, via Udacity, Coursera ou EdX). Pode ser útil gastar algum tempo aprendendo esse material. Você não precisa aprender todos os algoritmos do mundo, mas tente entender algumas técnicas algorítmicas comuns; projetar reduções é basicamente projetar um algoritmo, portanto esse conhecimento será útil. Além disso, verifique se você se sente confortável com as provas de correção dos algoritmos e da análise assintótica do tempo de execução.
Em seguida, pratique. Ninguém começa com uma maturidade com reduções. A maneira de se sentir mais confortável com isso é praticando - faça exercícios até que você se sinta à vontade com o material ou os exercícios revelem alguma lacuna na sua compreensão (sobre a qual você poderá voltar e se concentrar em aprender mais sobre). Você provavelmente não pode aprender o material sem esse tipo de prática.
Para ajudá-lo a praticar, pode ser útil procurar um curso on-line (um MOOC) sobre complexidade computacional. Você pode verificar Udacity, Coursera ou EdX.
Quão rigoroso você deve ser? Rigoroso o suficiente para que você esteja convencido de que poderia preencher todos os detalhes se necessário (e que um colega de classe em um nível semelhante de estudos possa preencher todos os detalhes sem pensar muito - eles concordariam em preencher os detalhes. tedioso, mas direto e óbvio).
fonte
Dado que sou o oposto (estudando ciência da computação / engenharia, estudando matemática), acho que posso esclarecer alguns tópicos.
Recentemente, participei de um curso de algoritmos e teoria da complexidade que abordava algoritmos, linguagens formais e teoria da complexidade. Eu acho que todos os três serão muito importantes se você quiser realmente entender o que está fazendo. Por exemplo, se você não entender as implicações do grande O e como analisar os tempos de execução, não entenderá realmente o que P e NP representam e será mais difícil mudar para outras classes de complexidade. Se você não entender TMs, autômatos etc., não entenderá linguagens regulares, CFGs e o que representam linguagens decidíveis e recursivamente enumeráveis. Portanto, minhas sugestões se originam de conexões que fiz com a matemática da ciência da computação.
Você adotou a teoria dos conjuntos e a análise real. Você deve estar familiarizado com a indução da maioria dos seus cursos (uma ferramenta que foi a parte mais desafiadora da análise de algoritmos para muitos colegas de classe) e a recursão provavelmente virá naturalmente para você. Quando se trata de objetos mais abstratos, embora não diretamente relacionados, acho que uma base forte na álgebra abstrata (e qualquer outra coisa) provará ser uma enorme vantagem que você tem. Grupos, anéis etc. são objetos algébricos que contêm alguma estrutura e você possui mapas e morfismos entre eles. Máquinas de Turing e autômatos são estruturas computacionais que contêm alguma estrutura e regras e têm transformações entre elas (a construção de Thompson para expressões regulares em NFAs, TMs multi-fitas em uma única fita TM).
Não tenho certeza do que você está perguntando especificamente, mas se você puder ser rigoroso, faça-o. Existem algumas técnicas usadas na matemática que são usadas em muitas construções (análise real usando provas epsilon delta que se acumulam no cálculo a partir de conceitos simples) e existem técnicas usadas na teoria da complexidade (reduções de um problema para outro, pense em um mapa injetivo onde você deve fornecer o mapa, em vez de provar que é injetivo).
Este curso ( https://courses.engr.illinois.edu/cs374/lectures.html ) fornece notas de aula e slides e possui ótimos materiais de referência introdutórios. De forma alguma isso cobre tudo, mas pode ser um ótimo começo para você. O trabalho de laboratório é bastante agradável de analisar e testar sua compreensão, mas muitas vezes é mais difícil do que o conhecimento necessário.
Por fim, sua matemática discreta será de grande ajuda durante tudo isso. Você verá a importância da teoria dos grafos na análise e no design de algoritmos, bem como na combinatória para análise da estrutura de dados. Boa sorte e espero que você encontre o que está procurando!
fonte
Eu sugiro que você (a) determine que pré-requisito de matemática você precisa, (b) mantenha-se realmente entendendo e resolva os primeiros 3-4 problemas em cada capítulo, confie em mim mesmo que demorem muito, você vai entender então, rapidamente, com problemas futuros.
fonte