VertexContract and contraction of vertices of degree 2

An interesting question! Here is how I would approach it:

  1. Create a random graph and highlighted the vertexes of degree 2:
g = RandomGraph[{30, 40}]
degree2[g_Graph] := Select[VertexList[g], VertexDegree[g, #] == 2 &]
HighlightGraph[g, degree2[g]]

enter image description here

  1. Generate a list of connected components among the vertexes of degree 2. As you can see, there are 5 individual vertexes that need to be removed individually, and 2 that need to be removed together.
components2[g_Graph] := ConnectedComponents[Subgraph[g, degree2[g]]]
Subgraph[g, components2[g]]

enter image description here

  1. Next, in order to use VertexContract, as explained by Vitaly, we need to add one of the vertexes connected to each component:
contractComponent[g_Graph, l_List] := 
 Prepend[l, 
  RandomChoice@Complement[VertexList@NeighborhoodGraph[g, l, 1], l]]

Let's visualize what we have so far:

HighlightGraph[g, 
 Flatten[contractComponent[g, #] & /@ components2[g]]]

enter image description here

  1. The only thing left is to contract all these components one by one:
Fold[VertexContract, g, contractComponent[g, #] & /@ components2[g]]

enter image description here

Note: This does not preserve the coordinates of the vertexes, but it can be easily done and is left as an exercise to the reader :).

Update. 5. Which is actually easier that it sounds:

graphVertexCoordinates[g_] := (# -> PropertyValue[{g, #}, VertexCoordinates]) & /@ 
  VertexList[g]
remove2s[g_Graph] := 
 Graph[Fold[VertexContract, g, 
   contractComponent[g, #] & /@ components2[g]],
  VertexCoordinates -> graphVertexCoordinates[g]]
remove2s[g]

enter image description here


ClearAll[aL, vContract]
aL[d_:2] := {#2, Select[Function[x, VertexDegree[#, x] == d]] @ AdjacencyList[##]} &;

vContract[d_:2][g_] := Fold[VertexContract, g, 
    aL[d][g, #] & /@ Select[VertexDegree[g, #] != d &][VertexList[g]]]

Graph[vContract[][mygraph], VertexLabels -> {_ -> "Name"}, 
 VertexCoordinates -> {v_ :> GraphEmbedding[mygraph][[v]]}]

enter image description here

SeedRandom[1]
rg = RandomGraph[{50, 70}, VertexLabels -> "Name"];

Row[{HighlightGraph[rg, v_ /; VertexDegree[rg, v] == 2, ImageSize -> 400], 
  Graph[vContract[][rg], ImageSize -> 400, VertexLabels -> {_ -> "Name"}, 
   VertexCoordinates -> {v_ :> GraphEmbedding[rg][[v]]}]},
 Spacer[15]]

enter image description here

Successively contract vertices with VertexDegree 1:

d = 1;
Row[{HighlightGraph[rg, v_ /; VertexDegree[rg, v] == d, ImageSize -> 400], 
  Graph[vContract[d][rg], ImageSize -> 400, 
   VertexLabels -> {_ -> "Name"}, 
   VertexCoordinates -> {v_ :> GraphEmbedding[rg][[v]]}]}, Spacer[15]]

enter image description here

With d = 3 we get

enter image description here


IGSmoothen from the IGraph/M package does precisely what you are asking for. It will also add up the weights of merged edges.

It will be by far the fastest and simplest solution. Note that IGSmoothen takes linear time, unlike some of the other proposed solutions.


Example

Needs["IGraphM`"]

Create a graph:

g = IGGiantComponent@RandomGraph[{100, 100}]

enter image description here

These vertices will be smoothened out:

HighlightGraph[g, Pick[VertexList[g], VertexDegree[g], 2]]

enter image description here

Smoothen the graph:

IGSmoothen[g]

enter image description here

Smoothen the graph while preserving the original vertex coordinates:

vertexAssoc[fun_][g_] := AssociationThread[VertexList[g], fun[g]]

IGSmoothen[g] // IGVertexMap[vertexAssoc[GraphEmbedding][g], VertexCoordinates -> VertexList]

enter image description here

Compare smoothened to original, with preserved vertex coordinates:

FlipView[{%, g}]

enter image description here