Here, I define \addProblemPlusSolution{}{} for defining problem/solution sets, and then \showProblemsThenSolutions to output all the problems sequentially, followed by all of the solutions, with hyperlinked references back and forth. No \labels and \refs are placed explicitly by the user, but are auto-generated by \showProblemsThenSolutions.
I don't do anything special in the formatting, other than to create a new \subsection* for each problem and solution, respectively. However, one could add a page break between problems and solutions, additional sectioning, etc.
I use Werner's label solution (the \mynameis macro) at How to force a label to be a given string?
\documentclass{article}
\usepackage{hyperref}
\usepackage{lipsum}
\usepackage{ifthen}
\makeatletter
\newcommand{\mynameis}[1]{%
\phantomsection#1% Mark hyperlink
\renewcommand{\@currentlabel}{#1}%
\renewcommand{\@currentlabelname}{#1}}
\makeatother
\newcounter{probcount}
\newcounter{pcindex}
\newcommand\addProblemPlusSolution[2]{%
\stepcounter{probcount}
\expandafter\def\csname P\romannumeral\theprobcount\endcsname{#1}%
\expandafter\def\csname S\romannumeral\theprobcount\endcsname{#2}%
}
\newcommand\showProblemsThenSolutions{%
\setcounter{pcindex}{0}%
\whiledo{\thepcindex < \theprobcount}{%
\stepcounter{pcindex}%
\subsection*{\mynameis{Problem \thepcindex}%
\label{LP\romannumeral\thepcindex}
{\small\mdseries(see \ref{LS\romannumeral\thepcindex})}}
\csname P\romannumeral\thepcindex\endcsname
}%
\setcounter{pcindex}{0}%
\whiledo{\thepcindex < \theprobcount}{%
\stepcounter{pcindex}%
\subsection*{\mynameis{Solution \thepcindex}%
\label{LS\romannumeral\thepcindex}
{\small\mdseries(see \ref{LP\romannumeral\thepcindex})}}
\csname S\romannumeral\thepcindex\endcsname
}%
}
\begin{document}
\addProblemPlusSolution
{
\lipsum[1-3]
\[ y = mx + b\]
}{
\[ m = 3, \quad b = 12 \]
\lipsum[3-4]
}
\addProblemPlusSolution
{
\lipsum[2-3]
\[E = mc^2\]
}{
\[ c = 186,000 \textrm{mi/s} \]
\lipsum[4]
}
\showProblemsThenSolutions
\end{document}

