예제 #1
0
def local_search():
    # This function carries out a local search to improve
    # the current guess. You can only examine *ONE* possible
    # update to the current solution per call. That is, at
    # most one of the current medians should change from
    # call to call. Note that this procedure is greedy
    # and will only update the current solution if its
    # new guess yields a better cost

    ####################################################
    ##
    ## TO DO: Complete this function to perform simple
    ##        local search for better solutions to the
    ##        K-medians problem.
    ##
    ##        Make sure your code updates the global
    ##        'current_medians' list!
    ####################################################

    point = random.randint(0, Kmedians_global_data.N - 1)
    median = random.randint(0, Kmedians_global_data.K - 1)
    temp_medians = list(Kmedians_global_data.current_medians)

    temp_medians.pop(median)
    temp_medians.append(Kmedians_global_data.all_points[point])

    if Kmedians_global_data.current_cost(
            temp_medians) < Kmedians_global_data.current_cost(
                Kmedians_global_data.current_medians):
        Kmedians_global_data.current_medians = temp_medians
        print Kmedians_global_data.current_cost(temp_medians)
    return
예제 #2
0
def local_search():
	# This function carries out a local search to improve
	# the current guess. You can only examine *ONE* possible
	# update to the current solution per call. That is, at
	# most one of the current medians should change from
	# call to call. Note that this procedure is greedy
	# and will only update the current solution if its
	# new guess yields a better cost

	####################################################
        ## 
        ## TO DO: Complete this function to perform simple
        ##        local search for better solutions to the
        ##        K-medians problem.
        ##
        ##        Make sure your code updates the global
        ##        'current_medians' list!
        ####################################################

        point =random.randint(0, Kmedians_global_data.N-1)
        median = random.randint(0, Kmedians_global_data.K-1)
        temp_medians = list(Kmedians_global_data.current_medians)

        temp_medians.pop(median)
        temp_medians.append(Kmedians_global_data.all_points[point])
        
        if Kmedians_global_data.current_cost(temp_medians) < Kmedians_global_data.current_cost(Kmedians_global_data.current_medians):
                Kmedians_global_data.current_medians = temp_medians  
                print Kmedians_global_data.current_cost(temp_medians)
	return 
예제 #3
0
def deterministic_annealing():
    # This function carries out a local search using the
    # deterministic annealing method as discussed in lecture.
    # The 'temperature' is set by the initKmedians function.
    # Each call to this function will try a new solution
    # and accept it under the conditions specified by the
    # deterministic annealing method.

    # temperature as T=T*D, where D<1.0 is a decay factor that
    # controls how quickly the temperature decreases.
    # Both the temperature and decay factor are global
    # variables.

    # Each call to this function can examine only *ONE*
    # guess at the solution.

    ####################################################
    # THE SAME NEIGHBOURHOOD DEFINITION APPLIES AS FOR
    # LOCAL SEARCH ABOVE
    ####################################################

    ####################################################
    ##
    ## TO DO: Complete this function to perform
    ##        local search with deterministic annealing.
    ##
    ##        Make sure your code updates the global
    ##        'current_medians' list!
    ####################################################

    T = Kmedians_global_data.Temperature = Kmedians_global_data.Temperature * Kmedians_global_data.Decay

    medians = try_new_medians()
    if not medians:
        return

    med_cost = Kmedians_global_data.current_cost(medians)
    cur_cost = Kmedians_global_data.current_cost(
        Kmedians_global_data.current_medians)
    delta_t = abs(med_cost - cur_cost)

    probability = math.exp(-delta_t / T)

    r = random.random()

    if med_cost > cur_cost:
        if r < probability:
            Kmedians_global_data.current_medians = medians
    else:
        Kmedians_global_data.current_medians = medians

    print med_cost

    return
예제 #4
0
def MainLoop():
    global iters
    global screen_shot_on_done
    global screeny_filename
    temp = list(Kmedians_global_data.current_medians)
    if iters < 150:
        if Kmedians_global_data.Temperature <= 0:
            local_search()
            if temp == Kmedians_global_data.current_medians:
                iters = iters + 1
            else:
                iters = 0
        else:
            deterministic_annealing()
            if temp == Kmedians_global_data.current_medians:
                iters = iters + 1
            else:
                iters = 0
        renderFrame()
        UpdateFrame()
    else:
        print 'No improvement for past 150 iterations. Search stop.\n'
        print "Press 'q' to quit\n"
        print "final cost:", Kmedians_global_data.current_cost(
            Kmedians_global_data.current_medians)

        if not screen_shot_on_done:
            exit(0)
예제 #5
0
def local_search():
    # This function carries out a local search to improve
    # the current guess. You can only examine *ONE* possible
    # update to the current solution per call. That is, at
    # most one of the current medians should change from
    # call to call. Note that this procedure is greedy
    # and will only update the current solution if its
    # new guess yields a better cost

    #####################################################
    # NEIGHBOURHOOD DEFINITION:
    # At each step, one of the current guesses for your
    # median locations can be swaped for another
    # point as long as the distance between the current
    # guess and the point is less than 250 units
    # (this is Euclidean distance of course)
    # This means that you CAN NOT SWAP with just any
    # point! Make sure your updates consider this
    # simple neighbourhood structure.
    #
    # If the proposed swap is more than 250 units away,
    # do not perform the sawp! just return from this
    # function with the same guess you started with.
    ######################################################

    ####################################################
    ##
    ## TO DO: Complete this function to perform simple
    ##        local search for better solutions to the
    ##        K-medians problem.
    ##
    ##        Make sure your code updates the global
    ##        'current_medians' list!
    ####################################################

    medians = try_new_medians()
    if not medians:
        return

    med_cost = Kmedians_global_data.current_cost(medians)
    cur_cost = Kmedians_global_data.current_cost(
        Kmedians_global_data.current_medians)

    if med_cost < cur_cost:
        Kmedians_global_data.current_medians = medians
        print med_cost
    return
예제 #6
0
def deterministic_annealing():
    # This function carries out a local search using the
    # deterministic annealing method as discussed in lecture.
    # The 'temperature' is set by the initKmedians function.
    # Each call to this function will try a new solution
    # and accept it under the conditions specified by the
    # deterministic annealing method.
    # Also, each call to this function will update the
    # temperature as T=T*D, where D<1.0 is a decay factor that
    # controls how quickly the temperature decreases.
    # Both the temperature and decay factor are global
    # variables.

    # Each call to this function can examine only *ONE*
    # guess at the solution.

    ####################################################
    ##
    ## TO DO: Complete this function to perform
    ##        local search with deterministic annealing.
    ##
    ##        Make sure your code updates the global
    ##        'current_medians' list!
    ####################################################

    point = random.randint(0, Kmedians_global_data.N - 1)
    median = random.randint(0, Kmedians_global_data.K - 1)
    temp_medians = list(Kmedians_global_data.current_medians)

    temp_medians.pop(median)
    temp_medians.append(Kmedians_global_data.all_points[point])

    if Kmedians_global_data.current_cost(
            temp_medians) < Kmedians_global_data.current_cost(
                Kmedians_global_data.current_medians):
        Kmedians_global_data.current_medians = temp_medians
        print Kmedians_global_data.current_cost(temp_medians)
    else:
        # get the probability
        cost_diff = abs(
            Kmedians_global_data.current_cost(temp_medians) -
            Kmedians_global_data.current_cost(
                Kmedians_global_data.current_medians))
        probability = math.exp(-cost_diff / Kmedians_global_data.Temperature)
        # generate a random float between 0 and 1
        rand_float = random.random()

        if probability > rand_float:
            Kmedians_global_data.current_medians = temp_medians
            print Kmedians_global_data.current_cost(temp_medians)
    Kmedians_global_data.Temperature = Kmedians_global_data.Temperature * Kmedians_global_data.Decay
    return
예제 #7
0
def deterministic_annealing():
	# This function carries out a local search using the
	# deterministic annealing method as discussed in lecture.
	# The 'temperature' is set by the initKmedians function.
        # Each call to this function will try a new solution
        # and accept it under the conditions specified by the
        # deterministic annealing method.
        # Also, each call to this function will update the
	# temperature as T=T*D, where D<1.0 is a decay factor that
	# controls how quickly the temperature decreases.
        # Both the temperature and decay factor are global
        # variables.
 
	# Each call to this function can examine only *ONE* 
	# guess at the solution.

	####################################################
        ## 
        ## TO DO: Complete this function to perform 
        ##        local search with deterministic annealing.
        ##
        ##        Make sure your code updates the global
        ##        'current_medians' list!
        ####################################################

        point =random.randint(0, Kmedians_global_data.N-1)
        median = random.randint(0, Kmedians_global_data.K-1)
        temp_medians = list(Kmedians_global_data.current_medians)

        temp_medians.pop(median)
        temp_medians.append(Kmedians_global_data.all_points[point])
        
        if Kmedians_global_data.current_cost(temp_medians) < Kmedians_global_data.current_cost(Kmedians_global_data.current_medians):
                Kmedians_global_data.current_medians = temp_medians  
                print Kmedians_global_data.current_cost(temp_medians)
        else:
                # get the probability
                cost_diff = abs(Kmedians_global_data.current_cost(temp_medians) - Kmedians_global_data.current_cost(Kmedians_global_data.current_medians))
                probability =  math.exp(-cost_diff/Kmedians_global_data.Temperature)        
                # generate a random float between 0 and 1 
                rand_float = random.random()

                if probability > rand_float:
                        Kmedians_global_data.current_medians = temp_medians  
                        print Kmedians_global_data.current_cost(temp_medians)
        Kmedians_global_data.Temperature = Kmedians_global_data.Temperature*Kmedians_global_data.Decay
	return
예제 #8
0
def deterministic_annealing():
    # This function carries out a local search using the
    # deterministic annealing method as discussed in lecture.
    # The 'temperature' is set by the initKmedians function.
    # Each call to this function will try a new solution
    # and accept it under the conditions specified by the
    # deterministic annealing method.
    # Also, each call to this function will update the
    # temperature as T=T*D, where D<1.0 is a decay factor that
    # controls how quickly the temperature decreases.
    # Both the temperature and decay factor are global
    # variables.

    # Each call to this function can examine only *ONE* 
    # guess at the solution.

    ####################################################
    # THE SAME NEIGHBOURHOOD DEFINITION APPLIES AS FOR 
    # LOCAL SEARCH ABOVE
    ####################################################
    # all_points      - List of [x,y] point coordinates
    # current_medians - List of [x,y] with current medians
    # N               - Number of points
    # K               - Number of medians
    # Temperature	  - Temperature for deterministic annealing
    # Decay           - Decay factor for deterministic annealing

    g.current_cost(g.current_medians)
    old_median = random.choice(g.current_medians)
    new_median = random.choice(g.all_points)
    if distance(old_median, new_median) > 250:
        return
    new_medians = g.current_medians[:]
    new_medians.remove(old_median)
    new_medians.append(new_median)
    dT = abs(g.current_cost(g.current_medians) - g.current_cost(new_medians))
    P = exp(-dT/g.Temperature)
    g.Temperature *= g.Decay
    print("temp: %f" % g.Temperature)
    print("cost: %f" % g.current_cost(g.current_medians))
    if g.current_cost(g.current_medians) > g.current_cost(new_medians):
        g.current_medians = new_medians
    elif random.random() < P:
        g.current_medians = new_medians


    return
예제 #9
0
def local_search():
    # This function carries out a local search to improve
    # the current guess. You can only examine *ONE* possible
    # update to the current solution per call. That is, at
    # most one of the current medians should change from
    # call to call. Note that this procedure is greedy
    # and will only update the current solution if its
    # new guess yields a better cost

    #####################################################
    # NEIGHBOURHOOD DEFINITION:
    # At each step, one of the current guesses for your
    # median locations can be swaped for another
    # point as long as the distance between the current
    # guess and the point is less than 250 units
    # (this is Euclidean distance of course)
    # This means that you CAN NOT SWAP with just any
    # point! Make sure your updates consider this 
    # simple neighbourhood structure.
    #
    # If the proposed swap is more than 250 units away,
    # do not perform the sawp! just return from this
    # function with the same guess you started with.
    #####################################################

    g.current_cost(g.current_medians)
    old_median = random.choice(g.current_medians)
    new_median = random.choice(g.all_points)
    if distance(old_median, new_median) > 250:
        return
    new_medians = g.current_medians[:]
    new_medians.remove(old_median)
    new_medians.append(new_median)
    if g.current_cost(g.current_medians) > g.current_cost(new_medians):
        g.current_medians = new_medians
    print g.current_cost(g.current_medians)
예제 #10
0
def initKmedians(seedNo, N, K, screeny=False, filename=''):
    global N_comps
    global sigs
    global pis
    global mus
    global blank
    global screen_shot_on_done
    global screeny_filename

    screen_shot_on_done = screeny
    if filename:
        screeny_filename = filename

    Kmedians_global_data.N = N
    Kmedians_global_data.K = K
    if N < 50 or N > 5000:
        print 'Value of N should be between 50 and 5000. Using 100\n'
        Kmedians_global_data.N = 100
    if K < 1 or K > 15:
        print 'Value of K should be between 1 and 15. Using 10\n'
        Kmedians_global_data.K = 5
    random.seed(31415)
    if seedNo >= 0:
        pisum = 0
        for i in range(N_comps + 1):
            pis.append(random.random())
            mus.append([random.randint(1, 1022), randint(1, 1022)])
            sigs.append([random.randint(50, 500)])
            pisum = pisum + pis[i]

        for i in range(N_comps + 1):
            pis[i] = pis[i] / pisum

    else:
        blank = open('TO_dense.ppm')
        pis.append(7)
        mus.append([165, 697])
        sigs.append(70)
        pis.append(7)
        mus.append([185, 530])
        sigs.append(100)
        pis.append(7)
        mus.append([490, 590])
        sigs.append(55)
        pis.append(7)
        mus.append([710, 475])
        sigs.append(70)
        pis.append(4)
        mus.append([300, 250])
        sigs.append(150)
        pis.append(2.5)
        mus.append([950, 340])
        sigs.append(140)
        pis.append(1.5)
        mus.append([610, 230])
        sigs.append(200)
        pis.append(0.5)
        mus.append([512, 512])
        sigs.append(1)
        pisum = 0
        for i in range(N_comps + 1):
            pisum = pisum + pis[i]

        for i in range(N_comps + 1):
            pis[i] = pis[i] / pisum

    for i in range(Kmedians_global_data.N):
        done = 0
        while not done:
            dice = random.random()
            pisum = 0
            idx = 0
            while idx < N_comps:
                pisum = pisum + pis[idx]
                if pisum >= dice:
                    break
                idx = idx + 1

            if idx < N_comps:
                mu = mus[idx]
                sig = sigs[idx]
                pt = list([
                    random.normal(mu[0], sig, 1),
                    random.normal(mu[1], sig, 1)
                ])
                if pt[0] > 0 and pt[0] < 1023 and pt[1] > 0 and pt[1] < 1023:
                    done = 1
            else:
                pt = [random.randint(1, 1023), random.randint(1, 1023)]
                done = 1
            if seedNo < 0 and done:
                pix = list(blank.getpixel(tuple([round(pt[0]), round(pt[1])])))
                if pix[0] == 0 and pix[1] == 0 and pix[2] == 0:
                    done = 0
            if done == 1:
                Kmedians_global_data.all_points.append(pt)

    random.seed(abs(seedNo))
    for i in range(Kmedians_global_data.K):
        Kmedians_global_data.current_medians.append(
            Kmedians_global_data.all_points[random.randint(0, N - 1)])

    print 'Initial K-medians guess:\n'
    print Kmedians_global_data.current_medians
    print 'Initial assignment cost (average distance from a point to the closest candidate median):\n'
    print Kmedians_global_data.current_cost(
        Kmedians_global_data.current_medians)