int legacyCommandLine(int argc, char *argv[]) { graphP theGraph = gp_New(); int Result; Result = gp_Read(theGraph, argv[1]); if (Result != OK) { if (Result != NONEMBEDDABLE) { if (strlen(argv[1]) > MAXLINE - 100) sprintf(Line, "Failed to read graph\n"); else sprintf(Line, "Failed to read graph %s\n", argv[1]); ErrorMessage(Line); return -2; } } Result = gp_Embed(theGraph, EMBEDFLAGS_PLANAR); if (Result == OK) { gp_SortVertices(theGraph); gp_Write(theGraph, argv[2], WRITE_ADJLIST); } else if (Result == NONEMBEDDABLE) { if (argc >= 5 && strcmp(argv[3], "-n")==0) { gp_SortVertices(theGraph); gp_Write(theGraph, argv[4], WRITE_ADJLIST); } } else Result = NOTOK; gp_Free(&theGraph); // In the legacy 1.x versions, OK/NONEMBEDDABLE was 0 and NOTOK was -2 return Result==OK || Result==NONEMBEDDABLE ? 0 : -2; }
int RandomGraphs(char command, int NumGraphs, int SizeOfGraphs) { char theFileName[256]; int K, countUpdateFreq; int Result=OK, MainStatistic=0; int ObstructionMinorFreqs[NUM_MINORS]; graphP theGraph=NULL, origGraph=NULL; platform_time start, end; int embedFlags = GetEmbedFlags(command); int ReuseGraphs = TRUE; GetNumberIfZero(&NumGraphs, "Enter number of graphs to generate:", 1, 1000000000); GetNumberIfZero(&SizeOfGraphs, "Enter size of graphs:", 1, 10000); theGraph = MakeGraph(SizeOfGraphs, command); origGraph = MakeGraph(SizeOfGraphs, command); if (theGraph == NULL || origGraph == NULL) { gp_Free(&theGraph); return NOTOK; } // Initialize a secondary statistics array for (K=0; K < NUM_MINORS; K++) ObstructionMinorFreqs[K] = 0; // Seed the random number generator with "now". Do it after any prompting // to tie randomness to human process of answering the prompt. srand(time(NULL)); // Select a counter update frequency that updates more frequently with larger graphs // and which is relatively prime with 10 so that all digits of the count will change // even though we aren't showing the count value on every iteration countUpdateFreq = 3579 / SizeOfGraphs; countUpdateFreq = countUpdateFreq < 1 ? 1 : countUpdateFreq; countUpdateFreq = countUpdateFreq % 2 == 0 ? countUpdateFreq+1 : countUpdateFreq; countUpdateFreq = countUpdateFreq % 5 == 0 ? countUpdateFreq+2 : countUpdateFreq; // Start the count fprintf(stdout, "0\r"); fflush(stdout); // Start the timer platform_GetTime(start); // Generate and process the number of graphs requested for (K=0; K < NumGraphs; K++) { if ((Result = gp_CreateRandomGraph(theGraph)) == OK) { if (tolower(OrigOut)=='y') { sprintf(theFileName, "random\\%d.txt", K%10); gp_Write(theGraph, theFileName, WRITE_ADJLIST); } gp_CopyGraph(origGraph, theGraph); if (strchr("pdo234", command)) { Result = gp_Embed(theGraph, embedFlags); if (gp_TestEmbedResultIntegrity(theGraph, origGraph, Result) != Result) Result = NOTOK; if (Result == OK) { MainStatistic++; if (tolower(EmbeddableOut) == 'y') { sprintf(theFileName, "embedded\\%d.txt", K%10); gp_Write(theGraph, theFileName, WRITE_ADJMATRIX); } if (tolower(AdjListsForEmbeddingsOut) == 'y') { sprintf(theFileName, "adjlist\\%d.txt", K%10); gp_Write(theGraph, theFileName, WRITE_ADJLIST); } } else if (Result == NONEMBEDDABLE) { if (embedFlags == EMBEDFLAGS_PLANAR || embedFlags == EMBEDFLAGS_OUTERPLANAR) { if (theGraph->IC.minorType & MINORTYPE_A) ObstructionMinorFreqs[0] ++; else if (theGraph->IC.minorType & MINORTYPE_B) ObstructionMinorFreqs[1] ++; else if (theGraph->IC.minorType & MINORTYPE_C) ObstructionMinorFreqs[2] ++; else if (theGraph->IC.minorType & MINORTYPE_D) ObstructionMinorFreqs[3] ++; else if (theGraph->IC.minorType & MINORTYPE_E) ObstructionMinorFreqs[4] ++; if (theGraph->IC.minorType & MINORTYPE_E1) ObstructionMinorFreqs[5] ++; else if (theGraph->IC.minorType & MINORTYPE_E2) ObstructionMinorFreqs[6] ++; else if (theGraph->IC.minorType & MINORTYPE_E3) ObstructionMinorFreqs[7] ++; else if (theGraph->IC.minorType & MINORTYPE_E4) ObstructionMinorFreqs[8] ++; if (tolower(ObstructedOut) == 'y') { sprintf(theFileName, "obstructed\\%d.txt", K%10); gp_Write(theGraph, theFileName, WRITE_ADJMATRIX); } } } } else if (command == 'c') { if ((Result = gp_ColorVertices(theGraph)) == OK) Result = gp_ColorVerticesIntegrityCheck(theGraph, origGraph); if (Result == OK && gp_GetNumColorsUsed(theGraph) <= 5) MainStatistic++; } // If there is an error in processing, then write the file for debugging if (Result != OK && Result != NONEMBEDDABLE) { sprintf(theFileName, "error\\%d.txt", K%10); gp_Write(origGraph, theFileName, WRITE_ADJLIST); } } // Reinitialize or recreate graphs for next iteration ReinitializeGraph(&theGraph, ReuseGraphs, command); ReinitializeGraph(&origGraph, ReuseGraphs, command); // Show progress, but not so often that it bogs down progress if (quietMode == 'n' && (K+1) % countUpdateFreq == 0) { fprintf(stdout, "%d\r", K+1); fflush(stdout); } // Terminate loop on error if (Result != OK && Result != NONEMBEDDABLE) { ErrorMessage("\nError found\n"); Result = NOTOK; break; } } // Stop the timer platform_GetTime(end); // Finish the count fprintf(stdout, "%d\n", NumGraphs); fflush(stdout); // Free the graph structures created before the loop gp_Free(&theGraph); gp_Free(&origGraph); // Print some demographic results if (Result == OK || Result == NONEMBEDDABLE) Message("\nNo Errors Found."); sprintf(Line, "\nDone (%.3lf seconds).\n", platform_GetDuration(start,end)); Message(Line); // Report statistics for planar or outerplanar embedding if (embedFlags == EMBEDFLAGS_PLANAR || embedFlags == EMBEDFLAGS_OUTERPLANAR) { sprintf(Line, "Num Embedded=%d.\n", MainStatistic); Message(Line); for (K=0; K<5; K++) { // Outerplanarity does not produces minors C and D if (embedFlags == EMBEDFLAGS_OUTERPLANAR && (K==2 || K==3)) continue; sprintf(Line, "Minor %c = %d\n", K+'A', ObstructionMinorFreqs[K]); Message(Line); } if (!(embedFlags & ~EMBEDFLAGS_PLANAR)) { sprintf(Line, "\nNote: E1 are added to C, E2 are added to A, and E=E3+E4+K5 homeomorphs.\n"); Message(Line); for (K=5; K<NUM_MINORS; K++) { sprintf(Line, "Minor E%d = %d\n", K-4, ObstructionMinorFreqs[K]); Message(Line); } } } // Report statistics for graph drawing else if (embedFlags == EMBEDFLAGS_DRAWPLANAR) { sprintf(Line, "Num Graphs Embedded and Drawn=%d.\n", MainStatistic); Message(Line); } // Report statistics for subgraph homeomorphism algorithms else if (embedFlags == EMBEDFLAGS_SEARCHFORK23) { sprintf(Line, "Of the generated graphs, %d did not contain a K_{2,3} homeomorph as a subgraph.\n", MainStatistic); Message(Line); } else if (embedFlags == EMBEDFLAGS_SEARCHFORK33) { sprintf(Line, "Of the generated graphs, %d did not contain a K_{3,3} homeomorph as a subgraph.\n", MainStatistic); Message(Line); } else if (embedFlags == EMBEDFLAGS_SEARCHFORK4) { sprintf(Line, "Of the generated graphs, %d did not contain a K_4 homeomorph as a subgraph.\n", MainStatistic); Message(Line); } // Report statistics for vertex coloring else if (command == 'c') { sprintf(Line, "Num Graphs colored with 5 or fewer colors=%d.\n", MainStatistic); Message(Line); } FlushConsole(stdout); return Result==OK || Result==NONEMBEDDABLE ? OK : NOTOK; }
int RandomGraph(char command, int extraEdges, int numVertices, char *outfileName, char *outfile2Name) { int Result; platform_time start, end; graphP theGraph=NULL, origGraph; int embedFlags = GetEmbedFlags(command); char saveEdgeListFormat; GetNumberIfZero(&numVertices, "Enter number of vertices:", 1, 1000000); if ((theGraph = MakeGraph(numVertices, command)) == NULL) return NOTOK; srand(time(NULL)); Message("Creating the random graph...\n"); platform_GetTime(start); if (gp_CreateRandomGraphEx(theGraph, 3*numVertices-6+extraEdges) != OK) { ErrorMessage("gp_CreateRandomGraphEx() failed\n"); return NOTOK; } platform_GetTime(end); sprintf(Line, "Created random graph with %d edges in %.3lf seconds. ", theGraph->M, platform_GetDuration(start,end)); Message(Line); FlushConsole(stdout); // The user may have requested a copy of the random graph before processing if (outfile2Name != NULL) { gp_Write(theGraph, outfile2Name, WRITE_ADJLIST); } origGraph = gp_DupGraph(theGraph); // Do the requested algorithm on the randomly generated graph Message("Now processing\n"); FlushConsole(stdout); if (strchr("pdo234", command)) { platform_GetTime(start); Result = gp_Embed(theGraph, embedFlags); platform_GetTime(end); gp_SortVertices(theGraph); if (gp_TestEmbedResultIntegrity(theGraph, origGraph, Result) != Result) Result = NOTOK; } else if (command == 'c') { platform_GetTime(start); Result = gp_ColorVertices(theGraph); platform_GetTime(end); } else Result = NOTOK; // Write what the algorithm determined and how long it took WriteAlgorithmResults(theGraph, Result, command, start, end, NULL); // On successful algorithm result, write the output file and see if the // user wants the edge list formatted file. if (Result == OK || Result == NONEMBEDDABLE) { if (outfileName != NULL) gp_Write(theGraph, outfileName, WRITE_ADJLIST); Prompt("Do you want to save the generated graph in edge list format (y/n)? "); fflush(stdin); scanf(" %c", &saveEdgeListFormat); if (tolower(saveEdgeListFormat) == 'y') { char *fileName = "maxPlanarEdgeList.txt"; if (extraEdges > 0) fileName = "nonPlanarEdgeList.txt"; SaveAsciiGraph(theGraph, fileName); sprintf(Line, "Edge list format saved to '%s'\n", fileName); Message(Line); } } else ErrorMessage("Failure occurred"); gp_Free(&theGraph); gp_Free(&origGraph); FlushConsole(stdout); return Result; }
int SpecificGraph(char command, char *infileName, char *outfileName, char *outfile2Name) { graphP theGraph, origGraph; platform_time start, end; int Result; // Get the filename of the graph to test if ((infileName = ConstructInputFilename(infileName)) == NULL) return NOTOK; // Create the graph and, if needed, attach the correct algorithm to it theGraph = gp_New(); switch (command) { case 'd' : gp_AttachDrawPlanar(theGraph); break; case '2' : gp_AttachK23Search(theGraph); break; case '3' : gp_AttachK33Search(theGraph); break; case '4' : gp_AttachK4Search(theGraph); break; case 'c' : gp_AttachColorVertices(theGraph); break; } // Read the graph into memory Result = gp_Read(theGraph, infileName); if (Result == NONEMBEDDABLE) { Message("The graph contains too many edges.\n"); // Some of the algorithms will still run correctly with some edges removed. if (strchr("pdo234", command)) { Message("Some edges were removed, but the algorithm will still run correctly.\n"); Result = OK; } } // If there was an unrecoverable error, report it if (Result != OK) ErrorMessage("Failed to read graph\n"); // Otherwise, call the correct algorithm on it else { // Copy the graph for integrity checking origGraph = gp_DupGraph(theGraph); // Run the algorithm if (strchr("pdo234", command)) { int embedFlags = GetEmbedFlags(command); platform_GetTime(start); // gp_CreateDFSTree(theGraph); // gp_SortVertices(theGraph); // gp_Write(theGraph, "debug.before.txt", WRITE_DEBUGINFO); // gp_SortVertices(theGraph); Result = gp_Embed(theGraph, embedFlags); platform_GetTime(end); Result = gp_TestEmbedResultIntegrity(theGraph, origGraph, Result); } else { platform_GetTime(start); if (command == 'c') { if ((Result = gp_ColorVertices(theGraph)) == OK) Result = gp_ColorVerticesIntegrityCheck(theGraph, origGraph); } else Result = NOTOK; platform_GetTime(end); } // Write what the algorithm determined and how long it took WriteAlgorithmResults(theGraph, Result, command, start, end, infileName); // Free the graph obtained for integrity checking. gp_Free(&origGraph); } // Report an error, if there was one, free the graph, and return if (Result != OK && Result != NONEMBEDDABLE) { ErrorMessage("AN ERROR HAS BEEN DETECTED\n"); Result = NOTOK; // gp_Write(theGraph, "debug.after.txt", WRITE_DEBUGINFO); } // Provide the output file(s) else { // Restore the vertex ordering of the original graph (undo DFS numbering) if (strchr("pdo234", command)) gp_SortVertices(theGraph); // Determine the name of the primary output file outfileName = ConstructPrimaryOutputFilename(infileName, outfileName, command); // For some algorithms, the primary output file is not always written if ((strchr("pdo", command) && Result == NONEMBEDDABLE) || (strchr("234", command) && Result == OK)) { // Do not write the file } // Write the primary output file, if appropriate to do so else { gp_Write(theGraph, outfileName, WRITE_ADJLIST); } // NOW WE WANT TO WRITE THE SECONDARY OUTPUT FILE // When called from the menu system, we want to write the planar or outerplanar // obstruction, if one exists. For planar graph drawing, we want the character // art rendition. An empty but non-NULL string is passed to indicate the necessity // of selecting a default name for the second output file. if (outfile2Name != NULL) { if ((command == 'p' || command == 'o') && Result == NONEMBEDDABLE) { // By default, use the same name as the primary output filename if (strlen(outfile2Name) == 0) outfile2Name = outfileName; gp_Write(theGraph, outfile2Name, WRITE_ADJLIST); } else if (command == 'd' && Result == OK) { // By default, add ".render.txt" to the primary output filename if (strlen(outfile2Name) == 0) strcat((outfile2Name = outfileName), ".render.txt"); gp_DrawPlanar_RenderToFile(theGraph, outfile2Name); } } } // Free the graph gp_Free(&theGraph); // Flush any remaining message content to the user, and return the result FlushConsole(stdout); return Result; }