static int findASolution(double[][][] graph, int[] assigned) throws Exception {
		//loop: while there are still tasks that need to be assigned
		//1. pick new unassigned task randomly
		//2. assign that task to an agent using "action choice rule"

		// init capacities

		double[] capacities = new double[NUM_AGENTS];
		for (int i=0; i<NUM_AGENTS; i++) {
			capacities[i] = CAPACITY_VALUE;
		}

		//create random ordering for processing tasks

		int[] order = new int[NUM_TASKS];
		for (int i = 0; i < order.length; i++) {
			order[i] = i;
		}

		// randomize order of assignments
		for (int i=0; i < order.length; i++) { // Fisher-Yates (Knuth) shuffle
			int random = generator.nextInt(order.length - i) + i; // [i, order.length)
			int temp = order[random];
			order[random] = order[i];
			order[i] = temp;
		}

		int currTask = 0; //increment this after each iteration through loop
		boolean foundFeasible = true;

		while (currTask < NUM_TASKS) {
			int agent = pickAgent(order[currTask], capacities, graph);
			if (agent != -1) {
				assigned[order[currTask]] = agent;
				if (verbosity >= 1) 
					System.out.println("\tAssigned " + agent + " to " + currTask + " in order[]");
				currTask++;
			} else { // if we didn't get a proper agent, this solution wasn't feasible
				foundFeasible = false;
				break;
			}
		}
		
		int cost = 0;
		if (foundFeasible) {
			
			for (int i = 0; i < assigned.length; i++) {
				cost += graph[assigned[i]][i][0];
				if (verbosity >= 1)
					System.out.println("\tAgent " + assigned[i] + " now has cost " + cost);
			}
		}
		GeneralizedAssignmentProblem.capacities = capacities;
		updatePheromones(assigned, graph, foundFeasible);
		return cost;
	}