stList *mergeSimpleCycles(stList *cycles, stList *nonZeroWeightAdjacencyEdges, stSortedSet *allAdjacencyEdges) { /* * Takes a set of simple cycles (containing only the adjacency edges). * Returns a single simple cycle, as a list of edges, by doing length(components)-1 * calls to doBestMergeOfTwoSimpleCycles. */ /* * Build a hash of nodes to adjacency edges. */ cycles = stList_copy(cycles, NULL); for (int64_t i = 0; i < stList_length(cycles); i++) { //Clone the complete list assert(stList_length(stList_get(cycles, i)) > 0); assert(!stList_contains(stList_get(cycles, i), NULL)); stList_set(cycles, i, stList_copy(stList_get(cycles, i), NULL)); } while (stList_length(cycles) > 1) { doBestMergeOfTwoSimpleCycles(cycles, nonZeroWeightAdjacencyEdges, allAdjacencyEdges); } assert(stList_length(cycles) == 1); stList *mergedComponent = stList_get(cycles, 0); stList_destruct(cycles); return mergedComponent; }
static void checkIsValidReference(CuTest *testCase, stList *reference, double totalScore) { stList *chosenEdges = convertReferenceToAdjacencyEdges(reference); //Check that everyone has a partner. CuAssertIntEquals(testCase, nodeNumber, stList_length(chosenEdges) * 2); stSortedSet *nodes = stSortedSet_construct3((int(*)(const void *, const void *)) stIntTuple_cmpFn, (void(*)(void *)) stIntTuple_destruct); for (int64_t i = 0; i < nodeNumber; i++) { stSortedSet_insert(nodes, stIntTuple_construct1( i)); } checkEdges(chosenEdges, nodes, 1, 0); //Check that the score is correct double totalScore2 = calculateZScoreOfReference(reference, nodeNumber, zMatrix); CuAssertDblEquals(testCase, totalScore2, totalScore, 0.000001); //Check that the stubs are properly connected. stList *allEdges = stList_copy(chosenEdges, NULL); stList_appendAll(allEdges, stubs); stList_appendAll(allEdges, chains); stList *components = getComponents(allEdges); CuAssertIntEquals(testCase, stList_length(stubs), stList_length(reference)); CuAssertIntEquals(testCase, stList_length(stubs), stList_length(components)); //Cleanup stList_destruct(components); stSortedSet_destruct(nodes); stList_destruct(allEdges); stList_destruct(chosenEdges); }
stList *chooseMatching_greedy(stList *edges, int64_t nodeNumber) { /* * Greedily picks the edge from the list such that each node has at most one edge. */ //First clone the list.. edges = stList_copy(edges, NULL); stSortedSet *seen = getEmptyNodeOrEdgeSetWithCleanup(); stList *matching = stList_construct(); //Sort the adjacency pairs.. stList_sort(edges, chooseMatching_greedyP); double strength = INT64_MAX; while (stList_length(edges) > 0) { stIntTuple *edge = stList_pop(edges); double d = stIntTuple_get(edge, 2); assert(d <= strength); strength = d; if(!nodeInSet(seen, stIntTuple_get(edge, 0)) && !nodeInSet(seen, stIntTuple_get(edge, 1))) { addNodeToSet(seen, stIntTuple_get(edge, 0)); addNodeToSet(seen, stIntTuple_get(edge, 1)); stList_append(matching,edge); } } assert(stList_length(edges) == 0); stList_destruct(edges); stSortedSet_destruct(seen); return matching; }
static stSortedSet *getSetOfMergedLists(stList *list1, stList *list2) { /* * Returns a sorted set of two input lists. */ stList *list3 = stList_copy(list1, NULL); stList_appendAll(list3, list2); stSortedSet *set = stList_getSortedSet(list3, NULL); stList_destruct(list3); return set; }
void test_stList_copy(CuTest *testCase) { setup(); stList *list2 = stList_copy(list, NULL); CuAssertTrue(testCase, stList_length(list) == stList_length(list2)); int64_t i; for(i=0; i<stringNumber; i++) { CuAssertTrue(testCase, stList_get(list2, i) == strings[i]); } stList_destruct(list2); teardown(); }
void checkInputs(stSortedSet *nodes, stList *adjacencyEdges, stList *stubEdges, stList *chainEdges) { /* * Checks the inputs to the algorithm are as expected. */ int64_t nodeNumber = stSortedSet_size(nodes); assert(nodeNumber % 2 == 0); if (nodeNumber > 0) { assert(stList_length(stubEdges) > 0); } assert( stList_length(stubEdges) + stList_length(chainEdges) == (nodeNumber / 2)); checkEdges(stubEdges, nodes, 0, 0); checkEdges(chainEdges, nodes, 0, 0); stList *stubsAndChainEdges = stList_copy(stubEdges, NULL); stList_appendAll(stubsAndChainEdges, chainEdges); checkEdges(stubsAndChainEdges, nodes, 1, 0); stList_destruct(stubsAndChainEdges); checkEdges(adjacencyEdges, nodes, 1, 1); }
static stList *splitMultipleStubCycle(stList *cycle, stList *nonZeroWeightAdjacencyEdges, stSortedSet *allAdjacencyEdges, stList *stubEdges, stList *chainEdges) { /* * Takes a simple cycle containing k stub edges and splits into k cycles, each containing 1 stub edge. */ /* * Get sub-components containing only adjacency and chain edges. */ stSortedSet *stubAndChainEdgesSet = getSetOfMergedLists(stubEdges, chainEdges); stList *adjacencyEdgeMatching = stList_filterToExclude(cycle, stubAndChainEdgesSet); //Filter out the the non-adjacency edges //Make it only the chain edges present in the original component stList *stubFreePaths = getComponents2(adjacencyEdgeMatching, NULL, chainEdges); stList_destruct(adjacencyEdgeMatching); assert(stList_length(stubFreePaths) >= 1); stList *splitCycles = stList_construct3(0, (void(*)(void *)) stList_destruct); //The list to return. if (stList_length(stubFreePaths) > 1) { /* * Build the list of adjacency edges acceptable in the merge */ stSortedSet *oddNodes = getOddNodes(cycle); stList *oddToEvenNonZeroWeightAdjacencyEdges = getOddToEvenAdjacencyEdges(oddNodes, nonZeroWeightAdjacencyEdges); stSortedSet *oddToEvenAllAdjacencyEdges = getOddToEvenAdjacencyEdges2(oddNodes, allAdjacencyEdges); /* * Merge together the best two components. */ stList *l = filterListsToExclude(stubFreePaths, stubAndChainEdgesSet); doBestMergeOfTwoSimpleCycles(l, oddToEvenNonZeroWeightAdjacencyEdges, oddToEvenAllAdjacencyEdges); //This is inplace. stList *l2 = stList_join(l); stList_destruct(l); l = getComponents2(l2, stubEdges, chainEdges); assert(stList_length(l) == 2); stList_destruct(l2); /* * Cleanup */ stSortedSet_destruct(oddNodes); stList_destruct(oddToEvenNonZeroWeightAdjacencyEdges); stSortedSet_destruct(oddToEvenAllAdjacencyEdges); /* * Call procedure recursively. */ for (int64_t i = 0; i < stList_length(l); i++) { /* * Split into adjacency edges, stub edges and chain edges. */ stList *subCycle = stList_get(l, i); stList *subAdjacencyEdges; stList *subStubEdges; stList *subChainEdges; splitIntoAdjacenciesStubsAndChains(subCycle, nonZeroWeightAdjacencyEdges, stubEdges, chainEdges, &subAdjacencyEdges, &subStubEdges, &subChainEdges); /* * Call recursively. */ l2 = splitMultipleStubCycle(subCycle, subAdjacencyEdges, allAdjacencyEdges, subStubEdges, subChainEdges); stList_appendAll(splitCycles, l2); /* * Clean up */ stList_setDestructor(l2, NULL); stList_destruct(l2); stList_destruct(subAdjacencyEdges); stList_destruct(subStubEdges); stList_destruct(subChainEdges); } stList_destruct(l); } else { stList_append(splitCycles, stList_copy(cycle, NULL)); } stSortedSet_destruct(stubAndChainEdgesSet); stList_destruct(stubFreePaths); return splitCycles; }